From: Ralph Ronnquist <ralph@selfhost.au>
To: Christian Albrecht Goeschel Ndjomouo <cgoesc2@wgu.edu>
Cc: Chris Hofstaedtler <zeha@debian.org>,
"util-linux@vger.kernel.org" <util-linux@vger.kernel.org>,
"1134639@bugs.debian.org" <1134639@bugs.debian.org>
Subject: Re: Bug#1134639: nsenter -t 1 -m escapes mount and pid namespaces
Date: Thu, 4 Jun 2026 20:15:35 +1000 [thread overview]
Message-ID: <aiFQRzblklN7Iv2I@smulan> (raw)
In-Reply-To: <SJ0P220MB0541F8F40FD5C0E972BBD715E9102@SJ0P220MB0541.NAMP220.PROD.OUTLOOK.COM>
On Thu, Jun 04, 2026 at 04:03:44AM +0000, Christian Albrecht Goeschel Ndjomouo wrote:
> > First: {unshare -m -p -f chroot FS} will change root into that
> > filesystem with unshared mount and pid namespaces.
> >
>
> This will successfully changes the root directory path of the child process,
> however, the newly created mount namespace's root mount will still
> point to the host's root filesystem, which is the actual root cause of the
> escape (it'll become clearer below).
>
> > Next: {mount -t proc proc /proc} will mount the procfs for that pid
> > namespace. We see with {ls -l /proc/1/ns/mnt} the identity of the
> > unshared mount namespace, which is different from the identity before
> > chroot.
> >
>
> As the mount(8) command has copied the execution context of the container
> process, it will see it's root filesystem as `FS`, so the 'procfs' will be mounted
> on FS/proc, rightfully so. The ls command is also running with that context,
> and will show the container's mount namespace ID.
>
> > But: {nsenter -t 1 -m -- ls -l /proc/1/ns/mnt} shows the identity of
> > the host mount namespace -- the outer namespace.
> >
> > Thus {nsenter -t 1 -m} "escapes" from the unshared namespace to the
> > containing namespace. And for example: {nsenter -t 1 -m /bin/sh}
> > starts a shell in the outer mount and pid namespace(s)!
> >
>
> The reason why you escaped is that when nsenter(1) calls setns(fd, CLONE_NEWNS)
> , the kernel will set the root filesystem for the calling process to the absolute root of
> the target mount namespace. And, whatever binary it forks will now be decoupled
> from the container's chroot and point back to the host's root filesystem. This is why
> you are also able to view the host's mount table or resolve paths relative to the host
> fs while inside the container, for example, when you executed a shell with nsenter(8).
>
> If you wish to completely cut ties with the VFS structure of the host, you can make use
> of pivot_root(8). It let's you set the global root mount of the mount namespace and truly
> isolates the mount namespace.
>
> You can do something like this:
>
> $ unshare --mount --pid --fork
> $ mount --bind FS FS/
> $ cd FS/
> $ mkdir -p old_root/
> $ /sbin/pivot_root . old_root/
> $ cd /
> $ mount -t proc proc /proc
> $ umount -l old_root/
> $ rmdir old_root
>
> You should then be able to see the exact same mnt namespace ID.
>
> $ ls -l /proc/1/ns/mnt
> [...] /proc/1/ns/mnt -> 'mnt:[4026533461]'
> $ nsenter --mount --target 1 -- ls -l /proc/1/ns/mnt
> [...] /proc/1/ns/mnt -> 'mnt:[4026533461]'
>
>
> Maybe Karel has more to say about this.
>
> Anyways I hope this cleared up at least some of the confusion.
Quite subtile, but I can confirm also in my actual setting (which is a
simple and plain "overlay-boot" example).
I will need a couple of sleeps before I fully grasp that "absolute
root" notion. However the recepie you outline does bring the desired
effect of eliminating that namespace eascape for me.
Thanks.
Ralph
>
>
> Christian Goeschel Ndjomouo
>
>
>
prev parent reply other threads:[~2026-06-04 10:25 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <aejkWHDXmpCX7Gh7@smyga.hemma>
2026-06-03 18:17 ` Bug#1134639: nsenter -t 1 -m escapes mount and pid namespaces Chris Hofstaedtler
2026-06-04 4:03 ` Christian Albrecht Goeschel Ndjomouo
2026-06-04 10:15 ` Ralph Ronnquist [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=aiFQRzblklN7Iv2I@smulan \
--to=ralph@selfhost.au \
--cc=1134639@bugs.debian.org \
--cc=cgoesc2@wgu.edu \
--cc=util-linux@vger.kernel.org \
--cc=zeha@debian.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox