mirror of
https://github.com/containers/podman.git
synced 2026-10-26 11:49:36 -04:00
rootless: new function to join existing conmon processes
move the logic for joining existing namespaces down to the rootless package. In main_local we still retrieve the list of conmon pid files and use it from the rootless package. In addition, create a temporary user namespace for reading these files, as the unprivileged user might not have enough privileges for reading the conmon pid file, for example when running with a different uidmap and root in the container is different than the rootless user. Closes: https://github.com/containers/libpod/issues/3187 Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
This commit is contained in:
4 files changed
+207
-74
No files matched your search
@@ -346,6 +346,26 @@ syscall_clone (unsigned long flags, void *child_stack)
|
||||
#endif
|
||||
}
|
||||
|
||||
int
|
||||
reexec_in_user_namespace_wait (int pid, int options)
|
||||
{
|
||||
pid_t p;
|
||||
int status;
|
||||
|
||||
do
|
||||
p = waitpid (pid, &status, 0);
|
||||
while (p < 0 && errno == EINTR);
|
||||
|
||||
if (p < 0)
|
||||
return -1;
|
||||
|
||||
if (WIFEXITED (status))
|
||||
return WEXITSTATUS (status);
|
||||
if (WIFSIGNALED (status))
|
||||
return 128 + WTERMSIG (status);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int
|
||||
create_pause_process (const char *pause_pid_file_path, char **argv)
|
||||
{
|
||||
@@ -369,6 +389,8 @@ create_pause_process (const char *pause_pid_file_path, char **argv)
|
||||
while (r < 0 && errno == EINTR);
|
||||
close (p[0]);
|
||||
|
||||
reexec_in_user_namespace_wait(r, 0);
|
||||
|
||||
return r == 1 && b == '0' ? 0 : -1;
|
||||
}
|
||||
else
|
||||
@@ -573,8 +595,51 @@ check_proc_sys_userns_file (const char *path)
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
copy_file_to_fd (const char *file_to_read, int outfd)
|
||||
{
|
||||
char buf[512];
|
||||
int fd;
|
||||
|
||||
fd = open (file_to_read, O_RDONLY);
|
||||
if (fd < 0)
|
||||
return fd;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
ssize_t r, w, t = 0;
|
||||
|
||||
do
|
||||
r = read (fd, buf, sizeof buf);
|
||||
while (r < 0 && errno == EINTR);
|
||||
if (r < 0)
|
||||
{
|
||||
close (fd);
|
||||
return r;
|
||||
}
|
||||
|
||||
if (r == 0)
|
||||
break;
|
||||
|
||||
while (t < r)
|
||||
{
|
||||
do
|
||||
w = write (outfd, &buf[t], r - t);
|
||||
while (w < 0 && errno == EINTR);
|
||||
if (w < 0)
|
||||
{
|
||||
close (fd);
|
||||
return w;
|
||||
}
|
||||
t += w;
|
||||
}
|
||||
}
|
||||
close (fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
reexec_in_user_namespace (int ready, char *pause_pid_file_path)
|
||||
reexec_in_user_namespace (int ready, char *pause_pid_file_path, char *file_to_read, int outputfd)
|
||||
{
|
||||
int ret;
|
||||
pid_t pid;
|
||||
@@ -598,11 +663,11 @@ reexec_in_user_namespace (int ready, char *pause_pid_file_path)
|
||||
listen_pid = getenv("LISTEN_PID");
|
||||
listen_fds = getenv("LISTEN_FDS");
|
||||
|
||||
if (listen_pid != NULL && listen_fds != NULL) {
|
||||
if (strtol(listen_pid, NULL, 10) == getpid()) {
|
||||
do_socket_activation = true;
|
||||
if (listen_pid != NULL && listen_fds != NULL)
|
||||
{
|
||||
if (strtol(listen_pid, NULL, 10) == getpid())
|
||||
do_socket_activation = true;
|
||||
}
|
||||
}
|
||||
|
||||
sprintf (uid, "%d", geteuid ());
|
||||
sprintf (gid, "%d", getegid ());
|
||||
@@ -658,11 +723,12 @@ reexec_in_user_namespace (int ready, char *pause_pid_file_path)
|
||||
_exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (do_socket_activation) {
|
||||
char s[32];
|
||||
sprintf (s, "%d", getpid());
|
||||
setenv ("LISTEN_PID", s, true);
|
||||
}
|
||||
if (do_socket_activation)
|
||||
{
|
||||
char s[32];
|
||||
sprintf (s, "%d", getpid());
|
||||
setenv ("LISTEN_PID", s, true);
|
||||
}
|
||||
|
||||
setenv ("_CONTAINERS_USERNS_CONFIGURED", "init", 1);
|
||||
setenv ("_CONTAINERS_ROOTLESS_UID", uid, 1);
|
||||
@@ -721,27 +787,14 @@ reexec_in_user_namespace (int ready, char *pause_pid_file_path)
|
||||
_exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (file_to_read && file_to_read[0])
|
||||
{
|
||||
ret = copy_file_to_fd (file_to_read, outputfd);
|
||||
close (outputfd);
|
||||
_exit (ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
|
||||
}
|
||||
|
||||
execvp (argv[0], argv);
|
||||
|
||||
_exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
int
|
||||
reexec_in_user_namespace_wait (int pid)
|
||||
{
|
||||
pid_t p;
|
||||
int status;
|
||||
|
||||
do
|
||||
p = waitpid (pid, &status, 0);
|
||||
while (p < 0 && errno == EINTR);
|
||||
|
||||
if (p < 0)
|
||||
return -1;
|
||||
|
||||
if (WIFEXITED (status))
|
||||
return WEXITSTATUS (status);
|
||||
if (WIFSIGNALED (status))
|
||||
return 128 + WTERMSIG (status);
|
||||
return -1;
|
||||
}
|
||||
Reference in new issue
Block a user