Merge tag 'ASB-2023-05-05_11-5.4' of https://android.googlesource.com/kernel/common into android13-5.4-lahaina

https://source.android.com/docs/security/bulletin/2023-05-01
CVE-2023-21102
CVE-2023-21106
CVE-2023-0266

* tag 'ASB-2023-05-05_11-5.4' of https://android.googlesource.com/kernel/common:
  UPSTREAM: usb: musb: mediatek: don't unregister something that wasn't registered
  UPSTREAM: net: fix NULL pointer in skb_segment_list
  UPSTREAM: xfrm/compat: prevent potential spectre v1 gadget in xfrm_xlate32_attr()
  UPSTREAM: xfrm: compat: change expression for switch in xfrm_xlate64
  UPSTREAM: perf/core: Call LSM hook after copying perf_event_attr
  UPSTREAM: ext4: fix use-after-free in ext4_xattr_set_entry
  UPSTREAM: ext4: remove duplicate definition of ext4_xattr_ibody_inline_set()
  UPSTREAM: Revert "ext4: fix use-after-free in ext4_xattr_set_entry"
  UPSTREAM: media: rc: Fix use-after-free bugs caused by ene_tx_irqsim()
  ANDROID: incremental fs: Evict inodes before freeing mount data

Change-Id: I0b01081a4a6d475b67b443421b8e0a2be57c8257
This commit is contained in:
Michael Bestas 2023-05-05 20:06:12 +03:00
commit dfc478b4fe
No known key found for this signature in database
GPG Key ID: CC95044519BE6669
10 changed files with 38 additions and 44 deletions

View File

@ -1106,6 +1106,8 @@ static void ene_remove(struct pnp_dev *pnp_dev)
struct ene_device *dev = pnp_get_drvdata(pnp_dev); struct ene_device *dev = pnp_get_drvdata(pnp_dev);
unsigned long flags; unsigned long flags;
rc_unregister_device(dev->rdev);
del_timer_sync(&dev->tx_sim_timer);
spin_lock_irqsave(&dev->hw_lock, flags); spin_lock_irqsave(&dev->hw_lock, flags);
ene_rx_disable(dev); ene_rx_disable(dev);
ene_rx_restore_hw_buffer(dev); ene_rx_restore_hw_buffer(dev);
@ -1113,7 +1115,6 @@ static void ene_remove(struct pnp_dev *pnp_dev)
free_irq(dev->irq, dev); free_irq(dev->irq, dev);
release_region(dev->hw_io, ENE_IO_SIZE); release_region(dev->hw_io, ENE_IO_SIZE);
rc_unregister_device(dev->rdev);
kfree(dev); kfree(dev);
} }

View File

@ -342,6 +342,7 @@ static int mtk_musb_init(struct musb *musb)
err_phy_power_on: err_phy_power_on:
phy_exit(glue->phy); phy_exit(glue->phy);
err_phy_init: err_phy_init:
if (musb->port_mode == MUSB_OTG)
mtk_otg_switch_exit(glue); mtk_otg_switch_exit(glue);
return ret; return ret;
} }

View File

