From 10983c363e4ccd7c82dc01607dbcb611150acfdc Mon Sep 17 00:00:00 2001 From: Giuseppe Scrivano Date: Fri, 31 May 2019 10:34:35 +0200 Subject: rootless: make sure the buffer is NUL terminated after we read from the pause PID file, NUL terminate the buffer to avoid reading garbage from the stack. Signed-off-by: Giuseppe Scrivano --- pkg/rootless/rootless_linux.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'pkg/rootless') diff --git a/pkg/rootless/rootless_linux.c b/pkg/rootless/rootless_linux.c index 2356882e7..8608930dd 100644 --- a/pkg/rootless/rootless_linux.c +++ b/pkg/rootless/rootless_linux.c @@ -276,6 +276,8 @@ static void __attribute__((constructor)) init() free (cwd); return; } + buf[r] = '\0'; + pid = strtol (buf, NULL, 10); if (pid == LONG_MAX) { -- cgit v1.2.3-54-g00ecf From b88dc3a41e54837b232cf9a5dad930e9f4749eb9 Mon Sep 17 00:00:00 2001 From: Giuseppe Scrivano Date: Fri, 31 May 2019 10:35:40 +0200 Subject: rootless: fix return type Signed-off-by: Giuseppe Scrivano --- pkg/rootless/rootless_linux.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'pkg/rootless') diff --git a/pkg/rootless/rootless_linux.c b/pkg/rootless/rootless_linux.c index 8608930dd..ec286a31f 100644 --- a/pkg/rootless/rootless_linux.c +++ b/pkg/rootless/rootless_linux.c @@ -180,7 +180,7 @@ can_use_shortcut () argv = get_cmd_line_args (0); if (argv == NULL) - return NULL; + return false; for (argc = 0; argv[argc]; argc++) { -- cgit v1.2.3-54-g00ecf From 27e47cb6d02598ecfc0338162c12175ac0ca5e62 Mon Sep 17 00:00:00 2001 From: Giuseppe Scrivano Date: Fri, 31 May 2019 10:42:26 +0200 Subject: rootless: use TEMP_FAILURE_RETRY macro avoid checking for EINTR for every syscall that could block. Signed-off-by: Giuseppe Scrivano --- pkg/rootless/rootless_linux.c | 58 ++++++++++++++++++------------------------- 1 file changed, 24 insertions(+), 34 deletions(-) (limited to 'pkg/rootless') diff --git a/pkg/rootless/rootless_linux.c b/pkg/rootless/rootless_linux.c index ec286a31f..a2425c83e 100644 --- a/pkg/rootless/rootless_linux.c +++ b/pkg/rootless/rootless_linux.c @@ -34,6 +34,15 @@ int renameat2 (int olddirfd, const char *oldpath, int newdirfd, const char *newp } #endif +#ifndef TEMP_FAILURE_RETRY +#define TEMP_FAILURE_RETRY(expression) \ + (__extension__ \ + ({ long int __result; \ + do __result = (long int) (expression); \ + while (__result == -1L && errno == EINTR); \ + __result; })) +#endif + static const char *_max_user_namespaces = "/proc/sys/user/max_user_namespaces"; static const char *_unprivileged_user_namespaces = "/proc/sys/kernel/unprivileged_userns_clone"; @@ -113,9 +122,7 @@ get_cmd_line_args (pid_t pid) return NULL; for (;;) { - do - ret = read (fd, buffer + used, allocated - used); - while (ret < 0 && errno == EINTR); + ret = TEMP_FAILURE_RETRY (read (fd, buffer + used, allocated - used)); if (ret < 0) { free (buffer); @@ -269,7 +276,7 @@ static void __attribute__((constructor)) init() return; } - r = read (fd, buf, sizeof (buf)); + r = TEMP_FAILURE_RETRY (read (fd, buf, sizeof (buf))); close (fd); if (r < 0) { @@ -354,10 +361,7 @@ reexec_in_user_namespace_wait (int pid, int options) pid_t p; int status; - do - p = waitpid (pid, &status, 0); - while (p < 0 && errno == EINTR); - + p = TEMP_FAILURE_RETRY (waitpid (pid, &status, 0)); if (p < 0) return -1; @@ -386,12 +390,10 @@ create_pause_process (const char *pause_pid_file_path, char **argv) close (p[1]); /* Block until we write the pid file. */ - do - r = read (p[0], &b, 1); - while (r < 0 && errno == EINTR); + r = TEMP_FAILURE_RETRY (read (p[0], &b, 1)); close (p[0]); - reexec_in_user_namespace_wait(r, 0); + reexec_in_user_namespace_wait (r, 0); return r == 1 && b == '0' ? 0 : -1; } @@ -428,9 +430,7 @@ create_pause_process (const char *pause_pid_file_path, char **argv) _exit (EXIT_FAILURE); } - do - r = write (fd, pid_str, strlen (pid_str)); - while (r < 0 && errno == EINTR); + r = TEMP_FAILURE_RETRY (write (fd, pid_str, strlen (pid_str))); if (r < 0) { kill (pid, SIGKILL); @@ -447,9 +447,7 @@ create_pause_process (const char *pause_pid_file_path, char **argv) _exit (EXIT_FAILURE); } - do - r = write (p[1], "0", 1); - while (r < 0 && errno == EINTR); + r = TEMP_FAILURE_RETRY (write (p[1], "0", 1)); close (p[1]); _exit (EXIT_SUCCESS); @@ -611,9 +609,7 @@ copy_file_to_fd (const char *file_to_read, int outfd) { ssize_t r, w, t = 0; - do - r = read (fd, buf, sizeof buf); - while (r < 0 && errno == EINTR); + r = TEMP_FAILURE_RETRY (read (fd, buf, sizeof buf)); if (r < 0) { close (fd); @@ -625,9 +621,7 @@ copy_file_to_fd (const char *file_to_read, int outfd) while (t < r) { - do - w = write (outfd, &buf[t], r - t); - while (w < 0 && errno == EINTR); + w = TEMP_FAILURE_RETRY (write (outfd, &buf[t], r - t)); if (w < 0) { close (fd); @@ -736,9 +730,7 @@ reexec_in_user_namespace (int ready, char *pause_pid_file_path, char *file_to_re setenv ("_CONTAINERS_ROOTLESS_UID", uid, 1); setenv ("_CONTAINERS_ROOTLESS_GID", gid, 1); - do - ret = read (ready, &b, 1) < 0; - while (ret < 0 && errno == EINTR); + ret = TEMP_FAILURE_RETRY (read (ready, &b, 1)); if (ret < 0) { fprintf (stderr, "cannot read from sync pipe: %s\n", strerror (errno)); @@ -750,21 +742,21 @@ reexec_in_user_namespace (int ready, char *pause_pid_file_path, char *file_to_re if (syscall_setresgid (0, 0, 0) < 0) { fprintf (stderr, "cannot setresgid: %s\n", strerror (errno)); - write (ready, "1", 1); + TEMP_FAILURE_RETRY (write (ready, "1", 1)); _exit (EXIT_FAILURE); } if (syscall_setresuid (0, 0, 0) < 0) { fprintf (stderr, "cannot setresuid: %s\n", strerror (errno)); - write (ready, "1", 1); + TEMP_FAILURE_RETRY (write (ready, "1", 1)); _exit (EXIT_FAILURE); } if (chdir (cwd) < 0) { fprintf (stderr, "cannot chdir: %s\n", strerror (errno)); - write (ready, "1", 1); + TEMP_FAILURE_RETRY (write (ready, "1", 1)); _exit (EXIT_FAILURE); } free (cwd); @@ -773,14 +765,12 @@ reexec_in_user_namespace (int ready, char *pause_pid_file_path, char *file_to_re { if (create_pause_process (pause_pid_file_path, argv) < 0) { - write (ready, "2", 1); + TEMP_FAILURE_RETRY (write (ready, "2", 1)); _exit (EXIT_FAILURE); } } - do - ret = write (ready, "0", 1) < 0; - while (ret < 0 && errno == EINTR); + ret = TEMP_FAILURE_RETRY (write (ready, "0", 1)); close (ready); if (sigprocmask (SIG_SETMASK, &oldsigset, NULL) < 0) -- cgit v1.2.3-54-g00ecf