summaryrefslogtreecommitdiff
path: root/pkg
diff options
context:
space:
mode:
authorGiuseppe Scrivano <gscrivan@redhat.com>2018-07-11 09:49:30 +0200
committerGiuseppe Scrivano <gscrivan@redhat.com>2018-07-13 16:41:11 +0200
commit62e48e5b71abe3002361bbf018961f8031fba03e (patch)
treec7befcc9ef6a7c00cc9ee36f171c62ce231f1ea8 /pkg
parent0066374fc3f69bbfd9ed08986115049d9a39b1f8 (diff)
downloadpodman-62e48e5b71abe3002361bbf018961f8031fba03e.tar.gz
podman-62e48e5b71abe3002361bbf018961f8031fba03e.tar.bz2
podman-62e48e5b71abe3002361bbf018961f8031fba03e.zip
rootless: correctly propagate the exit status from the container
Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
Diffstat (limited to 'pkg')
-rw-r--r--pkg/rootless/rootless_linux.c6
-rw-r--r--pkg/rootless/rootless_linux.go31
-rw-r--r--pkg/rootless/rootless_unsupported.go4
3 files changed, 22 insertions, 19 deletions
diff --git a/pkg/rootless/rootless_linux.c b/pkg/rootless/rootless_linux.c
index f2684f75f..d08c6c875 100644
--- a/pkg/rootless/rootless_linux.c
+++ b/pkg/rootless/rootless_linux.c
@@ -105,16 +105,16 @@ reexec_in_user_namespace(int ready)
ret = read (ready, &b, 1) < 0;
while (ret < 0 && errno == EINTR);
if (ret < 0)
- _exit (1);
+ _exit (EXIT_FAILURE);
close (ready);
if (setresgid (0, 0, 0) < 0 ||
setresuid (0, 0, 0) < 0)
- _exit (1);
+ _exit (EXIT_FAILURE);
execvp (argv[0], argv);
- _exit (1);
+ _exit (EXIT_FAILURE);
}
int
diff --git a/pkg/rootless/rootless_linux.go b/pkg/rootless/rootless_linux.go
index 55a55bbc6..6089ad73a 100644
--- a/pkg/rootless/rootless_linux.go
+++ b/pkg/rootless/rootless_linux.go
@@ -67,14 +67,16 @@ func tryMappingTool(tool string, pid int, hostID int, mappings []idtools.IDMap)
return cmd.Run()
}
-// BecomeRootInUserNS re-exec podman in a new userNS
-func BecomeRootInUserNS() (bool, error) {
-
+// BecomeRootInUserNS re-exec podman in a new userNS. It returns whether podman was re-executed
+// into a new user namespace and the return code from the re-executed podman process.
+// If podman was re-executed the caller needs to propagate the error code returned by the child
+// process.
+func BecomeRootInUserNS() (bool, int, error) {
if os.Getuid() == 0 || os.Getenv("_LIBPOD_USERNS_CONFIGURED") != "" {
if os.Getenv("_LIBPOD_USERNS_CONFIGURED") == "init" {
- return false, runInUser()
+ return false, 0, runInUser()
}
- return false, nil
+ return false, 0, nil
}
runtime.LockOSThread()
@@ -82,7 +84,7 @@ func BecomeRootInUserNS() (bool, error) {
r, w, err := os.Pipe()
if err != nil {
- return false, err
+ return false, -1, err
}
defer r.Close()
defer w.Close()
@@ -90,13 +92,13 @@ func BecomeRootInUserNS() (bool, error) {
pidC := C.reexec_in_user_namespace(C.int(r.Fd()))
pid := int(pidC)
if pid < 0 {
- return false, errors.Errorf("cannot re-exec process")
+ return false, -1, errors.Errorf("cannot re-exec process")
}
setgroups := fmt.Sprintf("/proc/%d/setgroups", pid)
err = ioutil.WriteFile(setgroups, []byte("deny\n"), 0666)
if err != nil {
- return false, errors.Wrapf(err, "cannot write setgroups file")
+ return false, -1, errors.Wrapf(err, "cannot write setgroups file")
}
var uids, gids []idtools.IDMap
@@ -115,7 +117,7 @@ func BecomeRootInUserNS() (bool, error) {
uidMap := fmt.Sprintf("/proc/%d/uid_map", pid)
err = ioutil.WriteFile(uidMap, []byte(fmt.Sprintf("%d %d 1\n", 0, os.Getuid())), 0666)
if err != nil {
- return false, errors.Wrapf(err, "cannot write uid_map")
+ return false, -1, errors.Wrapf(err, "cannot write uid_map")
}
}
@@ -127,13 +129,13 @@ func BecomeRootInUserNS() (bool, error) {
gidMap := fmt.Sprintf("/proc/%d/gid_map", pid)
err = ioutil.WriteFile(gidMap, []byte(fmt.Sprintf("%d %d 1\n", 0, os.Getgid())), 0666)
if err != nil {
- return false, errors.Wrapf(err, "cannot write gid_map")
+ return false, -1, errors.Wrapf(err, "cannot write gid_map")
}
}
_, err = w.Write([]byte("1"))
if err != nil {
- return false, errors.Wrapf(err, "write to sync pipe")
+ return false, -1, errors.Wrapf(err, "write to sync pipe")
}
c := make(chan os.Signal, 1)
@@ -150,9 +152,10 @@ func BecomeRootInUserNS() (bool, error) {
}
}()
- if C.reexec_in_user_namespace_wait(pidC) < 0 {
- return false, errors.Wrapf(err, "error waiting for the re-exec process")
+ ret := C.reexec_in_user_namespace_wait(pidC)
+ if ret < 0 {
+ return false, -1, errors.Wrapf(err, "error waiting for the re-exec process")
}
- return true, nil
+ return true, int(ret), nil
}
diff --git a/pkg/rootless/rootless_unsupported.go b/pkg/rootless/rootless_unsupported.go
index a6efa73f5..b1f075045 100644
--- a/pkg/rootless/rootless_unsupported.go
+++ b/pkg/rootless/rootless_unsupported.go
@@ -13,8 +13,8 @@ func IsRootless() bool {
// BecomeRootInUserNS is a stub function that always returns false and an
// error on unsupported OS's
-func BecomeRootInUserNS() (bool, error) {
- return false, errors.New("this function is not supported on this os")
+func BecomeRootInUserNS() (bool, int, error) {
+ return false, -1, errors.New("this function is not supported on this os")
}
// GetRootlessUID returns the UID of the user in the parent userNS