#5390·runc

rshared propagation (bind mount options and rootfsPropagation) silently results in private mounts; Kubernetes mountPropagation=Bidirectional inert (runc 1.4.2)

Author: beeekindCreated Aug 8, 2026Updated Aug 11, 2026
Labelsllm-generated

Description

With an OCI spec that requests rshared propagation — both as the option on bind mounts in spec.mounts and as linux.rootfsPropagation — the resulting container gets those mounts (and its rootfs) with no propagation peer groups at all: no shared: or master: optional fields in the container's /proc/self/mountinfo, i.e. fully private. Propagation is functionally dead in both directions for mounts created after container start: a filesystem mounted inside the container under an rshared bind never appears in the host's mount namespace.

The practical impact is that Kubernetes mountPropagation: Bidirectional (the CSI node-plugin pattern) silently does nothing: the kubelet and containerd both do their part (CRI reports PROPAGATION_BIDIRECTIONAL, the generated OCI spec carries rshared + rootfsPropagation: rshared), and the container still cannot expose a mount to the host. Nothing errors — the mounts are just private.

This looks like the rshared sibling of #5192 (fixed by #5200): same prepareRootfs make-private-then-restore area, but #5192/#5200 addressed the rslave/HostToContainer restore. In our capture on runc 1.4.2, the rshared case is broken too, and more broadly than the rootfs: the individual rshared bind mounts also come out private. I can't tell from #5200 whether its backports (labeled for release-1.4/1.5) also cover this path — if they do, treat this as a confirmation report with a reproducible environment.

Steps to reproduce

On a k3s v1.36.2+k3s1 node (containerd v2.3.2-k3s2, bundled runc 1.4.2), a privileged pod with:

yaml
volumeMounts:
  - name: cache
    mountPath: /srv/buildkit
    mountPropagation: Bidirectional
volumes:
  - name: cache
    persistentVolumeClaim:
      claimName: buildkit-cache   # static PV, hostPath /srv/buildkit
securityContext:
  privileged: true
  1. crictl inspect <cid> — CRI level is correct:
"containerPath": "/srv/buildkit", "propagation": "PROPAGATION_BIDIRECTIONAL"
  1. The generated OCI runtime spec is correct:
json
{
  "destination": "/srv/buildkit",
  "options": ["rbind", "rshared", "rw"],
  "source": "/srv/buildkit",
  "type": "bind"
}

with "rootfsPropagation": "rshared" in linux.

  1. Inside the running container, /proc/self/mountinfo:
202 200 0:106 / / rw,relatime - overlay overlay rw,lowerdir=...
375 202 8:1 /srv/buildkit /srv/buildkit rw,relatime - ext4 /dev/sda1 rw

No optional fields on either line — the rootfs and the bind are private, despite both rshared requests. (On the host, / is shared:1, systemd default; the source path is on the root fs.)

  1. Functional probe: inside the container, mkdir /srv/buildkit/proptest && mount -t tmpfs proptest /srv/buildkit/proptest. The mount appears in the container's mountinfo and never appears in the host's mount namespace (findmnt /srv/buildkit/proptest on the host: nothing).

Expected behavior

The bind mount at /srv/buildkit is a member of the host's peer group (shared:1 in the container's mountinfo), and the tmpfs mounted under it inside the container propagates to the host — Kubernetes Bidirectional semantics.

Environment

  • runc 1.4.2 (runc version 1.4.2, commit: v1.4.2-0-gc241c0b, spec: 1.3.0, libseccomp: 2.6.0), as bundled in k3s v1.36.2+k3s1
  • containerd v2.3.2-k3s2, runtime io.containerd.runc.v2
  • k3s v1.36.2+k3s1 (kubelet + containerd in host namespaces; host / is shared:1)
  • Ubuntu 24.04.4 LTS, kernel 6.8.0-136-generic, x86_64
  • No user namespaces; container is privileged

Caveat stated plainly: this was captured through the containerd/CRI stack on k3s, not with standalone runc run; the spec excerpts above are containerd's generated config.json, so runc received the rshared requests. Happy to gather more state from this environment or test a patched runc.

Discovered while diagnosing why a buildkitd pod's mounts never reached the host shim (moby/buildkit#4787 territory); full investigation trail with the raw captures: https://github.com/beeekind/infrastructure/issues/478#issuecomment-5223318251