@ -208,7 +208,7 @@ out:
/* /*
* write the buffer to the inline inode. * write the buffer to the inline inode.
* If 'create' is set, we don't need to do the extra copy in the xattr * If 'create' is set, we don't need to do the extra copy in the xattr
* value since it is already handled by ext4_xattr_ibody_inline_set. * value since it is already handled by ext4_xattr_ibody_set.
* That saves us one memcpy. * That saves us one memcpy.
*/ */
static void ext4_write_inline_data(struct inode *inode, struct ext4_iloc *iloc, static void ext4_write_inline_data(struct inode *inode, struct ext4_iloc *iloc,
@ -290,7 +290,7 @@ static int ext4_create_inline_data(handle_t *handle,
BUG_ON(!is.s.not_found); BUG_ON(!is.s.not_found);
error = ext4_xattr_ibody_inline_set(handle, inode, &i, &is); error = ext4_xattr_ibody_set(handle, inode, &i, &is);
if (error) { if (error) {
if (error == -ENOSPC) if (error == -ENOSPC)
ext4_clear_inode_state(inode, ext4_clear_inode_state(inode,
@ -362,7 +362,7 @@ static int ext4_update_inline_data(handle_t *handle, struct inode *inode,
i.value = value; i.value = value;
i.value_len = len; i.value_len = len;
error = ext4_xattr_ibody_inline_set(handle, inode, &i, &is); error = ext4_xattr_ibody_set(handle, inode, &i, &is);
if (error) if (error)
goto out; goto out;
@ -435,7 +435,7 @@ static int ext4_destroy_inline_data_nolock(handle_t *handle,
if (error) if (error)
goto out; goto out;
error = ext4_xattr_ibody_inline_set(handle, inode, &i, &is); error = ext4_xattr_ibody_set(handle, inode, &i, &is);
if (error) if (error)
goto out; goto out;
@ -1989,8 +1989,7 @@ int ext4_inline_data_truncate(struct inode *inode, int *has_inline)
i.value = value; i.value = value;
i.value_len = i_size > EXT4_MIN_INLINE_DATA_SIZE ? i.value_len = i_size > EXT4_MIN_INLINE_DATA_SIZE ?
i_size - EXT4_MIN_INLINE_DATA_SIZE : 0; i_size - EXT4_MIN_INLINE_DATA_SIZE : 0;
err = ext4_xattr_ibody_inline_set(handle, inode, err = ext4_xattr_ibody_set(handle, inode, &i, &is);
&i, &is);
if (err) if (err)
goto out_error; goto out_error;
} }

View File

@ -2221,7 +2221,7 @@ int ext4_xattr_ibody_find(struct inode *inode, struct ext4_xattr_info *i,
return 0; return 0;
} }
int ext4_xattr_ibody_inline_set(handle_t *handle, struct inode *inode, int ext4_xattr_ibody_set(handle_t *handle, struct inode *inode,
struct ext4_xattr_info *i, struct ext4_xattr_info *i,
struct ext4_xattr_ibody_find *is) struct ext4_xattr_ibody_find *is)
{ {
@ -2246,30 +2246,6 @@ int ext4_xattr_ibody_inline_set(handle_t *handle, struct inode *inode,
return 0; return 0;
} }
static int ext4_xattr_ibody_set(handle_t *handle, struct inode *inode,
struct ext4_xattr_info *i,
struct ext4_xattr_ibody_find *is)
{
struct ext4_xattr_ibody_header *header;
struct ext4_xattr_search *s = &is->s;
int error;
if (EXT4_I(inode)->i_extra_isize == 0)
return -ENOSPC;
error = ext4_xattr_set_entry(i, s, handle, inode, false /* is_block */);
if (error)
return error;
header = IHDR(inode, ext4_raw_inode(&is->iloc));
if (!IS_LAST_ENTRY(s->first)) {
header->h_magic = cpu_to_le32(EXT4_XATTR_MAGIC);
ext4_set_inode_state(inode, EXT4_STATE_XATTR);
} else {
header->h_magic = cpu_to_le32(0);
ext4_clear_inode_state(inode, EXT4_STATE_XATTR);
}
return 0;
}
static int ext4_xattr_value_same(struct ext4_xattr_search *s, static int ext4_xattr_value_same(struct ext4_xattr_search *s,
struct ext4_xattr_info *i) struct ext4_xattr_info *i)
{ {

View File

@ -199,7 +199,7 @@ extern int ext4_xattr_ibody_find(struct inode *inode, struct ext4_xattr_info *i,
extern int ext4_xattr_ibody_get(struct inode *inode, int name_index, extern int ext4_xattr_ibody_get(struct inode *inode, int name_index,
const char *name, const char *name,
void *buffer, size_t buffer_size); void *buffer, size_t buffer_size);
extern int ext4_xattr_ibody_inline_set(handle_t *handle, struct inode *inode, extern int ext4_xattr_ibody_set(handle_t *handle, struct inode *inode,
struct ext4_xattr_info *i, struct ext4_xattr_info *i,
struct ext4_xattr_ibody_find *is); struct ext4_xattr_ibody_find *is);

View File

@ -30,6 +30,15 @@ static ssize_t corefs_show(struct kobject *kobj,
static struct kobj_attribute corefs_attr = __ATTR_RO(corefs); static struct kobj_attribute corefs_attr = __ATTR_RO(corefs);
static ssize_t bugfix_inode_eviction_show(struct kobject *kobj,
struct kobj_attribute *attr, char *buff)
{
return snprintf(buff, PAGE_SIZE, "supported\n");
}
static struct kobj_attribute bugfix_inode_eviction_attr =
__ATTR_RO(bugfix_inode_eviction);
static ssize_t mounter_context_for_backing_rw_show(struct kobject *kobj, static ssize_t mounter_context_for_backing_rw_show(struct kobject *kobj,
struct kobj_attribute *attr, char *buff) struct kobj_attribute *attr, char *buff)
{ {
@ -41,6 +50,7 @@ static struct kobj_attribute mounter_context_for_backing_rw_attr =
static struct attribute *attributes[] = { static struct attribute *attributes[] = {
&corefs_attr.attr, &corefs_attr.attr,
&bugfix_inode_eviction_attr.attr,
&mounter_context_for_backing_rw_attr.attr, &mounter_context_for_backing_rw_attr.attr,
NULL, NULL,
}; };

View File

@ -2311,6 +2311,13 @@ void incfs_kill_sb(struct super_block *sb)
pr_debug("incfs: unmount\n"); pr_debug("incfs: unmount\n");
/*
* We must kill the super before freeing mi, since killing the super
* triggers inode eviction, which triggers the final update of the
* backing file, which uses certain information for mi
*/
kill_anon_super(sb);
if (mi) { if (mi) {
if (mi->mi_backing_dir_path.dentry) if (mi->mi_backing_dir_path.dentry)
dinode = d_inode(mi->mi_backing_dir_path.dentry); dinode = d_inode(mi->mi_backing_dir_path.dentry);
@ -2322,7 +2329,6 @@ void incfs_kill_sb(struct super_block *sb)
incfs_free_mount_info(mi); incfs_free_mount_info(mi);
sb->s_fs_info = NULL; sb->s_fs_info = NULL;
} }
kill_anon_super(sb);
} }
static int show_options(struct seq_file *m, struct dentry *root) static int show_options(struct seq_file *m, struct dentry *root)

View File

@ -11195,12 +11195,12 @@ SYSCALL_DEFINE5(perf_event_open,
if (flags & ~PERF_FLAG_ALL) if (flags & ~PERF_FLAG_ALL)
return -EINVAL; return -EINVAL;
/* Do we allow access to perf_event_open(2) ? */ err = perf_copy_attr(attr_uptr, &attr);
err = security_perf_event_open(&attr, PERF_SECURITY_OPEN);
if (err) if (err)
return err; return err;
err = perf_copy_attr(attr_uptr, &attr); /* Do we allow access to perf_event_open(2) ? */
err = security_perf_event_open(&attr, PERF_SECURITY_OPEN);
if (err) if (err)
return err; return err;

View File

@ -3697,7 +3697,7 @@ struct sk_buff *skb_segment_list(struct sk_buff *skb,
skb_shinfo(skb)->frag_list = NULL; skb_shinfo(skb)->frag_list = NULL;
do { while (list_skb) {
nskb = list_skb; nskb = list_skb;
list_skb = list_skb->next; list_skb = list_skb->next;
@ -3743,8 +3743,7 @@ struct sk_buff *skb_segment_list(struct sk_buff *skb,
if (skb_needs_linearize(nskb, features) && if (skb_needs_linearize(nskb, features) &&
__skb_linearize(nskb)) __skb_linearize(nskb))
goto err_linearize; goto err_linearize;
}
} while (list_skb);
skb->truesize = skb->truesize - delta_truesize; skb->truesize = skb->truesize - delta_truesize;
skb->data_len = skb->data_len - delta_len; skb->data_len = skb->data_len - delta_len;

View File

@ -5,6 +5,7 @@
* Based on code and translator idea by: Florian Westphal <fw@strlen.de> * Based on code and translator idea by: Florian Westphal <fw@strlen.de>
*/ */
#include <linux/compat.h> #include <linux/compat.h>
#include <linux/nospec.h>
#include <linux/xfrm.h> #include <linux/xfrm.h>
#include <net/xfrm.h> #include <net/xfrm.h>
@ -300,7 +301,7 @@ static int xfrm_xlate64(struct sk_buff *dst, const struct nlmsghdr *nlh_src)
nla_for_each_attr(nla, attrs, len, remaining) { nla_for_each_attr(nla, attrs, len, remaining) {
int err; int err;
switch (type) { switch (nlh_src->nlmsg_type) {
case XFRM_MSG_NEWSPDINFO: case XFRM_MSG_NEWSPDINFO:
err = xfrm_nla_cpy(dst, nla, nla_len(nla)); err = xfrm_nla_cpy(dst, nla, nla_len(nla));
break; break;
@ -435,6 +436,7 @@ static int xfrm_xlate32_attr(void *dst, const struct nlattr *nla,
NL_SET_ERR_MSG(extack, "Bad attribute"); NL_SET_ERR_MSG(extack, "Bad attribute");
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
type = array_index_nospec(type, XFRMA_MAX + 1);
if (nla_len(nla) < compat_policy[type].len) { if (nla_len(nla) < compat_policy[type].len) {
NL_SET_ERR_MSG(extack, "Attribute bad length"); NL_SET_ERR_MSG(extack, "Attribute bad length");
return -EOPNOTSUPP; return -EOPNOTSUPP;