aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Frysinger <vapier@gentoo.org>2013-02-22 21:18:07 -0500
committerMike Frysinger <vapier@gentoo.org>2013-02-24 23:15:44 -0500
commite12fee192ac8b0343a468e5a8f7811a7b029ff9a (patch)
tree252b2e528a3fb99f5cc32127a32ad4d785008a6f /libsbutil
parentlibsandbox: handle ENOSYS w/process_vm_readv (diff)
downloadsandbox-e12fee192ac8b0343a468e5a8f7811a7b029ff9a.tar.gz
sandbox-e12fee192ac8b0343a468e5a8f7811a7b029ff9a.tar.bz2
sandbox-e12fee192ac8b0343a468e5a8f7811a7b029ff9a.zip
add a new message env var
This is used whenever sandbox wants to display an informational message. For example, early notification of a path violation, or debugging output. We can't just pop open an fd and pass that around as apps consider that leakage and will often break assumptions in terms of free fds. Or apps that start up and cleanse all of their open fds. So instead, we just pass around an env var that holds the full path to the file we want will write to. Since these messages are infrequent (compared to overall runtime), opening/writing/closing the path every time is fine. This also avoids all the problems associated with using external portage helpers for writing messages. A follow up commit will take care of the situation where apps (such as scons) attempt to also cleanse the env before forking. URL: http://bugs.gentoo.org/278761 URL: http://bugs.gentoo.org/431638 Signed-off-by: Mike Frysinger <vapier@gentoo.org>
Diffstat (limited to 'libsbutil')
-rw-r--r--libsbutil/get_sandbox_log.c5
-rw-r--r--libsbutil/sb_efuncs.c66
-rw-r--r--libsbutil/sbutil.h3
3 files changed, 25 insertions, 49 deletions
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);