aboutsummaryrefslogtreecommitdiff
path: root/pkg/rootless
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/rootless')
-rw-r--r--pkg/rootless/rootless_linux.c71
-rw-r--r--pkg/rootless/rootless_linux.go7
2 files changed, 50 insertions, 28 deletions
diff --git a/pkg/rootless/rootless_linux.c b/pkg/rootless/rootless_linux.c
index 041a161dc..6643bfbbf 100644
--- a/pkg/rootless/rootless_linux.c
+++ b/pkg/rootless/rootless_linux.c
@@ -58,7 +58,7 @@ static const char *_max_user_namespaces = "/proc/sys/user/max_user_namespaces";
static const char *_unprivileged_user_namespaces = "/proc/sys/kernel/unprivileged_userns_clone";
static int open_files_max_fd;
-fd_set open_files_set;
+static fd_set *open_files_set;
static uid_t rootless_uid_init;
static gid_t rootless_gid_init;
@@ -108,10 +108,9 @@ do_pause ()
}
static char **
-get_cmd_line_args (pid_t pid)
+get_cmd_line_args ()
{
int fd;
- char path[PATH_MAX];
char *buffer;
size_t allocated;
size_t used = 0;
@@ -119,11 +118,7 @@ get_cmd_line_args (pid_t pid)
int i, argc = 0;
char **argv;
- if (pid)
- sprintf (path, "/proc/%d/cmdline", pid);
- else
- strcpy (path, "/proc/self/cmdline");
- fd = open (path, O_RDONLY);
+ fd = open ("/proc/self/cmdline", O_RDONLY);
if (fd < 0)
return NULL;
@@ -196,10 +191,13 @@ can_use_shortcut ()
return false;
#endif
- argv = get_cmd_line_args (0);
+ argv = get_cmd_line_args ();
if (argv == NULL)
return false;
+ if (strstr (argv[0], "podman") == NULL)
+ return false;
+
for (argc = 0; argv[argc]; argc++)
{
if (argc == 0 || argv[argc][0] == '-')
@@ -237,17 +235,39 @@ static void __attribute__((constructor)) init()
if (d)
{
struct dirent *ent;
+ size_t size = 0;
- FD_ZERO (&open_files_set);
for (ent = readdir (d); ent; ent = readdir (d))
{
- int fd = atoi (ent->d_name);
- if (fd != dirfd (d))
+ int fd;
+
+ if (ent->d_name[0] == '.')
+ continue;
+
+ fd = atoi (ent->d_name);
+ if (fd == dirfd (d))
+ continue;
+
+ if (fd >= size * FD_SETSIZE)
{
- if (fd > open_files_max_fd)
- open_files_max_fd = fd;
- FD_SET (fd, &open_files_set);
+ int i;
+ size_t new_size;
+
+ new_size = (fd / FD_SETSIZE) + 1;
+ open_files_set = realloc (open_files_set, new_size * sizeof (fd_set));
+ if (open_files_set == NULL)
+ _exit (EXIT_FAILURE);
+
+ for (i = size; i < new_size; i++)
+ FD_ZERO (&(open_files_set[i]));
+
+ size = new_size;
}
+
+ if (fd > open_files_max_fd)
+ open_files_max_fd = fd;
+
+ FD_SET (fd % FD_SETSIZE, &(open_files_set[fd / FD_SETSIZE]));
}
closedir (d);
}
@@ -517,7 +537,6 @@ create_pause_process (const char *pause_pid_file_path, char **argv)
int
reexec_userns_join (int userns, int mountns, char *pause_pid_file_path)
{
- pid_t ppid = getpid ();
char uid[16];
char gid[16];
char **argv;
@@ -534,7 +553,7 @@ reexec_userns_join (int userns, int mountns, char *pause_pid_file_path)
sprintf (uid, "%d", geteuid ());
sprintf (gid, "%d", getegid ());
- argv = get_cmd_line_args (ppid);
+ argv = get_cmd_line_args ();
if (argv == NULL)
{
fprintf (stderr, "cannot read argv: %s\n", strerror (errno));
@@ -550,10 +569,8 @@ reexec_userns_join (int userns, int mountns, char *pause_pid_file_path)
/* We passed down these fds, close them. */
int f;
for (f = 3; f < open_files_max_fd; f++)
- {
- if (FD_ISSET (f, &open_files_set))
- close (f);
- }
+ if (open_files_set == NULL || FD_ISSET (f % FD_SETSIZE, &(open_files_set[f / FD_SETSIZE])))
+ close (f);
return pid;
}
@@ -701,7 +718,6 @@ reexec_in_user_namespace (int ready, char *pause_pid_file_path, char *file_to_re
int ret;
pid_t pid;
char b;
- pid_t ppid = getpid ();
char **argv;
char uid[16];
char gid[16];
@@ -744,10 +760,11 @@ reexec_in_user_namespace (int ready, char *pause_pid_file_path, char *file_to_re
num_fds = strtol (listen_fds, NULL, 10);
if (num_fds != LONG_MIN && num_fds != LONG_MAX)
{
- long i;
- for (i = 3; i < num_fds + 3; i++)
- if (FD_ISSET (i, &open_files_set))
- close (i);
+ int f;
+
+ for (f = 3; f < num_fds + 3; f++)
+ if (open_files_set == NULL || FD_ISSET (f % FD_SETSIZE, &(open_files_set[f / FD_SETSIZE])))
+ close (f);
}
unsetenv ("LISTEN_PID");
unsetenv ("LISTEN_FDS");
@@ -777,7 +794,7 @@ reexec_in_user_namespace (int ready, char *pause_pid_file_path, char *file_to_re
_exit (EXIT_FAILURE);
}
- argv = get_cmd_line_args (ppid);
+ argv = get_cmd_line_args ();
if (argv == NULL)
{
fprintf (stderr, "cannot read argv: %s\n", strerror (errno));
diff --git a/pkg/rootless/rootless_linux.go b/pkg/rootless/rootless_linux.go
index 182a39f6b..5ddfab7ad 100644
--- a/pkg/rootless/rootless_linux.go
+++ b/pkg/rootless/rootless_linux.go
@@ -452,6 +452,7 @@ func TryJoinFromFilePaths(pausePidPath string, needNewNamespace bool, paths []st
var lastErr error
var pausePid int
+ foundProcess := false
for _, path := range paths {
if !needNewNamespace {
@@ -502,12 +503,16 @@ func TryJoinFromFilePaths(pausePidPath string, needNewNamespace bool, paths []st
}
pausePid, err = strconv.Atoi(string(b[:n]))
- if err == nil {
+ if err == nil && unix.Kill(pausePid, 0) == nil {
+ foundProcess = true
lastErr = nil
break
}
}
}
+ if !foundProcess && pausePidPath != "" {
+ return BecomeRootInUserNS(pausePidPath)
+ }
if lastErr != nil {
return false, 0, lastErr
}