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. -----BEGIN PGP SIGNATURE----- iHUEABYIAB0WIQQqUNBr3gm4hGXdBJlZ7Krx/gZQ6wUCYpvrWQAKCRBZ7Krx/gZQ 6z29AP9EZVSyIvnwXleehpa2mEZhsp+KAKgV/ENaKHMn7jiH0wD/bfgnhxIDNuc5 108E2R5RWEYTynW5k7nnP5PsTsMq5Qc= =b3Wc -----END PGP SIGNATURE----- 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)
This commit is contained in:
Коммит
cbd76edeab
|
@ -36,6 +36,7 @@
|
|||
#include <linux/types.h>
|
||||
#include <linux/ipc.h>
|
||||
#include <linux/namei.h>
|
||||
#include <linux/mount.h>
|
||||
#include <linux/uio.h>
|
||||
#include <linux/vfs.h>
|
||||
#include <linux/rcupdate.h>
|
||||
|
|
|
@ -119,7 +119,7 @@ SYSCALL_DEFINE2(fsopen, const char __user *, _fs_name, unsigned int, flags)
|
|||
const char *fs_name;
|
||||
int ret;
|
||||
|
||||
if (!ns_capable(current->nsproxy->mnt_ns->user_ns, CAP_SYS_ADMIN))
|
||||
if (!may_mount())
|
||||
return -EPERM;
|
||||
|
||||
if (flags & ~FSOPEN_CLOEXEC)
|
||||
|
@ -162,7 +162,7 @@ SYSCALL_DEFINE3(fspick, int, dfd, const char __user *, path, unsigned int, flags
|
|||
unsigned int lookup_flags;
|
||||
int ret;
|
||||
|
||||
if (!ns_capable(current->nsproxy->mnt_ns->user_ns, CAP_SYS_ADMIN))
|
||||
if (!may_mount())
|
||||
return -EPERM;
|
||||
|
||||
if ((flags & ~(FSPICK_CLOEXEC |
|
||||
|
|
|
@ -84,6 +84,7 @@ extern int __mnt_want_write_file(struct file *);
|
|||
extern void __mnt_drop_write_file(struct file *);
|
||||
|
||||
extern void dissolve_on_fput(struct vfsmount *);
|
||||
extern bool may_mount(void);
|
||||
|
||||
int path_mount(const char *dev_name, struct path *path,
|
||||
const char *type_page, unsigned long flags, void *data_page);
|
||||
|
|
|
@ -1760,7 +1760,7 @@ out_unlock:
|
|||
/*
|
||||
* Is the caller allowed to modify his namespace?
|
||||
*/
|
||||
static inline bool may_mount(void)
|
||||
bool may_mount(void)
|
||||
{
|
||||
return ns_capable(current->nsproxy->mnt_ns->user_ns, CAP_SYS_ADMIN);
|
||||
}
|
||||
|
|
|
@ -328,7 +328,7 @@ static struct file *__nfs42_ssc_open(struct vfsmount *ss_mnt,
|
|||
char *read_name = NULL;
|
||||
int len, status = 0;
|
||||
|
||||
server = NFS_SERVER(ss_mnt->mnt_root->d_inode);
|
||||
server = NFS_SB(ss_mnt->mnt_sb);
|
||||
|
||||
if (!fattr)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
@ -346,7 +346,7 @@ static struct file *__nfs42_ssc_open(struct vfsmount *ss_mnt,
|
|||
goto out;
|
||||
snprintf(read_name, len, SSC_READ_NAME_BODY, read_name_gen++);
|
||||
|
||||
r_ino = nfs_fhget(ss_mnt->mnt_root->d_inode->i_sb, src_fh, fattr);
|
||||
r_ino = nfs_fhget(ss_mnt->mnt_sb, src_fh, fattr);
|
||||
if (IS_ERR(r_ino)) {
|
||||
res = ERR_CAST(r_ino);
|
||||
goto out_free_name;
|
||||
|
|
|
@ -2469,22 +2469,11 @@ struct super_block *sget(struct file_system_type *type,
|
|||
|
||||
extern int register_filesystem(struct file_system_type *);
|
||||
extern int unregister_filesystem(struct file_system_type *);
|
||||
extern struct vfsmount *kern_mount(struct file_system_type *);
|
||||
extern void kern_unmount(struct vfsmount *mnt);
|
||||
extern int may_umount_tree(struct vfsmount *);
|
||||
extern int may_umount(struct vfsmount *);
|
||||
extern long do_mount(const char *, const char __user *,
|
||||
const char *, unsigned long, void *);
|
||||
extern struct vfsmount *collect_mounts(const struct path *);
|
||||
extern void drop_collected_mounts(struct vfsmount *);
|
||||
extern int iterate_mounts(int (*)(struct vfsmount *, void *), void *,
|
||||
struct vfsmount *);
|
||||
extern int vfs_statfs(const struct path *, struct kstatfs *);
|
||||
extern int user_statfs(const char __user *, struct kstatfs *);
|
||||
extern int fd_statfs(int, struct kstatfs *);
|
||||
extern int freeze_super(struct super_block *super);
|
||||
extern int thaw_super(struct super_block *super);
|
||||
extern bool our_mnt(struct vfsmount *mnt);
|
||||
extern __printf(2, 3)
|
||||
int super_setup_bdi_name(struct super_block *sb, char *fmt, ...);
|
||||
extern int super_setup_bdi(struct super_block *sb);
|
||||
|
|
|
@ -11,17 +11,15 @@
|
|||
#define _LINUX_MOUNT_H
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/nodemask.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/seqlock.h>
|
||||
#include <linux/atomic.h>
|
||||
#include <asm/barrier.h>
|
||||
|
||||
struct super_block;
|
||||
struct vfsmount;
|
||||
struct dentry;
|
||||
struct mnt_namespace;
|
||||
struct user_namespace;
|
||||
struct file_system_type;
|
||||
struct fs_context;
|
||||
struct file;
|
||||
struct path;
|
||||
|
||||
#define MNT_NOSUID 0x01
|
||||
#define MNT_NODEV 0x02
|
||||
|
@ -81,9 +79,6 @@ static inline struct user_namespace *mnt_user_ns(const struct vfsmount *mnt)
|
|||
return smp_load_acquire(&mnt->mnt_userns);
|
||||
}
|
||||
|
||||
struct file; /* forward dec */
|
||||
struct path;
|
||||
|
||||
extern int mnt_want_write(struct vfsmount *mnt);
|
||||
extern int mnt_want_write_file(struct file *file);
|
||||
extern void mnt_drop_write(struct vfsmount *mnt);
|
||||
|
@ -94,12 +89,10 @@ extern struct vfsmount *mnt_clone_internal(const struct path *path);
|
|||
extern bool __mnt_is_readonly(struct vfsmount *mnt);
|
||||
extern bool mnt_may_suid(struct vfsmount *mnt);
|
||||
|
||||
struct path;
|
||||
extern struct vfsmount *clone_private_mount(const struct path *path);
|
||||
extern int __mnt_want_write(struct vfsmount *);
|
||||
extern void __mnt_drop_write(struct vfsmount *);
|
||||
|
||||
struct file_system_type;
|
||||
extern struct vfsmount *fc_mount(struct fs_context *fc);
|
||||
extern struct vfsmount *vfs_create_mount(struct fs_context *fc);
|
||||
extern struct vfsmount *vfs_kern_mount(struct file_system_type *type,
|
||||
|
@ -115,6 +108,18 @@ extern void mark_mounts_for_expiry(struct list_head *mounts);
|
|||
extern dev_t name_to_dev_t(const char *name);
|
||||
extern bool path_is_mountpoint(const struct path *path);
|
||||
|
||||
extern bool our_mnt(struct vfsmount *mnt);
|
||||
|
||||
extern struct vfsmount *kern_mount(struct file_system_type *);
|
||||
extern void kern_unmount(struct vfsmount *mnt);
|
||||
extern int may_umount_tree(struct vfsmount *);
|
||||
extern int may_umount(struct vfsmount *);
|
||||
extern long do_mount(const char *, const char __user *,
|
||||
const char *, unsigned long, void *);
|
||||
extern struct vfsmount *collect_mounts(const struct path *);
|
||||
extern void drop_collected_mounts(struct vfsmount *);
|
||||
extern int iterate_mounts(int (*)(struct vfsmount *, void *), void *,
|
||||
struct vfsmount *);
|
||||
extern void kern_unmount_array(struct vfsmount *mnt[], unsigned int num);
|
||||
|
||||
#endif /* _LINUX_MOUNT_H */
|
||||
|
|
|
@ -28,7 +28,7 @@ static struct vfsmount *blob_to_mnt(const void *data, size_t len, const char *na
|
|||
|
||||
file = file_open_root_mnt(mnt, name, O_CREAT | O_WRONLY, 0700);
|
||||
if (IS_ERR(file)) {
|
||||
mntput(mnt);
|
||||
kern_unmount(mnt);
|
||||
return ERR_CAST(file);
|
||||
}
|
||||
|
||||
|
@ -38,7 +38,7 @@ static struct vfsmount *blob_to_mnt(const void *data, size_t len, const char *na
|
|||
if (err >= 0)
|
||||
err = -ENOMEM;
|
||||
filp_close(file, NULL);
|
||||
mntput(mnt);
|
||||
kern_unmount(mnt);
|
||||
return ERR_PTR(err);
|
||||
}
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include <linux/ctype.h>
|
||||
#include <linux/audit.h>
|
||||
#include <linux/magic.h>
|
||||
#include <linux/mount.h>
|
||||
#include <linux/fs_context.h>
|
||||
#include "smack.h"
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче