unshare
unshare copied to clipboard
Configure uid/gid maps from child and not parent
Hello, I've been trying to implement a tool based on this library which shares some functionality with the unshare utility from util-linux and noticed a problem where mapping UIDs and GIDs requires root permission with this library but not with the unshare utility.
In this PR I've changed the UID/GID mapping logic to mimick the unshare utility, I tried to do it in a way which affects the rest of the library the least but it may break some invariants I'm just not aware of. Do you think this a viable approach? Thank you
Hm.. I've always thought that you have either have root permissions or use newuidmap
/newgidmap
(which are setuid binaries) to adjust mappings. So I have to investigate whether something changed in the recent kernels or I'm missing something else. If this actually works in all desired scenarios, surely we can apply PR.
But I'm not even sure how does it work logically. Do you say that unprivileged user can adjust their uid/gid mappings freely? Do you create a new user namespace in this call, or spawning a process in the same one?
This might help, the manpage for unshare
the section about --setgroups
says:
--setgroups allow|deny
Allow or deny the
setgroups(2)
system call in a user namespace.To be able to call
setgroups(2)
, the calling process must at least haveCAP_SETGID
. But since Linux 3.19 a further restriction applies: the kernel gives permission to callsetgroups(2)
only after the GID map (/proc/pid/gid_map) has been set. The GID map is writable by root whensetgroups(2)
is enabled (i.e., allow, the default), and the GID map becomes writable by unprivileged processes whensetgroups(2)
is permanently disabled (with deny).
One problem I've come across is that using this I was unable remove the list of auxiliary groups. I've tried creating a trivial chroot environment with nothing else but static busybox at $CHROOT/bin/id
and then running strace unshare -r -R $CHROOT /bin/id
, what I've implemented here is just mimicking it's behaviour. The id
command prints uid=0 gid=0 groups=65534,65534,65534,65534,65534,65534,65534,65534,65534,65534,65534,65534,65534,65534,65534,65534,65534,65534,65534,65534,65534,65534,65534,0,65534,65534
so it masks the auxiliary groups to some nonsense but matches the number on the host system. Using the groups
method in combination with this setgroups
returns invalid argument error, which makes sense. It'd be great if some reordering of the operations could fix that but I haven't managed that yet.
masks the auxiliary groups to some nonsense
to be clear (as I already know this behavoir from the nix sandbox), it masks the auxiliary groups to nogroup
with the kernel-hardcoded gid 65534
.
The simple way to prevent it is by making sure that the user which opens the sandbox isn't in any groups.