3

I observe the following:

As unprivileged user in shell No 1:

user@box:~$ sysctl kernel.unprivileged_userns_clone
kernel.unprivileged_userns_clone = 1
user@box:~$ unshare --mount --user
nobody@box:~$ echo $$
18655

And as root in shell No 2:

root@box:~# mkdir -p /tmp/myns
root@box:~# touch /tmp/myns/{user,mnt}
root@box:~# mount --bind /proc/18655/ns/user /tmp/myns/user 
root@box:~# mount --bind /proc/18655/ns/mnt /tmp/myns/mnt
mount: /tmp/myns/mnt: wrong fs type, bad option, bad superblock on /proc/18655/ns/mnt, missing codepage or helper program, or other error.

The error comes as a surprise: I cannot bind-mount a mount namespace to a file, but I can bind-mount a user-namespace to a file? Why's that, and how can I make this mount-namespace available to an unprivileged user?

Why I want this: For testing a program, I want to overlay ~user with a temporary file system, initially sharing the original contents. It may be set up by root along the lines of

tmp='/tmp/GAtcNNeSfM8b'
mkdir -p "$tmp"
mount -t tmpfs -o size=100m tmpfs "$tmp"
mkdir -p "${tmp}/"{upper,work,lower}
mount --bind -o ro /home/user "${tmp}/lower"

unshare -m
mount -t overlay -o"lowerdir=${tmp}/lower,upperdir=${tmp}/upper,workdir=${tmp}/work" overlay /home/user
touch /tmp/namespace
mount --bind /proc/self/ns/mnt /tmp/namespace

but the last line fails.

The intention is that an unprivileged user may nsenter --mount=/tmp/namespace, and see the same system as before, except that changes to /home/user are not persistent. Actually, I do not even want to unshare the user namespace.

I am conciously trying to avoid the overhead of LXC, Docker or even VirtualBox. I think that should be possible with Linux standard tool.

Update: I'm running an up-to-date ArchLinux, with

$ uname -r
5.0.10-arch1-1-ARCH
  • Haven't you already get a shell in the newly-created mount namespace? Just write to /proc/self/uid_map – 炸鱼薯条德里克 May 5 at 14:23
  • And why all these complex setup, why can't you just unshare to get a shell with separate mount and user namespace? Then you can build the overlayfs directly under /home/user. – 炸鱼薯条德里克 May 5 at 14:35
  • AFAIK I cannot overlay /home/user unless being really privileged (not just fake-privileged as in unshare -r). This might require a kernel patch (lacking sources, but I think I've read it is part of Ubuntu's kernels, and controversial due to security concerns — but I'm on ArchLinux anyways). But if it works on your box, I'd really appreciate to see a working examlpe. – stefan May 5 at 14:47
  • I did exactly the same as you (including having kernel.unprivileged_userns_clone=1 which means ubuntu,debian or archlinux, I'm on Debian). Here it's working. 2 possibilities: you have some restriction (selinux & co, already within a container etc.) or it depends on kernel. I'm currently using (debian patched) kernel 5.0.9. Here mounting the mnt nsfs doesn't give an error, and it's really mounted (stat -f -c %T /tmp/myns/mnt gives nsfs) – A.B May 5 at 15:26
  • 1
    Also see there: manpages.debian.org/stretch/manpages/mount_namespaces.7.en.html . In case there's an interaction with shared filesystems, you should do on the initlal (host) , before anything else, mount --make-private / ; mount --make-private /proc , same for /tmp , and see if that makes any difference – A.B May 5 at 15:55
0

Given that it only affects the mount namespace, I am extremely suspicious that this is due to one of the loop prevention checks for mount namespaces. I do not think it is the exact same case as the link talks about, because unshare --mount defaults to setting mount propagation to private, i.e. disabling it.

However, to protect against certain race conditions, I think full correctness might require that you mount your mount namespaces inside a mount which has private mount propagation. I also think it might be cleanest (easiest to debug) if you use unbindable. (I think unbindable already includes all the effects of private).

I.e. mount your mount namespaces inside a directory prepared using:

mount --bind /var/local/lib/myns/ /var/local/lib/myns/
mount --make-unbindable /var/local/lib/myns/

In general I think this is the safest approach, to avoid ever triggering such a problem.

My race condition is hypothetical. I would not expect you to be hitting it most of the time. So I do not know what your actual problem is.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.