Merge pull request #6035 from giuseppe/move-rootless-open-before-fork

rootless: move ns open before fork
This commit is contained in:
OpenShift Merge Robot
2020-04-29 15:07:07 +02:00
committed by GitHub

View File

@ -535,32 +535,30 @@ create_pause_process (const char *pause_pid_file_path, char **argv)
} }
} }
static void static int
join_namespace_or_die (int pid_to_join, const char *ns_file) open_namespace (int pid_to_join, const char *ns_file)
{ {
char ns_path[PATH_MAX]; char ns_path[PATH_MAX];
int ret; int ret;
int fd;
ret = snprintf (ns_path, PATH_MAX, "/proc/%d/ns/%s", pid_to_join, ns_file); ret = snprintf (ns_path, PATH_MAX, "/proc/%d/ns/%s", pid_to_join, ns_file);
if (ret == PATH_MAX) if (ret == PATH_MAX)
{ {
fprintf (stderr, "internal error: namespace path too long\n"); fprintf (stderr, "internal error: namespace path too long\n");
_exit (EXIT_FAILURE); return -1;
} }
fd = open (ns_path, O_CLOEXEC | O_RDONLY); return open (ns_path, O_CLOEXEC | O_RDONLY);
if (fd < 0) }
static void
join_namespace_or_die (const char *name, int ns_fd)
{
if (setns (ns_fd, 0) < 0)
{ {
fprintf (stderr, "cannot open: %s\n", ns_path); fprintf (stderr, "cannot set %s namespace\n", name);
_exit (EXIT_FAILURE); _exit (EXIT_FAILURE);
} }
if (setns (fd, 0) < 0)
{
fprintf (stderr, "cannot set namespace to %s: %s\n", ns_path, strerror (errno));
_exit (EXIT_FAILURE);
}
close (fd);
} }
int int
@ -570,6 +568,8 @@ reexec_userns_join (int pid_to_join, char *pause_pid_file_path)
char gid[16]; char gid[16];
char **argv; char **argv;
int pid; int pid;
int mnt_ns = -1;
int user_ns = -1;
char *cwd = getcwd (NULL, 0); char *cwd = getcwd (NULL, 0);
sigset_t sigset, oldsigset; sigset_t sigset, oldsigset;
@ -589,14 +589,28 @@ reexec_userns_join (int pid_to_join, char *pause_pid_file_path)
_exit (EXIT_FAILURE); _exit (EXIT_FAILURE);
} }
user_ns = open_namespace (pid_to_join, "user");
if (user_ns < 0)
return user_ns;
mnt_ns = open_namespace (pid_to_join, "mnt");
if (mnt_ns < 0)
{
close (user_ns);
return mnt_ns;
}
pid = fork (); pid = fork ();
if (pid < 0) if (pid < 0)
fprintf (stderr, "cannot fork: %s\n", strerror (errno)); fprintf (stderr, "cannot fork: %s\n", strerror (errno));
if (pid) if (pid)
{ {
/* We passed down these fds, close them. */
int f; int f;
/* We passed down these fds, close them. */
close (user_ns);
close (mnt_ns);
for (f = 3; f < open_files_max_fd; f++) for (f = 3; f < open_files_max_fd; f++)
if (open_files_set == NULL || FD_ISSET (f % FD_SETSIZE, &(open_files_set[f / FD_SETSIZE]))) if (open_files_set == NULL || FD_ISSET (f % FD_SETSIZE, &(open_files_set[f / FD_SETSIZE])))
close (f); close (f);
@ -634,8 +648,10 @@ reexec_userns_join (int pid_to_join, char *pause_pid_file_path)
_exit (EXIT_FAILURE); _exit (EXIT_FAILURE);
} }
join_namespace_or_die (pid_to_join, "user"); join_namespace_or_die ("user", user_ns);
join_namespace_or_die (pid_to_join, "mnt"); join_namespace_or_die ("mnt", mnt_ns);
close (user_ns);
close (mnt_ns);
if (syscall_setresgid (0, 0, 0) < 0) if (syscall_setresgid (0, 0, 0) < 0)
{ {