On Tue, Feb 06, 2024 at 11:22:09AM +0100, Christian Brauner wrote:
When we added mount_setattr() I added additional checks compared to the legacy do_reconfigure_mnt() and do_change_type() helpers used by regular mount(2). If that mount had a parent then verify that the caller and the mount namespace the mount is attached to match and if not make sure that it's an anonymous mount.
The real rootfs falls into neither category. It is neither an anoymous mount because it is obviously attached to the initial mount namespace but it also obviously doesn't have a parent mount. So that means legacy mount(2) allows changing mount properties on the real rootfs but mount_setattr(2) blocks this. I never thought much about this but of course someone on this planet of earth changes properties on the real rootfs as can be seen in [1].
Since util-linux finally switched to the new mount api in 2.39 not so long ago it also relies on mount_setattr() and that surfaced this issue when Fedora 39 finally switched to it. Fix this.
Link: https://bugzilla.redhat.com/show_bug.cgi?id=2256843 Reported-by: Karel Zak kzak@redhat.com Cc: stable@vger.kernel.org # v5.12+ Signed-off-by: Christian Brauner brauner@kernel.org
Fwiw, I've been going back and forth on this yesterday evening because of an inconsistency in legacy mount(2). The gist is that for changing generic mount properties via do_reconfigure_mnt() we check_mnt() but for changing mount propagation settings via do_change_type() we don't. For mount_setattr(2) we should do better. So the change I originally went with didn't bother to do check_mnt() when that thing doesn't have a parent to be true to mount propagation behavior in legacy mount(2). But I think that this is wrong and this should be if ((mnt_has_parent(mnt) || !is_anon_ns(mnt->mnt_ns)) && !check_mnt(mnt)) which means we do check_mnt() even for the real rootfs which doesn't have a parent and for both regular and mount propagation properties. I've changed the patch to that.