Skip to content

fix(libcontainer): preserve rootfs slave propagation for rslave containers#5200

Merged
kolyshkin merged 2 commits into
opencontainers:mainfrom
xujihui1985:fix/rootfs-propagation
Apr 13, 2026
Merged

fix(libcontainer): preserve rootfs slave propagation for rslave containers#5200
kolyshkin merged 2 commits into
opencontainers:mainfrom
xujihui1985:fix/rootfs-propagation

Conversation

@xujihui1985

@xujihui1985 xujihui1985 commented Mar 28, 2026

Copy link
Copy Markdown
Contributor

When rootfsPropagation is set to rslave, prepareRoot() was forcing the rootfs parent mount to MS_PRIVATE before bind-mounting and pivoting into the rootfs. That breaks the slave relationship needed for HostToContainer propagation, so later unmount/remount events on host mountpoints under the rootfs are not reflected inside the running container.

Fix this by keeping the rootfs parent mount as MS_SLAVE for slave-like rootfs propagation settings, while leaving the final root propagation remount in place.

Fixes: #5192

@xujihui1985

Copy link
Copy Markdown
Contributor Author

@lifubang Please take look at this PR that fix issue #5192

@lifubang

Copy link
Copy Markdown
Member

Thanks, I'll take a look next week. One small request: please use git rebase main instead of git merge main.

@xujihui1985 xujihui1985 force-pushed the fix/rootfs-propagation branch 2 times, most recently from 739bdaa to 2a80f7b Compare March 29, 2026 02:44

@lifubang lifubang left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!
The patch looks correct, though I've left a few comments. Also, could you move the integration test to a separate commit? It would make it easier for maintainers to review the changes step-by-step.

Comment thread libcontainer/rootfs_linux.go Outdated
Comment thread libcontainer/rootfs_linux_test.go Outdated
}
}

func TestRootfsParentMountPropagationFlags(t *testing.T) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice, thanks for the detailed test cases.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OTOH I don't think this test makes sense. The code which it tests is:

func rootfsParentMountPropagationFlags(rootPropagation int) uintptr {
	if rootPropagation&unix.MS_SLAVE != 0 {
		return unix.MS_SLAVE
	}
	return unix.MS_PRIVATE
}

and I don't think this code is that complicated to deserve a test case. You can "test" it by just reading it.

More to say, if we ever want to change it for whatever reason, it's more work now (as the test cases will fail).

So I'd rather remove the unit test. @lifubang WDYT?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In fact, I originally wanted to keep this unit test to ensure we wouldn’t forget MS_SLAVE during future refactoring. However, now that we have an integration test covering this behavior -- and although the logic is simple yet critical -- I think we can safely remove the unit test.
@xujihui1985

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, unittest for this function has been removed

Comment thread libcontainer/integration/exec_test.go Outdated
Comment thread libcontainer/integration/exec_test.go Outdated
@xujihui1985 xujihui1985 force-pushed the fix/rootfs-propagation branch 5 times, most recently from 928a051 to dc1ae2a Compare March 30, 2026 15:46
Comment thread tests/integration/mounts_propagation.bats Outdated
@kolyshkin

Copy link
Copy Markdown
Contributor

@xujihui1985 you also need to run make shfmt to fix bats formatting

@xujihui1985 xujihui1985 force-pushed the fix/rootfs-propagation branch 3 times, most recently from 5e9e5e0 to 7e21150 Compare March 31, 2026 16:04
Comment thread tests/integration/mounts_propagation.bats Outdated
Comment thread tests/integration/mounts_propagation.bats Outdated
@xujihui1985 xujihui1985 force-pushed the fix/rootfs-propagation branch from 7e21150 to 30275eb Compare April 1, 2026 14:06
kolyshkin added a commit to kolyshkin/runc that referenced this pull request Apr 1, 2026
Some of runc integration tests may do something that I would not like
when running those on my development laptop. Examples include

 - changing the root mount propagation [1];
 - replacing /root/runc [2];
 - changing the file in /etc (see checkpoint.bats).

Yet it is totally fine to do all that in a throwaway CI environment,
or inside a Docker container.

Introduce a mechanism to skip specific "unsafe" tests unless an
environment variable, RUNC_ALLOW_UNSAFE_TESTS, is set. Use it
from a specific checkpoint/restore test which modifies
/etc/criu/default.conf.

[1]: opencontainers#5200
[2]: opencontainers#5207

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
@xujihui1985 xujihui1985 force-pushed the fix/rootfs-propagation branch from 30275eb to f77f958 Compare April 2, 2026 02:15
kolyshkin added a commit to kolyshkin/runc that referenced this pull request Apr 2, 2026
Some of runc integration tests may do something that I would not like
when running those on my development laptop. Examples include

 - changing the root mount propagation [1];
 - replacing /root/runc [2];
 - changing the file in /etc (see checkpoint.bats).

Yet it is totally fine to do all that in a throwaway CI environment,
or inside a Docker container.

Introduce a mechanism to skip specific "unsafe" tests unless an
environment variable, RUNC_ALLOW_UNSAFE_TESTS, is set. Use it
from a specific checkpoint/restore test which modifies
/etc/criu/default.conf.

[1]: opencontainers#5200
[2]: opencontainers#5207

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
@kolyshkin

Copy link
Copy Markdown
Contributor

The test in this PR (which modifies / propagation) should benefit from the feature from #5212, so if that one is approved and merged, the test here needs to add require unsafe.

kolyshkin added a commit to kolyshkin/runc that referenced this pull request Apr 3, 2026
Some of runc integration tests may do something that I would not like
when running those on my development laptop. Examples include

 - changing the root mount propagation [1];
 - replacing /root/runc [2];
 - changing the file in /etc (see checkpoint.bats).

Yet it is totally fine to do all that in a throwaway CI environment,
or inside a Docker container.

Introduce a mechanism to skip specific "unsafe" tests unless an
environment variable, RUNC_ALLOW_UNSAFE_TESTS, is set. Use it
from a specific checkpoint/restore test which modifies
/etc/criu/default.conf.

[1]: opencontainers#5200
[2]: opencontainers#5207

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
@xujihui1985 xujihui1985 force-pushed the fix/rootfs-propagation branch from f77f958 to a191f22 Compare April 3, 2026 11:03
Comment thread tests/integration/mounts_propagation_unsafe.bats Outdated
@xujihui1985 xujihui1985 force-pushed the fix/rootfs-propagation branch 3 times, most recently from 14eafe9 to d5951ea Compare April 7, 2026 14:46
@xujihui1985 xujihui1985 force-pushed the fix/rootfs-propagation branch 2 times, most recently from 3382d5d to f15a20b Compare April 9, 2026 13:58
Comment thread libcontainer/rootfs_linux.go Outdated

@lifubang lifubang left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM with one nit.
Thanks!

@xujihui1985 xujihui1985 force-pushed the fix/rootfs-propagation branch 2 times, most recently from a09515f to 0d3e2ca Compare April 11, 2026 02:20
When rootfsPropagation is set to rslave, prepareRoot() was forcing the
rootfs parent mount to MS_PRIVATE before bind-mounting and pivoting into
the rootfs. That breaks the slave relationship needed for HostToContainer
propagation, so later unmount/remount events on host mountpoints under
the rootfs are not reflected inside the running container.

Fix this by keeping the rootfs parent mount as MS_SLAVE for slave-like
rootfs propagation settings, while leaving the final root propagation
remount in place.

Signed-off-by: sean <xujihui1985@gmail.com>
add bat integration test for rootfs propagation test, expect to
see the mount propagation is slave, the test will create a isolate mntns
to run the test as the test will mutate the rootfs propagation

Signed-off-by: sean <xujihui1985@gmail.com>
@xujihui1985 xujihui1985 force-pushed the fix/rootfs-propagation branch from 0d3e2ca to 38245cc Compare April 11, 2026 02:23

@kolyshkin kolyshkin left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thank you

@kolyshkin kolyshkin enabled auto-merge April 13, 2026 04:52
@kolyshkin kolyshkin merged commit edbed61 into opencontainers:main Apr 13, 2026
54 checks passed
@xujihui1985

Copy link
Copy Markdown
Contributor Author

@kolyshkin @lifubang Thanks for reviewing the MR. This was a great learning opportunity, and I learned a lot from this process.

@kolyshkin

Copy link
Copy Markdown
Contributor

