Inside a child user namespace, an overlay layer that has a locked mount at or below it shows the files that mount hides, because clonePrivateMount clones each layer without its submounts (pkg/sentry/fsimpl/overlay/overlay.go). A layer from another mount namespace, passed as /proc/self/fd/N, shows what that namespace hides, and a detached tree cloned by open_tree(2) in a more privileged user namespace shows what its own submounts hide.
Linux refuses all three in clone_private_mount(), the first two with EINVAL and the third with EPERM.
Reproducer for the first case (as root under runsc do, it prints secret, where Linux refuses the mount)
mkdir -p /tmp/t && mount -t tmpfs t /tmp/t
mkdir -p /tmp/t/layer/hidden /tmp/t/other /tmp/t/merged
touch /tmp/t/layer/hidden/secret
mount -t tmpfs mask /tmp/t/layer/hidden
unshare -Urm sh -c 'mount -t overlay overlay -o lowerdir=/tmp/t/layer:/tmp/t/other /tmp/t/merged && ls /tmp/t/merged/hidden'
Proposed fix in #15531.
Inside a child user namespace, an overlay layer that has a locked mount at or below it shows the files that mount hides, because clonePrivateMount clones each layer without its submounts (pkg/sentry/fsimpl/overlay/overlay.go). A layer from another mount namespace, passed as /proc/self/fd/N, shows what that namespace hides, and a detached tree cloned by open_tree(2) in a more privileged user namespace shows what its own submounts hide.
Linux refuses all three in clone_private_mount(), the first two with EINVAL and the third with EPERM.
Reproducer for the first case (as root under runsc do, it prints secret, where Linux refuses the mount)
Proposed fix in #15531.