Loosen the permission check on forced umount to allow users holding CAP_SYS_ADMIN privileges in namespaces that are privileged with respect to the userns that originally mounted the filesystem.
Unified · Split
| @@ -2105,6 +2105,7 @@ static void warn_mandlock(void) · 2104 unmodified lines | |||
| 2105 | static int can_umount(const struct path *path, int flags) | 2105 | static int can_umount(const struct path *path, int flags) |
| 2106 | { | 2106 | { |
| 2107 | struct mount *mnt = real_mount(path->mnt); | 2107 | struct mount *mnt = real_mount(path->mnt); |
| 2108 | struct super_block *sb = path->dentry->d_sb; | ||
| 2108 | 2109 | ||
| 2109 | if (!may_mount()) | 2110 | if (!may_mount()) |
| 2110 | return -EPERM; | 2111 | return -EPERM; |
| @@ -2114,7 +2115,7 @@ static int can_umount(const struct path *path, int flags) · 3 unmodified lines | |||
| 2114 | return -EINVAL; | 2115 | return -EINVAL; |
| 2115 | if (mnt->mnt.mnt_flags & MNT_LOCKED) /* Check optimistically */ | 2116 | if (mnt->mnt.mnt_flags & MNT_LOCKED) /* Check optimistically */ |
| 2116 | return -EINVAL; | 2117 | return -EINVAL; |
| 2117 | if (flags & MNT_FORCE && !capable(CAP_SYS_ADMIN)) | 2118 | if (flags & MNT_FORCE && !ns_capable(sb->s_user_ns, CAP_SYS_ADMIN)) |
| 2118 | return -EPERM; | 2119 | return -EPERM; |
| 2119 | return 0; | 2120 | return 0; |
| 2120 | } | 2121 | } |