backport path unmount

Signed-off-by: xenxynon <flynryder427@gmail.com>
This commit is contained in:
xenxynon
2025-01-31 04:55:46 +00:00
committed by nyxalune
parent b724213c2a
commit 90832ed56f
2 changed files with 31 additions and 0 deletions

View File

@@ -85,6 +85,7 @@ extern int finish_automount(struct vfsmount *, struct path *);
extern int sb_prepare_remount_readonly(struct super_block *); extern int sb_prepare_remount_readonly(struct super_block *);
extern void __init mnt_init(void); extern void __init mnt_init(void);
int path_umount(struct path *path, int flags);
extern int __mnt_want_write_file(struct file *); extern int __mnt_want_write_file(struct file *);
extern void __mnt_drop_write_file(struct file *); extern void __mnt_drop_write_file(struct file *);

View File

@@ -1750,6 +1750,36 @@ SYSCALL_DEFINE1(oldumount, char __user *, name)
#endif #endif
static int can_umount(const struct path *path, int flags)
{
struct mount *mnt = real_mount(path->mnt);
if (flags & ~(MNT_FORCE | MNT_DETACH | MNT_EXPIRE | UMOUNT_NOFOLLOW))
return -EINVAL;
if (!may_mount())
return -EPERM;
if (path->dentry != path->mnt->mnt_root)
return -EINVAL;
if (!check_mnt(mnt))
return -EINVAL;
if (mnt->mnt.mnt_flags & MNT_LOCKED)
return -EINVAL;
if (flags & MNT_FORCE && !capable(CAP_SYS_ADMIN))
return -EPERM;
return 0;
}
int path_umount(struct path *path, int flags)
{
struct mount *mnt = real_mount(path->mnt);
int ret;
ret = can_umount(path, flags);
if (!ret)
ret = do_umount(mnt, flags);
dput(path->dentry);
mntput_no_expire(mnt);
return ret;
}
static bool is_mnt_ns_file(struct dentry *dentry) static bool is_mnt_ns_file(struct dentry *dentry)
{ {
/* Is this a proxy for a mount namespace? */ /* Is this a proxy for a mount namespace? */