From e266387a86dd6677a3d9628871d463fd69302e8f Mon Sep 17 00:00:00 2001 From: Sargun Dhillon Date: Sat, 22 Apr 2017 16:21:23 -0700 Subject: [PATCH] Add stdio attribute --- src/tini.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/tini.c b/src/tini.c index 867c8e3..d0a02e5 100644 --- a/src/tini.c +++ b/src/tini.c @@ -19,6 +19,8 @@ #include #include #include +#include +#include #include "tiniConfig.h" #include "tiniLicense.h" @@ -29,6 +31,7 @@ #define REDIRECT_STDOUT "TITUS_REDIRECT_STDOUT" #define TITUS_CB_PATH "TITUS_UNIX_CB_PATH" +const char stdioattr[] = "user.stdio"; #if TINI_MINIMAL #define PRINT_FATAL(...) fprintf(stderr, __VA_ARGS__); fprintf(stderr, "\n"); @@ -148,6 +151,9 @@ int spawn(const signal_configuration_t* const sigconf_ptr, char* const argv[], i char *redir_path; pid_t pid; + // So, we might leak file descriptors here. For example, if we successfully wire up the stdout, + // but the stderr fd fails. Fortunately, this should make the init in the container bail entirely. + // This will have the side-effect of closing all of our file descriptors. redir_path = getenv(REDIRECT_STDOUT); if (redir_path) { new_stdout_fd = open(redir_path, O_WRONLY | O_CREAT | O_APPEND, S_IRUGO | S_IWUGO); @@ -155,6 +161,10 @@ int spawn(const signal_configuration_t* const sigconf_ptr, char* const argv[], i PRINT_FATAL("Failed to open stdout redirect path: %s", strerror(errno)); return 1; } + if (fsetxattr(new_stdout_fd, stdioattr, NULL, 0, 0) == -1) { + PRINT_FATAL("Unable to set stdio attribute on stdout redirect: %s", strerror(errno)); + return 1; + } } redir_path = getenv(REDIRECT_STDERR); @@ -164,6 +174,10 @@ int spawn(const signal_configuration_t* const sigconf_ptr, char* const argv[], i PRINT_FATAL("Failed to open stderr redirect path: %s", strerror(errno)); return 1; } + if (fsetxattr(new_stderr_fd, stdioattr, NULL, 0, 0) == -1) { + PRINT_FATAL("Unable to set stdio attribute on stderr redirect: %s", strerror(errno)); + return 1; + } } // TODO: check if tini was a foreground process to begin with (it's not OK to "steal" the foreground!") @@ -218,6 +232,11 @@ int spawn(const signal_configuration_t* const sigconf_ptr, char* const argv[], i return status; } else { // Parent + if (new_stdout_fd != 1) + close(new_stdout_fd); + if (new_stderr_fd != 2) + close(new_stderr_fd); + PRINT_INFO("Spawned child process '%s' with pid '%i'", argv[0], pid); *child_pid_ptr = pid; return 0;