path: root/fs/fs_context.c
diff options
authorEric Biggers <>2019-08-21 22:16:33 -0700
committerAl Viro <>2019-09-05 14:33:45 -0400
commit1dd9bc08cf1420d466dd8dcfcc233777e61ca5d2 (patch)
treeefa24be2b2316d016ef0b1d19ff489dcf170fc06 /fs/fs_context.c
parentd1abaeb3be7b5fa6d7a1fbbd2e14e3310005c4c1 (diff)
vfs: set fs_context::user_ns for reconfigure
fs_context::user_ns is used by fuse_parse_param(), even during remount, so it needs to be set to the existing value for reconfigure. Reproducer: #include <fcntl.h> #include <sys/mount.h> int main() { char opts[128]; int fd = open("/dev/fuse", O_RDWR); sprintf(opts, "fd=%d,rootmode=040000,user_id=0,group_id=0", fd); mkdir("mnt", 0777); mount("foo", "mnt", "", 0, opts); mount("foo", "mnt", "", MS_REMOUNT, opts); } Crash: BUG: kernel NULL pointer dereference, address: 0000000000000000 #PF: supervisor read access in kernel mode #PF: error_code(0x0000) - not-present page PGD 0 P4D 0 Oops: 0000 [#1] SMP CPU: 0 PID: 129 Comm: syz_make_kuid Not tainted 5.3.0-rc5-next-20190821 #3 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.12.0-20181126_142135-anatol 04/01/2014 RIP: 0010:map_id_range_down+0xb/0xc0 kernel/user_namespace.c:291 [...] Call Trace: map_id_down kernel/user_namespace.c:312 [inline] make_kuid+0xe/0x10 kernel/user_namespace.c:389 fuse_parse_param+0x116/0x210 fs/fuse/inode.c:523 vfs_parse_fs_param+0xdb/0x1b0 fs/fs_context.c:145 vfs_parse_fs_string+0x6a/0xa0 fs/fs_context.c:188 generic_parse_monolithic+0x85/0xc0 fs/fs_context.c:228 parse_monolithic_mount_data+0x1b/0x20 fs/fs_context.c:708 do_remount fs/namespace.c:2525 [inline] do_mount+0x39a/0xa60 fs/namespace.c:3107 ksys_mount+0x7d/0xd0 fs/namespace.c:3325 __do_sys_mount fs/namespace.c:3339 [inline] __se_sys_mount fs/namespace.c:3336 [inline] __x64_sys_mount+0x20/0x30 fs/namespace.c:3336 do_syscall_64+0x4a/0x1a0 arch/x86/entry/common.c:290 entry_SYSCALL_64_after_hwframe+0x49/0xbe Reported-by: Fixes: 408cbe695350 ("vfs: Convert fuse to use the new mount API") Cc: David Howells <> Cc: Miklos Szeredi <> Signed-off-by: Eric Biggers <> Reviewed-by: David Howells <> Signed-off-by: Al Viro <>
Diffstat (limited to 'fs/fs_context.c')
1 files changed, 1 insertions, 3 deletions
diff --git a/fs/fs_context.c b/fs/fs_context.c
index 103643c68e3f..87c2c9687d90 100644
--- a/fs/fs_context.c
+++ b/fs/fs_context.c
@@ -279,10 +279,8 @@ static struct fs_context *alloc_fs_context(struct file_system_type *fs_type,
fc->user_ns = get_user_ns(reference->d_sb->s_user_ns);
- /* We don't pin any namespaces as the superblock's
- * subscriptions cannot be changed at this point.
- */
+ fc->user_ns = get_user_ns(reference->d_sb->s_user_ns);
fc->root = dget(reference);