mirror of
https://github.com/torvalds/linux.git
synced 2026-11-09 13:44:03 +01:00
mount: refuse MOVE_MOUNT_SET_GROUP on an unbindable mount
do_set_group() only accepts mounts as targets that are neither shared
nor a slave. That encompasses undindable mounts.
If the source mount is a slave mount the target mount will end up with
source's master as its master. It keeps T_UNBINDABLE. That means we get
a mount that is both unbindable and a slave:
mount --bind /tmp/src /tmp/src
mount --make-shared /tmp/src
mount --bind /tmp/src /tmp/b
mount --make-slave /tmp/b
mount --bind /tmp/src /tmp/c
mount --make-unbindable /tmp/c
move_mount(b, "", c, "", MOVE_MOUNT_SET_GROUP)
grep /tmp/c /proc/self/mountinfo
... /tmp/c ... master:646 unbindable ...
This property cannot be produced any other way. change_mnt_propagation()
drops the master when it makes a mount unbindable (iow, it becomes
private) and doesn't touch an unbindable mount when it is supposed to
turned into a slave mount.
End-result is that the unbindable-slave mount receives everything
propagated from its master's peer group while it can't be bind mounted
itself. Not sure what that's supposed to do.
On the other side: if the source mount is shared, the target mount drops
T_UNBINDABLE because because set_mnt_shared() clears T_SHARED_MASK.
So teach do_set_group() to refuse an unbindable target mount the same
way a shared or slave target mount is refused.
The main user of MOVE_MOUNT_SET_GROUP is CRIU which restores sharing
first and applies MS_UNBINDABLE afterwards. It never hits this.
Link: https://patch.msgid.link/20260923-work-mount-fixes-v1-3-f424cf8d3242@kernel.org
Fixes: 9ffb14ef61 ("move_mount: allow to add a mount into an existing group")
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
This commit is contained in:
parent
0bab6b6d77
commit
a2b42babc9
|
|
@ -3468,7 +3468,7 @@ static int do_set_group(const struct path *from_path, const struct path *to_path
|
|||
return -EINVAL;
|
||||
|
||||
/* Setting sharing groups is only allowed on private mounts */
|
||||
if (IS_MNT_SHARED(to) || IS_MNT_SLAVE(to))
|
||||
if (IS_MNT_SHARED(to) || IS_MNT_SLAVE(to) || IS_MNT_UNBINDABLE(to))
|
||||
return -EINVAL;
|
||||
|
||||
/* From should not be private */
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user