-
Notifications
You must be signed in to change notification settings - Fork 18k
proposal: os/exec: better support for user namespaces #50098
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
This is supposed to be done by using the |
Behavior is the same no matter if I use Software like |
What would we have to change to make this work? Thanks. |
I believe ready to use implementation is here: https://github.com/containers/storage/tree/main/pkg/unshare/ |
BTW: the best approach IMO would be to implement
Whenever someone shares this idea golang team answers that the correct way of doing this is to use
Imagine this situation: |
It's infeasible to implement Thanks for pointing to the package. There is a lot there, and I don't know what matters. It would help this proposal a great deal if you or somebody could write down exactly what would need to be added to |
I'm not a C expert but linked library works this way:
// #cgo CFLAGS: -Wall -Wextra
// extern void _containers_unshare(void);
// void __attribute__((constructor)) init(void) {
// _containers_unshare();
// }
import "C"
And this is the flow:
In this setup flags for Entire process is sooooo complicated... |
We are not going to permit calling ordinary Go code between I don't know what the For this proposal to move forward we're going to need more precise details as to exactly what needs to be implemented in the syscall package. I'm going to put this on hold for now. |
https://man7.org/linux/man-pages/man1/newuidmap.1.html
I think I provided all the details on how the flow should look like. But once again:
go is frequently used to develop containerization engines so it would be nice to implement this once for all. |
Why is it necessary to call an external binary to make this work? Why can't we do this entirely with system calls? |
Unprivileged user may create only a single mapping: |
Beforehand, unprivileged user could only create id mappings like this: <ID in user namespace> -> current uid/gid on the host Using the new{uid,gid}map executables, this limitation can be bypassed, because those executables have setuid and setgid sticky bits or capabilities set. Fixes golang#50098 Signed-off-by: Höhl, Lukas <lukas.hoehl@accso.de>
Beforehand, unprivileged user could only create id mappings like this: <ID in user namespace> -> current uid/gid on the host Using the new{uid,gid}map executables, this limitation can be bypassed, because those executables have setuid and setgid sticky bits or capabilities set. Fixes golang#50098 Signed-off-by: Höhl, Lukas <lukas.hoehl@accso.de>
Hey everyone, I tried to come up with an implementation for this issue: I tried to follow the logic of util-linux's implementation of unshare, although I ran into an issue: Lines 200 to 216 in 29b9a32
I think if that problem is sorted out, the implementation can go on further. Can someone with a bit more experience on the stdlib help out? |
I've been running into A little debugging reveals it comes from when go tries to write to the child process's So to best logically deduce what's happening, I looked at the source code for the Conclusively, in a non-root environment, doing anything advanced with UidMappings will always fail with EPERM until capabilities are set prior to In other words, we need to implement the go-equivalent of this mess:
|
1.5 year later, having more experience in running programs in namespaces using go I think there is no good solution for this, as the limitation comes from the kernel. There are 4 possible ways to deal with it:
|
My current understanding of this issue, which may be mistaken, is that we don't need to change any user visible API in the standard library. This issue is about the fact that the Does that sound right? If that's right, this doesn't need to be a proposal. (As an aside, I don't see why |
And this is the problem. Because, at the moment, we have no way to inject the logic into |
If we know precisely what has to be done, we can change the syscall package to do it. We don't have to support having the program inject arbitrary code. Even if there were a reasonable way to do that, it's not what we want. |
I agree that adding code calling |
I am actually suggesting that perhaps we could change the syscall package to invoke |
I have this scenario:
unshare
syscall allows me to maproot
user only.podman
is able to map subids too by callingnewuidmap
andnewgidmap
(it is implemented here: https://github.com/containers/storage/tree/main/pkg/unshare/unshare_linux.go)exec.Cmd
plus some C code to callunshare
in the middle of the process, after setting full mapping setsyscall.Unshare(syscall.CLONE_NEWUSER)
returnsinvalid argument
error even if called from goroutine pinned to thread.It would be nice to have more "goish" way to do it, like this:
The text was updated successfully, but these errors were encountered: