diff options
-rw-r--r-- | libsandbox/libsandbox.c | 4 | ||||
-rw-r--r-- | libsbutil/get_sandbox_log.c | 5 | ||||
-rw-r--r-- | libsbutil/sb_efuncs.c | 66 | ||||
-rw-r--r-- | libsbutil/sbutil.h | 3 | ||||
-rw-r--r-- | src/environ.c | 5 | ||||
-rw-r--r-- | src/sandbox.c | 13 | ||||
-rw-r--r-- | src/sandbox.h | 1 | ||||
-rw-r--r-- | tests/sb_printf_tst.c | 1 |
8 files changed, 47 insertions, 51 deletions
diff --git a/libsandbox/libsandbox.c b/libsandbox/libsandbox.c index eaa5c7d..0ec5fe1 100644 --- a/libsandbox/libsandbox.c +++ b/libsandbox/libsandbox.c @@ -47,6 +47,7 @@ typedef struct { static char *cached_env_vars[MAX_DYN_PREFIXES]; static char log_path[SB_PATH_MAX]; static char debug_log_path[SB_PATH_MAX]; +static char message_path[SB_PATH_MAX]; bool sandbox_on = true; static bool sb_init = false; int (*sbio_open)(const char *, int, mode_t) = sb_unwrapped_open; @@ -58,6 +59,7 @@ static void clean_env_entries(char ***, int *); static void init_context(sbcontext_t *); static void init_env_entries(char ***, int *, const char *, const char *, int); +const char *sbio_message_path; const char sbio_fallback_path[] = "/dev/tty"; /* resolve_dirfd_path - get the path relative to a dirfd @@ -940,6 +942,8 @@ bool before_syscall(int dirfd, int sb_nr, const char *func, const char *file, in get_sandbox_log(log_path, NULL); get_sandbox_debug_log(debug_log_path, NULL); + get_sandbox_message_path(message_path); + sbio_message_path = message_path; init_context(&sbcontext); sb_init = true; diff --git a/libsbutil/get_sandbox_log.c b/libsbutil/get_sandbox_log.c index 947566a..a79b399 100644 --- a/libsbutil/get_sandbox_log.c +++ b/libsbutil/get_sandbox_log.c @@ -58,3 +58,8 @@ void get_sandbox_debug_log(char *path, const char *tmpdir) { _get_sb_log(path, tmpdir, ENV_SANDBOX_DEBUG_LOG, DEBUG_LOG_FILE_PREFIX); } + +void get_sandbox_message_path(char *path) +{ + _get_sb_log(path, NULL, ENV_SANDBOX_MESSAGE_PATH, DEBUG_LOG_FILE_PREFIX); +} diff --git a/libsbutil/sb_efuncs.c b/libsbutil/sb_efuncs.c index 484e8a0..80064c6 100644 --- a/libsbutil/sb_efuncs.c +++ b/libsbutil/sb_efuncs.c @@ -26,65 +26,33 @@ static void sbio_init(void) } } -static bool try_portage_helpers = true; - /* - * First try to use the helper programs from portage so that it can sanely - * log things itself, and so the output doesn't get consumed by something - * else #278761. If that fails, fall back to writing to /dev/tty. While - * this might annoy some people, using stderr will break tests that try to - * validate output #261957. + * First try to write to the known good message log location (which is + * normally tied to the initial sandbox's stderr). If that fails, fall + * back to writing to /dev/tty. While this might annoy some people, + * using stderr will break tests that try to validate output. #261957 + * Other related bugs on the topic: #278761 */ static void sb_vefunc(const char *prog, const char *color, const char *format, va_list args) { - char shellcode[128]; + int fd; FILE *fp; - struct sigaction sa, old_sa; - bool is_pipe = false; - va_list retry_args; - - if (try_portage_helpers) { - /* If popen() fails, then writes to it will trigger SIGPIPE */ - sa.sa_flags = SA_RESTART; - sa.sa_handler = SIG_IGN; - sigaction(SIGCHLD, &sa, &old_sa); - - sprintf(shellcode, "xargs %s 2>/dev/null", prog); - fp = sbio_popen(shellcode, "we"); - is_pipe = true; - va_copy(retry_args, args); - } else - fp = NULL; - - if (!fp) { - do_tty: - is_pipe = false; - int fd = sbio_open(sbio_fallback_path, O_WRONLY|O_CLOEXEC, 0); - if (fd >= 0) - fp = fdopen(fd, "ae"); - if (!fp) - fp = stderr; - } + + if (likely(sbio_message_path)) + fd = sbio_open(sbio_message_path, O_WRONLY|O_APPEND|O_CLOEXEC, 0); + else + fd = -1; + if (fd == -1) + sbio_open(sbio_fallback_path, O_WRONLY|O_CLOEXEC, 0); + fp = fd == -1 ? NULL : fdopen(fd, "ae"); + if (!fp) + fp = stderr; sb_fprintf(fp, " %s*%s ", color, COLOR_NORMAL); sb_vfprintf(fp, format, args); - if (is_pipe) { - int status = pclose(fp); - if (WEXITSTATUS(status)) { - args = retry_args; - goto do_tty; - } - } else if (fp != stderr) + if (fp != stderr) fclose(fp); - - if (try_portage_helpers) { - sigaction(SIGCHLD, &old_sa, NULL); - va_end(retry_args); - if (!is_pipe) - /* If we failed once, we'll fail again */ - try_portage_helpers = false; - } } void sb_einfo(const char *format, ...) diff --git a/libsbutil/sbutil.h b/libsbutil/sbutil.h index 90de815..993d7ad 100644 --- a/libsbutil/sbutil.h +++ b/libsbutil/sbutil.h @@ -46,6 +46,7 @@ #define ENV_SANDBOX_BASHRC "SANDBOX_BASHRC" #define ENV_SANDBOX_LOG "SANDBOX_LOG" #define ENV_SANDBOX_DEBUG_LOG "SANDBOX_DEBUG_LOG" +#define ENV_SANDBOX_MESSAGE_PATH "SANDBOX_MESSAGE_PATH" #define ENV_SANDBOX_WORKDIR "SANDBOX_WORKDIR" #define ENV_SANDBOX_DENY "SANDBOX_DENY" @@ -70,6 +71,7 @@ void get_sandbox_lib(char *path); void get_sandbox_rc(char *path); void get_sandbox_log(char *path, const char *tmpdir); void get_sandbox_debug_log(char *path, const char *tmpdir); +void get_sandbox_message_path(char *path); int get_tmp_dir(char *path); bool is_env_on(const char *); bool is_env_off(const char *); @@ -86,6 +88,7 @@ const char *sb_get_cmdline(pid_t pid); /* libsandbox need to use a wrapper for open */ attribute_hidden extern int (*sbio_open)(const char *, int, mode_t); attribute_hidden extern FILE *(*sbio_popen)(const char *, const char *); +extern const char *sbio_message_path; extern const char sbio_fallback_path[]; /* Convenience functions to reliably open, read and write to a file */ int sb_open(const char *path, int flags, mode_t mode); diff --git a/src/environ.c b/src/environ.c index 727f10b..5f22829 100644 --- a/src/environ.c +++ b/src/environ.c @@ -254,6 +254,7 @@ char **setup_environ(struct sandbox_info_t *sandbox_info) unsetenv(ENV_SANDBOX_BASHRC); unsetenv(ENV_SANDBOX_LOG); unsetenv(ENV_SANDBOX_DEBUG_LOG); + unsetenv(ENV_SANDBOX_MESSAGE_PATH); unsetenv(ENV_SANDBOX_WORKDIR); unsetenv(ENV_SANDBOX_ACTIVE); unsetenv(ENV_BASH_ENV); @@ -285,8 +286,8 @@ char **setup_environ(struct sandbox_info_t *sandbox_info) sb_setenv(&new_environ, ENV_SANDBOX_LIB, sandbox_info->sandbox_lib); sb_setenv(&new_environ, ENV_SANDBOX_BASHRC, sandbox_info->sandbox_rc); sb_setenv(&new_environ, ENV_SANDBOX_LOG, sandbox_info->sandbox_log); - sb_setenv(&new_environ, ENV_SANDBOX_DEBUG_LOG, - sandbox_info->sandbox_debug_log); + sb_setenv(&new_environ, ENV_SANDBOX_DEBUG_LOG, sandbox_info->sandbox_debug_log); + sb_setenv(&new_environ, ENV_SANDBOX_MESSAGE_PATH, sandbox_info->sandbox_message_path); /* Just set the these if not already set so that is_env_on() work */ if (!getenv(ENV_SANDBOX_VERBOSE)) sb_setenv(&new_environ, ENV_SANDBOX_VERBOSE, "1"); diff --git a/src/sandbox.c b/src/sandbox.c index aa957f6..51f2d95 100644 --- a/src/sandbox.c +++ b/src/sandbox.c @@ -26,6 +26,7 @@ volatile static pid_t child_pid = 0; static const char sandbox_banner[] = "============================= Gentoo path sandbox =============================="; static const char sandbox_footer[] = "--------------------------------------------------------------------------------"; +const char *sbio_message_path; const char sbio_fallback_path[] = "/dev/stderr"; static int setup_sandbox(struct sandbox_info_t *sandbox_info, bool interactive) @@ -80,6 +81,18 @@ static int setup_sandbox(struct sandbox_info_t *sandbox_info, bool interactive) } } + /* Generate sandbox message path -- this process's stderr */ + char path[SB_PATH_MAX]; + sprintf(path, "%s/2", sb_get_fd_dir()); + if (realpath(path, sandbox_info->sandbox_message_path) == NULL) { + sb_pwarn("could not read stderr path: %s", path); + if (realpath(sbio_fallback_path, sandbox_info->sandbox_message_path)) { + sb_pwarn("could not read stderr path: %s", sbio_fallback_path); + /* fuck it */ + strcpy(sandbox_info->sandbox_message_path, sbio_fallback_path); + } + } + return 0; } diff --git a/src/sandbox.h b/src/sandbox.h index cc67753..c0c4315 100644 --- a/src/sandbox.h +++ b/src/sandbox.h @@ -16,6 +16,7 @@ struct sandbox_info_t { char sandbox_log[SB_PATH_MAX]; char sandbox_debug_log[SB_PATH_MAX]; + char sandbox_message_path[SB_PATH_MAX]; char sandbox_lib[SB_PATH_MAX]; char sandbox_rc[SB_PATH_MAX]; char work_dir[SB_PATH_MAX]; diff --git a/tests/sb_printf_tst.c b/tests/sb_printf_tst.c index 867f782..1fe7566 100644 --- a/tests/sb_printf_tst.c +++ b/tests/sb_printf_tst.c @@ -11,6 +11,7 @@ int (*sbio_open)(const char *, int, mode_t) = (void *)open; FILE *(*sbio_popen)(const char *, const char *) = popen; const char sbio_fallback_path[] = "/dev/stderr"; +const char *sbio_message_path = sbio_fallback_path; int main(int argc, char *argv[]) { |