mirror of https://github.com/containers/podman.git
Merge pull request #5323 from giuseppe/rootless-join-fixes
rootless: fix segfault when open fd >= FD_SETSIZE
This commit is contained in:
commit
72fdccda7a
|
@ -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 const char *_unprivileged_user_namespaces = "/proc/sys/kernel/unprivileged_userns_clone";
|
||||||
|
|
||||||
static int open_files_max_fd;
|
static int open_files_max_fd;
|
||||||
fd_set open_files_set;
|
static fd_set *open_files_set;
|
||||||
static uid_t rootless_uid_init;
|
static uid_t rootless_uid_init;
|
||||||
static gid_t rootless_gid_init;
|
static gid_t rootless_gid_init;
|
||||||
|
|
||||||
|
@ -240,17 +240,39 @@ static void __attribute__((constructor)) init()
|
||||||
if (d)
|
if (d)
|
||||||
{
|
{
|
||||||
struct dirent *ent;
|
struct dirent *ent;
|
||||||
|
size_t size = 0;
|
||||||
|
|
||||||
FD_ZERO (&open_files_set);
|
|
||||||
for (ent = readdir (d); ent; ent = readdir (d))
|
for (ent = readdir (d); ent; ent = readdir (d))
|
||||||
{
|
{
|
||||||
int fd = atoi (ent->d_name);
|
int fd;
|
||||||
if (fd != dirfd (d))
|
|
||||||
|
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)
|
int i;
|
||||||
open_files_max_fd = fd;
|
size_t new_size;
|
||||||
FD_SET (fd, &open_files_set);
|
|
||||||
|
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);
|
closedir (d);
|
||||||
}
|
}
|
||||||
|
@ -553,10 +575,8 @@ reexec_userns_join (int userns, int mountns, char *pause_pid_file_path)
|
||||||
/* We passed down these fds, close them. */
|
/* We passed down these fds, close them. */
|
||||||
int f;
|
int f;
|
||||||
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 (FD_ISSET (f, &open_files_set))
|
close (f);
|
||||||
close (f);
|
|
||||||
}
|
|
||||||
return pid;
|
return pid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -747,10 +767,11 @@ reexec_in_user_namespace (int ready, char *pause_pid_file_path, char *file_to_re
|
||||||
num_fds = strtol (listen_fds, NULL, 10);
|
num_fds = strtol (listen_fds, NULL, 10);
|
||||||
if (num_fds != LONG_MIN && num_fds != LONG_MAX)
|
if (num_fds != LONG_MIN && num_fds != LONG_MAX)
|
||||||
{
|
{
|
||||||
long i;
|
int f;
|
||||||
for (i = 3; i < num_fds + 3; i++)
|
|
||||||
if (FD_ISSET (i, &open_files_set))
|
for (f = 3; f < num_fds + 3; f++)
|
||||||
close (i);
|
if (open_files_set == NULL || FD_ISSET (f % FD_SETSIZE, &(open_files_set[f / FD_SETSIZE])))
|
||||||
|
close (f);
|
||||||
}
|
}
|
||||||
unsetenv ("LISTEN_PID");
|
unsetenv ("LISTEN_PID");
|
||||||
unsetenv ("LISTEN_FDS");
|
unsetenv ("LISTEN_FDS");
|
||||||
|
|
Loading…
Reference in New Issue