@lifubang you set 1.3.6 milestone for the issue this PR fixes (#5192); does that mean you want 1.3, 1.4 and 1.5 backports? When answering this, please consider whether it can bring some other regressions.

If the answer is yes, please add appropriate labels (feel free to open the backports, too).

@lifubang

lifubang commented Apr 14, 2026

Copy link
Copy Markdown
Member

you set 1.3.6 milestone for the issue this PR fixes (#5192); does that mean you want 1.3, 1.4 and 1.5 backports? When answering this, please consider whether it can bring some other regressions.

If the answer is yes, please add appropriate labels (feel free to open the backports, too).

I set the 1.3.6 milestone because this bug affects all releases from 1.3.x through 1.5.x, and the impact is broader than it appears:

  1. Silent semantic regression: Users configuring rootfsPropagation: rslave get no error -- the container starts fine, but mount propagation silently falls back to rprivate. This is extremely hard to debug in production.

  2. K8s 1.35 uses runc 1.3.x: Per containerd's release docs, K8s 1.35 recommends containerd 2.2.x/2.1.x/1.7.x, all of which bundle runc 1.3.4/1.3.5. Without a backport, this bug persists in current and upcoming Kubernetes deployments.

  3. Docker 29.4.0 uses runc 1.3.5: The latest Docker release also carries this bug. Affecting both major container ecosystems justifies the backport effort.

  4. Low regression risk: The fix is minimal and conservative -- only changes behavior when rootPropagation & MS_SLAVE != 0. All other paths remain identical.

@xujihui1985 WDYT?

@lifubang lifubang added backport/1.3-todo A PR in main branch which needs to be backported to release-1.3 backport/1.4-todo A PR in main branch which needs to backported to release-1.4 backport/1.5-todo A PR in main branch which needs to be backported to release-1.5 labels Apr 14, 2026
@lifubang

lifubang commented Apr 14, 2026

Copy link
Copy Markdown
Member

Oh, looking at the actual OCI spec generated by Kubernetes/docker, there's no linux.rootfsPropagation field set. So this bug only affects users who directly configure rootfsPropagation: rslave in runc. Given the limited impact, let's only backport to release-1.5.

@lifubang lifubang removed backport/1.3-todo A PR in main branch which needs to be backported to release-1.3 backport/1.4-todo A PR in main branch which needs to backported to release-1.4 labels Apr 14, 2026
@xujihui1985

Copy link
Copy Markdown
Contributor Author

Oh, looking at the actual OCI spec generated by Kubernetes/docker, there's no linux.rootfsPropagation field set. So this bug only affects users who directly configure rootfsPropagation: rslave in runc. Given the limited impact, let's only backport to release-1.5.

image https://github.com/containerd/containerd/blob/f006ee06cabf52ee4a32429487b93d334c009589/internal/cri/opts/spec_linux_opts.go#L173 @lifubang I didn't test on the latest kubernetes and containerd, but from our internal version, the rootfsPropagation actually set on the bundle json, I'm not sure right now if this is a internal feature, I will check it later

@lifubang

lifubang commented May 7, 2026

Copy link
Copy Markdown
Member

I'm not sure right now if this is a internal feature, I will check it later

Have you had a chance to look into it yet?

@xujihui1985

Copy link
Copy Markdown
Contributor Author

I'm not sure right now if this is a internal feature, I will check it later

Have you had a chance to look into it yet?

Hi, I check the current upstream version from internal codebase, it's from 1.5.4, and it's not an internal logic, https://github.com/containerd/containerd/blob/v1.5.4/pkg/cri/opts/spec_linux.go#L180-L197

@lifubang

Copy link
Copy Markdown
Member

Thanks, this appears to be a long-standing bug. Do you think we should backport this to release-1.3? Since many of us are still running runc 1.3.x in production, it seems worth fixing.
Feel free to open the backport PRs.

@lifubang lifubang added the backport/1.4-todo A PR in main branch which needs to backported to release-1.4 label May 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backport/1.4-todo A PR in main branch which needs to backported to release-1.4 backport/1.5-todo A PR in main branch which needs to be backported to release-1.5 kind/bug

Projects

None yet

Development

Successfully merging this pull request may close these issues.

rootfs mount propagation cannot be restored to rslave after being made private in prepareRootfs

3 participants