-
Notifications
You must be signed in to change notification settings - Fork 18k
syscall: Unshare with CLONE_NEWUSER fails #22283
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
My understanding is that the One thing that you can safely do is use the os/exec package to start a new program (or to re-exec the same program), setting `SysProcAttr.Unshareflags to the unshare flags you want to use for the new program. I'm going to close this since I don't think there is any possible resolution. Please comment if you disagree. |
I see your point, but in my particular use case I need to bind mount a directory in the file system root as a non-root user and afaik there's no way to do so using "just" Excerpt from the program: if err = syscall.Unshare(unshareFlags); err != nil {
log.Fatal(errors.Wrap(err, "Failed to unshare()"))
}
f, err := os.Open(hostRoot)
if err != nil {
log.Fatal(errors.Wrapf(err, "Failed to open %s", hostRoot))
}
names, err := f.Readdirnames(-1)
if err != nil {
log.Fatal(errors.Wrapf(err, "Failed to read directory names at %s", hostRoot))
}
m := make(map[string]string, len(names)+1)
for _, name := range names {
if name == "nix" {
continue
}
m[filepath.Join(hostRoot, name)] = filepath.Join(rootPath, name)
}
m[nixPath] = filepath.Join(rootPath, "nix")
for hostPath, guestPath := range m {
fi, err := os.Stat(hostPath)
if err != nil {
log.Fatal(errors.Wrapf(err, "Failed to stat() %s", hostPath))
}
mode := fi.Mode() &^ syscall.S_IFMT
if err = os.Mkdir(guestPath, mode); err != nil {
log.Fatal(errors.Wrapf(err, "Failed to create new directory at %s with mode %s", guestPath, mode))
}
if err := syscall.Mount(hostPath, guestPath, "none", syscall.MS_BIND|syscall.MS_REC, ""); err != nil {
log.Fatal(errors.Wrapf(err, "Failed to bind mount %s to %s", hostRoot, guestPath))
}
} I need to setup a Any suggestions how I could do that, or is it not possible to do so with Go? |
Is that the same as #12125? |
#12125 is a proposal for a feature, but this is a bugreport. The essential idea is the same though. Regardless, solution from #12125 is pretty much exactly what I tried to do and it fails with |
The C program is a single-threaded program. The Go program is a multi-threaded program (all Go programs are multi-threaded programs). You can't reliably use |
Okay, so it's not possible to do bind mounts as a non-root user in Go, right? |
@rvolosatovs I'm doing something similar; I have a simple Go program https://github.com/myitcv/g/blob/master/cmd/unsharemounts/main.go (could just as easily be C code as @ianlancetaylor points out) that runs The code is old, probably could be done a better way... but it works for my requirements. The background to my requirement is http://blog.myitcv.io/2014/03/18/using-process-namespaces-to-implement-variant-symlinks.html |
@rvolosatovs I do not know enough about this to usefully comment. The point of #12125, which is still open, is to figure out some useful way to do bind mounts in Go. Any comment on that topic should go onto that issue, not this one. Thanks. |
@rvolosatovs - I don't understand why execing yourself wouldn't work in this case. It seems simple enough. Just exec yourself with a special parameter (or even environment variable) set to tell the new version of yourself not to do it again. Heck, you could even test whether or not a file previously owned by root is now owned by nobody or any number of other things. |
What version of Go are you using (
go version
)?go version go1.9.1 linux/amd64
Does this issue reproduce with the latest release?
yes
What operating system and processor architecture are you using (
go env
)?What did you do?
main.c
main.go
:main_cgo.go
:compile and run each of those with:
What did you expect to see?
What did you see instead?
The errno
22
returned bymain.go
implementation corresponds tosyscall.EINVAL
, "invalid argument"The text was updated successfully, but these errors were encountered: