aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libsandbox/libsandbox.c4
-rw-r--r--libsbutil/get_sandbox_log.c5
-rw-r--r--libsbutil/sb_efuncs.c66
-rw-r--r--libsbutil/sbutil.h3
-rw-r--r--src/environ.c5
-rw-r--r--src/sandbox.c13
-rw-r--r--src/sandbox.h1
-rw-r--r--tests/sb_printf_tst.c1
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[])
{