summaryrefslogtreecommitdiff
path: root/pkg
diff options
context:
space:
mode:
authorGiuseppe Scrivano <gscrivan@redhat.com>2018-10-11 12:38:10 +0200
committerGiuseppe Scrivano <gscrivan@redhat.com>2018-10-11 17:09:18 +0200
commit48f6f9254dc04350c15a136dd94487400f34dfb5 (patch)
tree54a82d664e48135738820ad6abab69069081e707 /pkg
parent23c9816ba9ff1af3538dcb725d86fc565df53a30 (diff)
downloadpodman-48f6f9254dc04350c15a136dd94487400f34dfb5.tar.gz
podman-48f6f9254dc04350c15a136dd94487400f34dfb5.tar.bz2
podman-48f6f9254dc04350c15a136dd94487400f34dfb5.zip
rootless: fix an hang on older versions of setresuid/setresgid
the issue is caused by the Go Runtime that messes up with the process signals, overriding SIGSETXID and SIGCANCEL which are used internally by glibc. They are used to inform all the threads to update their stored uid/gid information. This causes a hang on the set*id glibc wrappers since the handler installed by glibc is never invoked. Since we are running with only one thread, we don't really need to update other threads or even the current thread as we are not using getuid/getgid before the execvp. Closes: https://github.com/containers/libpod/issues/1625 Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
Diffstat (limited to 'pkg')
-rw-r--r--pkg/rootless/rootless_linux.c22
1 files changed, 18 insertions, 4 deletions
diff --git a/pkg/rootless/rootless_linux.c b/pkg/rootless/rootless_linux.c
index d78d95453..034a410bd 100644
--- a/pkg/rootless/rootless_linux.c
+++ b/pkg/rootless/rootless_linux.c
@@ -13,6 +13,18 @@
#include <sys/wait.h>
static int
+syscall_setresuid (uid_t ruid, uid_t euid, uid_t suid)
+{
+ return (int) syscall (__NR_setresuid, ruid, euid, suid);
+}
+
+static int
+syscall_setresgid (gid_t rgid, gid_t egid, gid_t sgid)
+{
+ return (int) syscall (__NR_setresgid, rgid, egid, sgid);
+}
+
+static int
syscall_clone (unsigned long flags, void *child_stack)
{
return (int) syscall (__NR_clone, flags, child_stack);
@@ -107,8 +119,8 @@ reexec_userns_join (int userns)
_exit (EXIT_FAILURE);
close (userns);
- if (setresgid (0, 0, 0) < 0 ||
- setresuid (0, 0, 0) < 0)
+ if (syscall_setresgid (0, 0, 0) < 0 ||
+ syscall_setresuid (0, 0, 0) < 0)
_exit (EXIT_FAILURE);
execvp (argv[0], argv);
@@ -146,8 +158,10 @@ reexec_in_user_namespace (int ready)
_exit (EXIT_FAILURE);
close (ready);
- if (setresgid (0, 0, 0) < 0 ||
- setresuid (0, 0, 0) < 0)
+ if (syscall_setresgid (0, 0, 0) < 0)
+ _exit (EXIT_FAILURE);
+
+ if (syscall_setresuid (0, 0, 0) < 0)
_exit (EXIT_FAILURE);
execvp (argv[0], argv);