Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'pull-18-rc1-work.mount' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs

Pull mount handling updates from Al Viro:
"Cleanups (and one fix) around struct mount handling.

The fix is usermode_driver.c one - once you've done kern_mount(), you
must kern_unmount(); simple mntput() will end up with a leak. Several
failure exits in there messed up that way... In practice you won't hit
those particular failure exits without fault injection, though"

* tag 'pull-18-rc1-work.mount' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs:
move mount-related externs from fs.h to mount.h
blob_to_mnt(): kern_unmount() is needed to undo kern_mount()
m->mnt_root->d_inode->i_sb is a weird way to spell m->mnt_sb...
linux/mount.h: trim includes
uninline may_mount() and don't opencode it in fspick(2)/fsopen(2)

+27 -30
+1
arch/alpha/kernel/osf_sys.c
··· 36 36 #include <linux/types.h> 37 37 #include <linux/ipc.h> 38 38 #include <linux/namei.h> 39 + #include <linux/mount.h> 39 40 #include <linux/uio.h> 40 41 #include <linux/vfs.h> 41 42 #include <linux/rcupdate.h>
+2 -2
fs/fsopen.c
··· 119 119 const char *fs_name; 120 120 int ret; 121 121 122 - if (!ns_capable(current->nsproxy->mnt_ns->user_ns, CAP_SYS_ADMIN)) 122 + if (!may_mount()) 123 123 return -EPERM; 124 124 125 125 if (flags & ~FSOPEN_CLOEXEC) ··· 162 162 unsigned int lookup_flags; 163 163 int ret; 164 164 165 - if (!ns_capable(current->nsproxy->mnt_ns->user_ns, CAP_SYS_ADMIN)) 165 + if (!may_mount()) 166 166 return -EPERM; 167 167 168 168 if ((flags & ~(FSPICK_CLOEXEC |
+1
fs/internal.h
··· 84 84 extern void __mnt_drop_write_file(struct file *); 85 85 86 86 extern void dissolve_on_fput(struct vfsmount *); 87 + extern bool may_mount(void); 87 88 88 89 int path_mount(const char *dev_name, struct path *path, 89 90 const char *type_page, unsigned long flags, void *data_page);
+1 -1
fs/namespace.c
··· 1760 1760 /* 1761 1761 * Is the caller allowed to modify his namespace? 1762 1762 */ 1763 - static inline bool may_mount(void) 1763 + bool may_mount(void) 1764 1764 { 1765 1765 return ns_capable(current->nsproxy->mnt_ns->user_ns, CAP_SYS_ADMIN); 1766 1766 }
+2 -2
fs/nfs/nfs4file.c
··· 328 328 char *read_name = NULL; 329 329 int len, status = 0; 330 330 331 - server = NFS_SERVER(ss_mnt->mnt_root->d_inode); 331 + server = NFS_SB(ss_mnt->mnt_sb); 332 332 333 333 if (!fattr) 334 334 return ERR_PTR(-ENOMEM); ··· 346 346 goto out; 347 347 snprintf(read_name, len, SSC_READ_NAME_BODY, read_name_gen++); 348 348 349 - r_ino = nfs_fhget(ss_mnt->mnt_root->d_inode->i_sb, src_fh, fattr); 349 + r_ino = nfs_fhget(ss_mnt->mnt_sb, src_fh, fattr); 350 350 if (IS_ERR(r_ino)) { 351 351 res = ERR_CAST(r_ino); 352 352 goto out_free_name;
-11
include/linux/fs.h
··· 2469 2469 2470 2470 extern int register_filesystem(struct file_system_type *); 2471 2471 extern int unregister_filesystem(struct file_system_type *); 2472 - extern struct vfsmount *kern_mount(struct file_system_type *); 2473 - extern void kern_unmount(struct vfsmount *mnt); 2474 - extern int may_umount_tree(struct vfsmount *); 2475 - extern int may_umount(struct vfsmount *); 2476 - extern long do_mount(const char *, const char __user *, 2477 - const char *, unsigned long, void *); 2478 - extern struct vfsmount *collect_mounts(const struct path *); 2479 - extern void drop_collected_mounts(struct vfsmount *); 2480 - extern int iterate_mounts(int (*)(struct vfsmount *, void *), void *, 2481 - struct vfsmount *); 2482 2472 extern int vfs_statfs(const struct path *, struct kstatfs *); 2483 2473 extern int user_statfs(const char __user *, struct kstatfs *); 2484 2474 extern int fd_statfs(int, struct kstatfs *); 2485 2475 extern int freeze_super(struct super_block *super); 2486 2476 extern int thaw_super(struct super_block *super); 2487 - extern bool our_mnt(struct vfsmount *mnt); 2488 2477 extern __printf(2, 3) 2489 2478 int super_setup_bdi_name(struct super_block *sb, char *fmt, ...); 2490 2479 extern int super_setup_bdi(struct super_block *sb);
+17 -12
include/linux/mount.h
··· 11 11 #define _LINUX_MOUNT_H 12 12 13 13 #include <linux/types.h> 14 - #include <linux/list.h> 15 - #include <linux/nodemask.h> 16 - #include <linux/spinlock.h> 17 - #include <linux/seqlock.h> 18 - #include <linux/atomic.h> 14 + #include <asm/barrier.h> 19 15 20 16 struct super_block; 21 - struct vfsmount; 22 17 struct dentry; 23 - struct mnt_namespace; 18 + struct user_namespace; 19 + struct file_system_type; 24 20 struct fs_context; 21 + struct file; 22 + struct path; 25 23 26 24 #define MNT_NOSUID 0x01 27 25 #define MNT_NODEV 0x02 ··· 79 81 return smp_load_acquire(&mnt->mnt_userns); 80 82 } 81 83 82 - struct file; /* forward dec */ 83 - struct path; 84 - 85 84 extern int mnt_want_write(struct vfsmount *mnt); 86 85 extern int mnt_want_write_file(struct file *file); 87 86 extern void mnt_drop_write(struct vfsmount *mnt); ··· 89 94 extern bool __mnt_is_readonly(struct vfsmount *mnt); 90 95 extern bool mnt_may_suid(struct vfsmount *mnt); 91 96 92 - struct path; 93 97 extern struct vfsmount *clone_private_mount(const struct path *path); 94 98 extern int __mnt_want_write(struct vfsmount *); 95 99 extern void __mnt_drop_write(struct vfsmount *); 96 100 97 - struct file_system_type; 98 101 extern struct vfsmount *fc_mount(struct fs_context *fc); 99 102 extern struct vfsmount *vfs_create_mount(struct fs_context *fc); 100 103 extern struct vfsmount *vfs_kern_mount(struct file_system_type *type, ··· 108 115 extern dev_t name_to_dev_t(const char *name); 109 116 extern bool path_is_mountpoint(const struct path *path); 110 117 118 + extern bool our_mnt(struct vfsmount *mnt); 119 + 120 + extern struct vfsmount *kern_mount(struct file_system_type *); 121 + extern void kern_unmount(struct vfsmount *mnt); 122 + extern int may_umount_tree(struct vfsmount *); 123 + extern int may_umount(struct vfsmount *); 124 + extern long do_mount(const char *, const char __user *, 125 + const char *, unsigned long, void *); 126 + extern struct vfsmount *collect_mounts(const struct path *); 127 + extern void drop_collected_mounts(struct vfsmount *); 128 + extern int iterate_mounts(int (*)(struct vfsmount *, void *), void *, 129 + struct vfsmount *); 111 130 extern void kern_unmount_array(struct vfsmount *mnt[], unsigned int num); 112 131 113 132 #endif /* _LINUX_MOUNT_H */
+2 -2
kernel/usermode_driver.c
··· 28 28 29 29 file = file_open_root_mnt(mnt, name, O_CREAT | O_WRONLY, 0700); 30 30 if (IS_ERR(file)) { 31 - mntput(mnt); 31 + kern_unmount(mnt); 32 32 return ERR_CAST(file); 33 33 } 34 34 ··· 38 38 if (err >= 0) 39 39 err = -ENOMEM; 40 40 filp_close(file, NULL); 41 - mntput(mnt); 41 + kern_unmount(mnt); 42 42 return ERR_PTR(err); 43 43 } 44 44
+1
security/smack/smackfs.c
··· 23 23 #include <linux/ctype.h> 24 24 #include <linux/audit.h> 25 25 #include <linux/magic.h> 26 + #include <linux/mount.h> 26 27 #include <linux/fs_context.h> 27 28 #include "smack.h" 28 29