diff options
author | pendulm <lonependulm@gmail.com> | 2021-04-02 19:33:05 +0800 |
---|---|---|
committer | pendulm <lonependulm@gmail.com> | 2021-04-05 17:43:11 +0800 |
commit | 11917a1a6b74a9abf18ae5ed307007bf9f316a8f (patch) | |
tree | 7e77e3f8899ac43b2a7b02cac8f372c7ff32aade /pkg/rootless | |
parent | 23ee8b1df1f70aaad4fc4bc9c0c6b17f7aae5c8a (diff) | |
download | podman-11917a1a6b74a9abf18ae5ed307007bf9f316a8f.tar.gz podman-11917a1a6b74a9abf18ae5ed307007bf9f316a8f.tar.bz2 podman-11917a1a6b74a9abf18ae5ed307007bf9f316a8f.zip |
Move socket activation check into init() and set global condition.
So rootless setup could use this condition in parent and child, child
podman should adjust LISTEN_PID to its self PID.
Add system test for systemd socket activation
Signed-off-by: pendulm <lonependulm@gmail.com>
Diffstat (limited to 'pkg/rootless')
-rw-r--r-- | pkg/rootless/rootless_linux.c | 58 |
1 files changed, 46 insertions, 12 deletions
diff --git a/pkg/rootless/rootless_linux.c b/pkg/rootless/rootless_linux.c index 7a2bf0377..918b9a7e6 100644 --- a/pkg/rootless/rootless_linux.c +++ b/pkg/rootless/rootless_linux.c @@ -61,6 +61,10 @@ static int open_files_max_fd; static fd_set *open_files_set; static uid_t rootless_uid_init; static gid_t rootless_gid_init; +static bool do_socket_activation = false; +static char *saved_systemd_listen_fds; +static char *saved_systemd_listen_pid; +static char *saved_systemd_listen_fdnames; static int syscall_setresuid (uid_t ruid, uid_t euid, uid_t suid) @@ -242,6 +246,10 @@ static void __attribute__((constructor)) init() { const char *xdg_runtime_dir; const char *pause; + const char *listen_pid; + const char *listen_fds; + const char *listen_fdnames; + DIR *d; pause = getenv ("_PODMAN_PAUSE"); @@ -293,6 +301,26 @@ static void __attribute__((constructor)) init() closedir (d); } + listen_pid = getenv("LISTEN_PID"); + listen_fds = getenv("LISTEN_FDS"); + listen_fdnames = getenv("LISTEN_FDNAMES"); + + if (listen_pid != NULL && listen_fds != NULL && strtol(listen_pid, NULL, 10) == getpid()) + { + // save systemd socket environment for rootless child + do_socket_activation = true; + saved_systemd_listen_pid = strdup(listen_pid); + saved_systemd_listen_fds = strdup(listen_fds); + saved_systemd_listen_fdnames = strdup(listen_fdnames); + if (saved_systemd_listen_pid == NULL + || saved_systemd_listen_fds == NULL + || saved_systemd_listen_fdnames == NULL) + { + fprintf (stderr, "save socket listen environments error: %s\n", strerror (errno)); + _exit (EXIT_FAILURE); + } + } + /* Shortcut. If we are able to join the pause pid file, do it now so we don't need to re-exec. */ xdg_runtime_dir = getenv ("XDG_RUNTIME_DIR"); @@ -635,6 +663,12 @@ reexec_userns_join (int pid_to_join, char *pause_pid_file_path) for (f = 3; f <= open_files_max_fd; f++) if (is_fd_inherited (f)) close (f); + if (do_socket_activation) + { + unsetenv ("LISTEN_PID"); + unsetenv ("LISTEN_FDS"); + unsetenv ("LISTEN_FDNAMES"); + } return pid; } @@ -660,6 +694,15 @@ reexec_userns_join (int pid_to_join, char *pause_pid_file_path) _exit (EXIT_FAILURE); } + if (do_socket_activation) + { + char s[32]; + sprintf (s, "%d", getpid()); + setenv ("LISTEN_PID", s, true); + setenv ("LISTEN_FDS", saved_systemd_listen_fds, true); + setenv ("LISTEN_FDNAMES", saved_systemd_listen_fdnames, true); + } + setenv ("_CONTAINERS_USERNS_CONFIGURED", "init", 1); setenv ("_CONTAINERS_ROOTLESS_UID", uid, 1); setenv ("_CONTAINERS_ROOTLESS_GID", gid, 1); @@ -777,9 +820,6 @@ reexec_in_user_namespace (int ready, char *pause_pid_file_path, char *file_to_re char **argv; char uid[16]; char gid[16]; - char *listen_fds = NULL; - char *listen_pid = NULL; - bool do_socket_activation = false; char *cwd = getcwd (NULL, 0); sigset_t sigset, oldsigset; @@ -789,14 +829,6 @@ reexec_in_user_namespace (int ready, char *pause_pid_file_path, char *file_to_re _exit (EXIT_FAILURE); } - 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; - } sprintf (uid, "%d", geteuid ()); sprintf (gid, "%d", getegid ()); @@ -814,7 +846,7 @@ reexec_in_user_namespace (int ready, char *pause_pid_file_path, char *file_to_re { long num_fds; - num_fds = strtol (listen_fds, NULL, 10); + num_fds = strtol (saved_systemd_listen_fds, NULL, 10); if (num_fds != LONG_MIN && num_fds != LONG_MAX) { int f; @@ -863,6 +895,8 @@ reexec_in_user_namespace (int ready, char *pause_pid_file_path, char *file_to_re char s[32]; sprintf (s, "%d", getpid()); setenv ("LISTEN_PID", s, true); + setenv ("LISTEN_FDS", saved_systemd_listen_fds, true); + setenv ("LISTEN_FDNAMES", saved_systemd_listen_fdnames, true); } setenv ("_CONTAINERS_USERNS_CONFIGURED", "init", 1); |