summaryrefslogtreecommitdiff
path: root/pkg/rootless/rootless_linux.c
diff options
context:
space:
mode:
authorGiuseppe Scrivano <gscrivan@redhat.com>2019-04-18 10:27:08 +0200
committerGiuseppe Scrivano <gscrivan@redhat.com>2019-04-18 14:32:46 +0200
commit0dfb61d8064feaae1ac83fcfb15514c30cb8ca28 (patch)
tree9c63eac5c5b8687d56d024a90dca9c26d6abe599 /pkg/rootless/rootless_linux.c
parentbf5ffdafb40f32fac891a8cd5fc64cfd5b77674f (diff)
downloadpodman-0dfb61d8064feaae1ac83fcfb15514c30cb8ca28.tar.gz
podman-0dfb61d8064feaae1ac83fcfb15514c30cb8ca28.tar.bz2
podman-0dfb61d8064feaae1ac83fcfb15514c30cb8ca28.zip
rootless: not close more FDs than needed
we were previously closing as many FDs as they were open when we first started Podman in the range (3-MAX-FD). This would cause issues if there were empty intervals, as these FDs are later on used by the Golang runtime. Store exactly what FDs were first open in a fd_set, so that we can close exactly the FDs that were open at startup. Closes: https://github.com/containers/libpod/issues/2964 Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
Diffstat (limited to 'pkg/rootless/rootless_linux.c')
-rw-r--r--pkg/rootless/rootless_linux.c55
1 files changed, 34 insertions, 21 deletions
diff --git a/pkg/rootless/rootless_linux.c b/pkg/rootless/rootless_linux.c
index 9cb79ed4d..1d32b1adb 100644
--- a/pkg/rootless/rootless_linux.c
+++ b/pkg/rootless/rootless_linux.c
@@ -16,11 +16,13 @@
#include <sys/types.h>
#include <sys/prctl.h>
#include <dirent.h>
+#include <sys/select.h>
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 n_files;
+static int open_files_max_fd;
+fd_set open_files_set;
static void __attribute__((constructor)) init()
{
@@ -32,11 +34,16 @@ static void __attribute__((constructor)) init()
{
struct dirent *ent;
+ FD_ZERO (&open_files_set);
for (ent = readdir (d); ent; ent = readdir (d))
{
int fd = atoi (ent->d_name);
- if (fd > n_files && fd != dirfd (d))
- n_files = fd;
+ if (fd != dirfd (d))
+ {
+ if (fd > open_files_max_fd)
+ open_files_max_fd = fd;
+ FD_SET (fd, &open_files_set);
+ }
}
closedir (d);
}
@@ -164,8 +171,11 @@ reexec_userns_join (int userns, int mountns)
{
/* We passed down these fds, close them. */
int f;
- for (f = 3; f < n_files; f++)
- close (f);
+ for (f = 3; f < open_files_max_fd; f++)
+ {
+ if (FD_ISSET (f, &open_files_set))
+ close (f);
+ }
return pid;
}
@@ -274,22 +284,25 @@ reexec_in_user_namespace (int ready)
check_proc_sys_userns_file (_max_user_namespaces);
check_proc_sys_userns_file (_unprivileged_user_namespaces);
}
- if (pid) {
- if (do_socket_activation) {
- long num_fds;
- num_fds = strtol(listen_fds, NULL, 10);
- if (num_fds != LONG_MIN && num_fds != LONG_MAX) {
- long i;
- for (i = 0; i < num_fds; i++) {
- close(3+i);
+ if (pid)
+ {
+ if (do_socket_activation)
+ {
+ long num_fds;
+ 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);
+ }
+ unsetenv ("LISTEN_PID");
+ unsetenv ("LISTEN_FDS");
+ unsetenv ("LISTEN_FDNAMES");
}
- }
- unsetenv("LISTEN_PID");
- unsetenv("LISTEN_FDS");
- unsetenv("LISTEN_FDNAMES");
+ return pid;
}
- return pid;
- }
argv = get_cmd_line_args (ppid);
if (argv == NULL)
@@ -300,8 +313,8 @@ reexec_in_user_namespace (int ready)
if (do_socket_activation) {
char s[32];
- sprintf(s, "%d", getpid());
- setenv("LISTEN_PID", s, true);
+ sprintf (s, "%d", getpid());
+ setenv ("LISTEN_PID", s, true);
}
setenv ("_CONTAINERS_USERNS_CONFIGURED", "init", 1);