Merge 5.15.52 into android14-5.15
Changes in 5.15.52 tick/nohz: unexport __init-annotated tick_nohz_full_setup() x86, kvm: use proper ASM macros for kvm_vcpu_is_preempted bcache: memset on stack variables in bch_btree_check() and bch_sectors_dirty_init() xfs: use kmem_cache_free() for kmem_cache objects xfs: punch out data fork delalloc blocks on COW writeback failure xfs: Fix the free logic of state in xfs_attr_node_hasname xfs: remove all COW fork extents when remounting readonly xfs: check sb_meta_uuid for dabuf buffer recovery xfs: prevent UAF in xfs_log_item_in_current_chkpt xfs: only bother with sync_filesystem during readonly remount powerpc/ftrace: Remove ftrace init tramp once kernel init is complete fs: add is_idmapped_mnt() helper fs: move mapping helpers fs: tweak fsuidgid_has_mapping() fs: account for filesystem mappings docs: update mapping documentation fs: use low-level mapping helpers fs: remove unused low-level mapping helpers fs: port higher-level mapping helpers fs: add i_user_ns() helper fs: support mapped mounts of mapped filesystems fs: fix acl translation fs: account for group membership rtw88: 8821c: support RFE type4 wifi NIC rtw88: rtw8821c: enable rfe 6 devices net: mscc: ocelot: allow unregistered IP multicast flooding to CPU io_uring: fix not locked access to fixed buf table Linux 5.15.52 Signed-off-by: Greg Kroah-Hartman <gregkh@google.com> Change-Id: Icfb690703efd8cab1dffa7ca6cce28bbca635c3d
This commit is contained in:
@@ -31,6 +31,7 @@
|
||||
#include <uapi/linux/mount.h>
|
||||
#include <linux/fs_context.h>
|
||||
#include <linux/shmem_fs.h>
|
||||
#include <linux/mnt_idmapping.h>
|
||||
|
||||
#include "pnode.h"
|
||||
#include "internal.h"
|
||||
@@ -561,7 +562,7 @@ static void free_vfsmnt(struct mount *mnt)
|
||||
struct user_namespace *mnt_userns;
|
||||
|
||||
mnt_userns = mnt_user_ns(&mnt->mnt);
|
||||
if (mnt_userns != &init_user_ns)
|
||||
if (!initial_idmapping(mnt_userns))
|
||||
put_user_ns(mnt_userns);
|
||||
kfree_const(mnt->mnt_devname);
|
||||
#ifdef CONFIG_SMP
|
||||
@@ -965,6 +966,7 @@ static struct mount *skip_mnt_tree(struct mount *p)
|
||||
struct vfsmount *vfs_create_mount(struct fs_context *fc)
|
||||
{
|
||||
struct mount *mnt;
|
||||
struct user_namespace *fs_userns;
|
||||
|
||||
if (!fc->root)
|
||||
return ERR_PTR(-EINVAL);
|
||||
@@ -982,6 +984,10 @@ struct vfsmount *vfs_create_mount(struct fs_context *fc)
|
||||
mnt->mnt_mountpoint = mnt->mnt.mnt_root;
|
||||
mnt->mnt_parent = mnt;
|
||||
|
||||
fs_userns = mnt->mnt.mnt_sb->s_user_ns;
|
||||
if (!initial_idmapping(fs_userns))
|
||||
mnt->mnt.mnt_userns = get_user_ns(fs_userns);
|
||||
|
||||
lock_mount_hash();
|
||||
list_add_tail(&mnt->mnt_instance, &mnt->mnt.mnt_sb->s_mounts);
|
||||
unlock_mount_hash();
|
||||
@@ -1072,7 +1078,7 @@ static struct mount *clone_mnt(struct mount *old, struct dentry *root,
|
||||
|
||||
atomic_inc(&sb->s_active);
|
||||
mnt->mnt.mnt_userns = mnt_user_ns(&old->mnt);
|
||||
if (mnt->mnt.mnt_userns != &init_user_ns)
|
||||
if (!initial_idmapping(mnt->mnt.mnt_userns))
|
||||
mnt->mnt.mnt_userns = get_user_ns(mnt->mnt.mnt_userns);
|
||||
mnt->mnt.mnt_sb = sb;
|
||||
mnt->mnt.mnt_root = dget(root);
|
||||
@@ -3927,28 +3933,32 @@ static unsigned int recalc_flags(struct mount_kattr *kattr, struct mount *mnt)
|
||||
static int can_idmap_mount(const struct mount_kattr *kattr, struct mount *mnt)
|
||||
{
|
||||
struct vfsmount *m = &mnt->mnt;
|
||||
struct user_namespace *fs_userns = m->mnt_sb->s_user_ns;
|
||||
|
||||
if (!kattr->mnt_userns)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Creating an idmapped mount with the filesystem wide idmapping
|
||||
* doesn't make sense so block that. We don't allow mushy semantics.
|
||||
*/
|
||||
if (kattr->mnt_userns == fs_userns)
|
||||
return -EINVAL;
|
||||
|
||||
/*
|
||||
* Once a mount has been idmapped we don't allow it to change its
|
||||
* mapping. It makes things simpler and callers can just create
|
||||
* another bind-mount they can idmap if they want to.
|
||||
*/
|
||||
if (mnt_user_ns(m) != &init_user_ns)
|
||||
if (is_idmapped_mnt(m))
|
||||
return -EPERM;
|
||||
|
||||
/* The underlying filesystem doesn't support idmapped mounts yet. */
|
||||
if (!(m->mnt_sb->s_type->fs_flags & FS_ALLOW_IDMAP))
|
||||
return -EINVAL;
|
||||
|
||||
/* Don't yet support filesystem mountable in user namespaces. */
|
||||
if (m->mnt_sb->s_user_ns != &init_user_ns)
|
||||
return -EINVAL;
|
||||
|
||||
/* We're not controlling the superblock. */
|
||||
if (!capable(CAP_SYS_ADMIN))
|
||||
if (!ns_capable(fs_userns, CAP_SYS_ADMIN))
|
||||
return -EPERM;
|
||||
|
||||
/* Mount has already been visible in the filesystem hierarchy. */
|
||||
@@ -4002,14 +4012,27 @@ out:
|
||||
|
||||
static void do_idmap_mount(const struct mount_kattr *kattr, struct mount *mnt)
|
||||
{
|
||||
struct user_namespace *mnt_userns;
|
||||
struct user_namespace *mnt_userns, *old_mnt_userns;
|
||||
|
||||
if (!kattr->mnt_userns)
|
||||
return;
|
||||
|
||||
/*
|
||||
* We're the only ones able to change the mount's idmapping. So
|
||||
* mnt->mnt.mnt_userns is stable and we can retrieve it directly.
|
||||
*/
|
||||
old_mnt_userns = mnt->mnt.mnt_userns;
|
||||
|
||||
mnt_userns = get_user_ns(kattr->mnt_userns);
|
||||
/* Pairs with smp_load_acquire() in mnt_user_ns(). */
|
||||
smp_store_release(&mnt->mnt.mnt_userns, mnt_userns);
|
||||
|
||||
/*
|
||||
* If this is an idmapped filesystem drop the reference we've taken
|
||||
* in vfs_create_mount() before.
|
||||
*/
|
||||
if (!initial_idmapping(old_mnt_userns))
|
||||
put_user_ns(old_mnt_userns);
|
||||
}
|
||||
|
||||
static void mount_setattr_commit(struct mount_kattr *kattr,
|
||||
@@ -4133,13 +4156,15 @@ static int build_mount_idmapped(const struct mount_attr *attr, size_t usize,
|
||||
}
|
||||
|
||||
/*
|
||||
* The init_user_ns is used to indicate that a vfsmount is not idmapped.
|
||||
* This is simpler than just having to treat NULL as unmapped. Users
|
||||
* wanting to idmap a mount to init_user_ns can just use a namespace
|
||||
* with an identity mapping.
|
||||
* The initial idmapping cannot be used to create an idmapped
|
||||
* mount. We use the initial idmapping as an indicator of a mount
|
||||
* that is not idmapped. It can simply be passed into helpers that
|
||||
* are aware of idmapped mounts as a convenient shortcut. A user
|
||||
* can just create a dedicated identity mapping to achieve the same
|
||||
* result.
|
||||
*/
|
||||
mnt_userns = container_of(ns, struct user_namespace, ns);
|
||||
if (mnt_userns == &init_user_ns) {
|
||||
if (initial_idmapping(mnt_userns)) {
|
||||
err = -EPERM;
|
||||
goto out_fput;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user