Skip to content

fix: mount namespace propagation - #99

Merged
tgross merged 3 commits into
mainfrom
fix-mount-namespace-propagation
Aug 14, 2026
Merged

fix: mount namespace propagation#99
tgross merged 3 commits into
mainfrom
fix-mount-namespace-propagation

Conversation

@ritesh-harihar

@ritesh-harihar ritesh-harihar commented Aug 12, 2026

Copy link
Copy Markdown
Collaborator

Fixes: #74

Summary

exec2 tasks could not see autofs-mounted filesystems (or any other host mount created after the task started) because unshare --mount-proc implicitly created a mount namespace with MS_PRIVATE propagation, severing it from the host's mount tree. Adding --propagation slave restores propagation in one direction — host mounts flow into the task, task mounts do not leak to the host.

Root Cause

exec2 creates its task process tree using unshare. The --mount-proc flag is required to give the new PID namespace a private /proc, but this forces unshare to create a new mount namespace, and without an explicit --propagation flag that namespace defaults to MS_PRIVATE for every mount point.

MS_PRIVATE does not prevent mounts that existed before the namespace was created from being visible (they are snapshotted in). It prevents mounts created on the host after the namespace exists from propagating in. This is exactly how autofs works, it creates mounts on demand, after tasks are already running.

The kernel records propagation type in /proc/self/mountinfo.

State Root mount entry in /proc/self/mountinfo Meaning
Before fix ... / rw,noatime - btrfs ... ✗ No peer group — MS_PRIVATE
After fix ... / rw,noatime master:35 - btrfs ... ✓ Slave of peer group 35 — receives host propagation

Options explored

Option Issue
--propagation slave (chosen) correct on every host, no new privileges, no config surface
--propagation unchanged Works on some hosts, silently fails on others (it inherits whatever propagation the parent namespace has, which varies by host and container environment)
mount --make-slave in shim Needs elevated privilege just to work around something unshare already handles natively
Config option Exposes the broken state as a valid choice; no real use case for any value except slave

Practical example

  • Before fix: task fails with No such file or directory — mount not even visible.
  • After fix, without unveil: task fails with Permission denied — mount visible, Landlock blocks it.
  • After fix, with unveil:
config {
  command = "/bin/cat"
  args    = ["/nfs/data/file.txt"]
  unveil  = ["r:/nfs/data"]
}

Task succeeds mount visible and Landlock allows access.

This PR fixes the prerequisite that was completely broken. The Landlock layer was already working correctly and just needs the operator to unveil the autofs paths as they would for any other filesystem path. The two layers are independent and both must be satisfied.

Testing

Details
 job "mount-test" {
  type = "batch"
  group "group" {
    task "check" {
      driver = "exec2"
      config {
        command = "/usr/bin/awk"
        args    = ["NR==1", "/proc/self/mountinfo"]
        unveil  = ["r:/proc"]
      }
    }
  }
}

Before:

riteshharihar@podman-dev:/Users/riteshharihar/Desktop/Src/nomad-driver-exec2$ nomad job run /tmp/mount-test.hcl
==> 2026-08-11T15:13:55+05:30: Monitoring evaluation "65364008"
    2026-08-11T15:13:55+05:30: Evaluation triggered by job "mount-test"
    2026-08-11T15:13:56+05:30: Allocation "ca908b94" created: node "e2feae5d", group "group"
    2026-08-11T15:13:56+05:30: Evaluation status changed: "pending" -> "complete"
==> 2026-08-11T15:13:56+05:30: Evaluation "65364008" finished with status "complete"

riteshharihar@podman-dev:/Users/riteshharihar/Desktop/Src/nomad-driver-exec2$ nomad alloc logs 
811 808 0:38 /scon/containers/01KS4F7XKHAVX614ZKDHGS499Q/rootfs / rw,noatime - btrfs /dev/vdb1 rw,nodatasum,nodatacow,ssd,discard,space_cache=v2,subvolid=333,subvol=/scon/containers/01KS4F7XKHAVX614ZKDHGS499Q

After:

riteshharihar@podman-dev:/Users/riteshharihar/Desktop/Src/nomad-driver-exec2$ nomad job run /tmp/mount-test.hcl
==> 2026-08-11T15:17:40+05:30: Monitoring evaluation "4a280b01"
    2026-08-11T15:17:40+05:30: Evaluation triggered by job "mount-test"
    2026-08-11T15:17:40+05:30: Allocation "3d37353c" created: node "7a43f8f2", group "group"
    2026-08-11T15:17:41+05:30: Allocation "3d37353c" status changed: "pending" -> "running" (Tasks are running)
    2026-08-11T15:17:41+05:30: Evaluation status changed: "pending" -> "complete"
==> 2026-08-11T15:17:41+05:30: Evaluation "4a280b01" finished with status "complete"

riteshharihar@podman-dev:/Users/riteshharihar/Desktop/Src/nomad-driver-exec2$ nomad alloc logs 3d37353c
811 808 0:38 /scon/containers/01KS4F7XKHAVX614ZKDHGS499Q/rootfs / rw,noatime master:35 - btrfs /dev/vdb1 rw,nodatasum,nodatacow,ssd,discard,space_cache=v2,subvolid=333,subvol=/scon/containers/01KS4F7XKHAVX614ZKDHGS499Q
  • If a change needs to be reverted, we will roll out an update to the code within 7 days.

Changes to Security Controls

Are there any changes to security controls (access controls, encryption, logging) in this pull request? If so, explain.

@ritesh-harihar ritesh-harihar self-assigned this Aug 12, 2026
@ritesh-harihar
ritesh-harihar marked this pull request as ready for review August 12, 2026 07:40
@ritesh-harihar
ritesh-harihar requested a review from a team as a code owner August 12, 2026 07:40
tgross
tgross previously approved these changes Aug 13, 2026

@tgross tgross 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! I don't think I realized we were implicitly creating a mount namespace with --mount-proc, although I suppose that was obvious in retrospect

@tgross
tgross merged commit 4732880 into main Aug 14, 2026
11 checks passed
@tgross
tgross deleted the fix-mount-namespace-propagation branch August 14, 2026 12:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Mount namespace propagation

2 participants