summaryrefslogtreecommitdiff
path: root/pkg/rootless
diff options
context:
space:
mode:
authorGiuseppe Scrivano <gscrivan@redhat.com>2018-12-19 18:07:03 +0100
committerGiuseppe Scrivano <gscrivan@redhat.com>2018-12-21 09:46:05 +0100
commitf2e96b0934a6d1b3aac8a1d931e790c6226dd4e0 (patch)
treedb7815fc4f17916f1e0f5beed9bc144c5b7cdb35 /pkg/rootless
parentf65eafa6ba2fec491185ccf29a515c9a96b9852a (diff)
downloadpodman-f2e96b0934a6d1b3aac8a1d931e790c6226dd4e0.tar.gz
podman-f2e96b0934a6d1b3aac8a1d931e790c6226dd4e0.tar.bz2
podman-f2e96b0934a6d1b3aac8a1d931e790c6226dd4e0.zip
rootless: add function to join user and mount namespace
Add the possibility to join directly the user and mount namespace without looking up the parent of the user namespace. We need this in order to be able the conmon process, as the mount namespace is kept alive only there. Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
Diffstat (limited to 'pkg/rootless')
-rw-r--r--pkg/rootless/rootless_linux.c9
-rw-r--r--pkg/rootless/rootless_linux.go39
2 files changed, 44 insertions, 4 deletions
diff --git a/pkg/rootless/rootless_linux.c b/pkg/rootless/rootless_linux.c
index 9eb16c1a5..1d28ff68d 100644
--- a/pkg/rootless/rootless_linux.c
+++ b/pkg/rootless/rootless_linux.c
@@ -99,7 +99,7 @@ get_cmd_line_args (pid_t pid)
}
int
-reexec_userns_join (int userns)
+reexec_userns_join (int userns, int mountns)
{
pid_t ppid = getpid ();
char uid[16];
@@ -131,6 +131,13 @@ reexec_userns_join (int userns)
}
close (userns);
+ if (mountns >= 0 && setns (mountns, 0) < 0)
+ {
+ fprintf (stderr, "cannot setns: %s\n", strerror (errno));
+ _exit (EXIT_FAILURE);
+ }
+ close (userns);
+
if (syscall_setresgid (0, 0, 0) < 0)
{
fprintf (stderr, "cannot setresgid: %s\n", strerror (errno));
diff --git a/pkg/rootless/rootless_linux.go b/pkg/rootless/rootless_linux.go
index 07002da3f..9a192c0fa 100644
--- a/pkg/rootless/rootless_linux.go
+++ b/pkg/rootless/rootless_linux.go
@@ -25,7 +25,7 @@ import (
/*
extern int reexec_in_user_namespace(int ready);
extern int reexec_in_user_namespace_wait(int pid);
-extern int reexec_userns_join(int userns);
+extern int reexec_userns_join(int userns, int mountns);
*/
import "C"
@@ -112,7 +112,40 @@ func JoinNS(pid uint) (bool, int, error) {
}
defer userNS.Close()
- pidC := C.reexec_userns_join(C.int(userNS.Fd()))
+ pidC := C.reexec_userns_join(C.int(userNS.Fd()), -1)
+ if int(pidC) < 0 {
+ return false, -1, errors.Errorf("cannot re-exec process")
+ }
+
+ ret := C.reexec_in_user_namespace_wait(pidC)
+ if ret < 0 {
+ return false, -1, errors.New("error waiting for the re-exec process")
+ }
+
+ return true, int(ret), nil
+}
+
+// JoinDirectUserAndMountNS re-exec podman in a new userNS and join the user and mount
+// namespace of the specified PID without looking up its parent. Useful to join directly
+// the conmon process.
+func JoinDirectUserAndMountNS(pid uint) (bool, int, error) {
+ if os.Geteuid() == 0 || os.Getenv("_LIBPOD_USERNS_CONFIGURED") != "" {
+ return false, -1, nil
+ }
+
+ userNS, err := os.Open(fmt.Sprintf("/proc/%d/ns/user", pid))
+ if err != nil {
+ return false, -1, err
+ }
+ defer userNS.Close()
+
+ mountNS, err := os.Open(fmt.Sprintf("/proc/%d/ns/mnt", pid))
+ if err != nil {
+ return false, -1, err
+ }
+ defer userNS.Close()
+
+ pidC := C.reexec_userns_join(C.int(userNS.Fd()), C.int(mountNS.Fd()))
if int(pidC) < 0 {
return false, -1, errors.Errorf("cannot re-exec process")
}
@@ -138,7 +171,7 @@ func JoinNSPath(path string) (bool, int, error) {
}
defer userNS.Close()
- pidC := C.reexec_userns_join(C.int(userNS.Fd()))
+ pidC := C.reexec_userns_join(C.int(userNS.Fd()), -1)
if int(pidC) < 0 {
return false, -1, errors.Errorf("cannot re-exec process")
}