public inbox for gentoo-commits@lists.gentoo.org
 help / color / mirror / Atom feed
* [gentoo-commits] proj/sandbox:master commit in: src/, libsbutil/, libsandbox/, tests/
@ 2013-02-25  4:23 Mike Frysinger
  0 siblings, 0 replies; only message in thread
From: Mike Frysinger @ 2013-02-25  4:23 UTC (permalink / raw
  To: gentoo-commits

commit:     e12fee192ac8b0343a468e5a8f7811a7b029ff9a
Author:     Mike Frysinger <vapier <AT> gentoo <DOT> org>
AuthorDate: Sat Feb 23 02:18:07 2013 +0000
Commit:     Mike Frysinger <vapier <AT> gentoo <DOT> org>
CommitDate: Mon Feb 25 04:15:44 2013 +0000
URL:        http://git.overlays.gentoo.org/gitweb/?p=proj/sandbox.git;a=commit;h=e12fee19

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 <AT> gentoo.org>

---
 libsandbox/libsandbox.c     |    4 ++
 libsbutil/get_sandbox_log.c |    5 +++
 libsbutil/sb_efuncs.c       |   66 +++++++++++--------------------------------
 libsbutil/sbutil.h          |    3 ++
 src/environ.c               |    5 ++-
 src/sandbox.c               |   13 ++++++++
 src/sandbox.h               |    1 +
 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[])
 {


^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2013-02-25  4:24 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-02-25  4:23 [gentoo-commits] proj/sandbox:master commit in: src/, libsbutil/, libsandbox/, tests/ Mike Frysinger

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox