public inbox for gentoo-commits@lists.gentoo.org
 help / color / mirror / Atom feed
* [gentoo-commits] proj/sandbox:master commit in: src/, libsbutil/, libsandbox/trace/linux/, /, libsandbox/wrapper-funcs/, ...
@ 2012-06-23 22:08 Mike Frysinger
  0 siblings, 0 replies; only message in thread
From: Mike Frysinger @ 2012-06-23 22:08 UTC (permalink / raw
  To: gentoo-commits

commit:     40abb498ca4a24495fe34e133379382ce8c3eaca
Author:     Mike Frysinger <vapier <AT> gentoo <DOT> org>
AuthorDate: Fri Jun 22 21:19:14 2012 +0000
Commit:     Mike Frysinger <vapier <AT> gentoo <DOT> org>
CommitDate: Sat Jun 23 22:02:43 2012 +0000
URL:        http://git.overlays.gentoo.org/gitweb/?p=proj/sandbox.git;a=commit;h=40abb498

significantly overhaul output helpers

There are a few major points we want to hit here:
 - have all output from libsandbox go through portage helpers when we are
   in the portage environment so that output is properly logged
 - convert SB_E{info,warn,error} to sb_e{info,warn,error} to match style
   of other functions and cut down on confusion
 - move all abort/output helpers to libsbutil so it can be used in all
   source trees and not just by libsandbox
 - migrate all abort points to the centralized sb_ebort helper

Unfortunately, it's not terribly easy to untangle these into separate
patches, but hopefully this shouldn't be too messy as much of it is
mechanical: move funcs between files, and change the name of funcs
that get called.

URL: http://bugs.gentoo.org/278761
Reported-by: Mounir Lamouri <volkmar <AT> gentoo.org>
Signed-off-by: Mike Frysinger <vapier <AT> gentoo.org>

---
 Makefile.am                                   |    9 ++
 libsandbox/Makefile.am                        |    1 -
 libsandbox/canonicalize.c                     |    3 +-
 libsandbox/eqawarn.c                          |   49 -------
 libsandbox/libsandbox.c                       |  139 ++++---------------
 libsandbox/libsandbox.h                       |    4 -
 libsandbox/memory.c                           |    6 +-
 libsandbox/trace.c                            |   62 ++++-----
 libsandbox/trace/linux/x86_64.c               |    2 +-
 libsandbox/wrapper-funcs/fopen_pre_check.c    |    5 +-
 libsandbox/wrapper-funcs/mkdirat_pre_check.c  |   15 +--
 libsandbox/wrapper-funcs/openat_pre_check.c   |   10 +-
 libsandbox/wrapper-funcs/unlinkat_pre_check.c |   15 +--
 libsbutil/Makefile.am                         |    4 +
 libsbutil/sb_backtrace.c                      |   15 ++
 libsbutil/sb_efuncs.c                         |  190 +++++++++++++++++++++++++
 libsbutil/sb_memory.c                         |   37 ++----
 libsbutil/sb_printf.c                         |   25 ----
 libsbutil/sb_proc.c                           |   31 ++++
 libsbutil/sb_write_fd.c                       |   42 ++++++
 libsbutil/sbutil.h                            |   39 ++++--
 src/Makefile.am                               |    6 -
 src/sandbox.c                                 |   17 +--
 tests/sb_printf_tst.c                         |    4 +
 24 files changed, 415 insertions(+), 315 deletions(-)

diff --git a/Makefile.am b/Makefile.am
index 40fbcda..e326b23 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -30,3 +30,12 @@ dist-hook:
 			touch "$(distdir)/ChangeLog" ; \
 		fi ; \
 	fi
+
+install-exec-hook:
+	set -e ; \
+	for f in $(bindir)/sandbox $(libdir)/libsandbox.so ; do \
+		sed -i.tmp \
+			's:__SANDBOX_TESTING:\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00:' \
+			$(DESTDIR)$$f ; \
+		rm -f $(DESTDIR)$$f.tmp ; \
+	done

diff --git a/libsandbox/Makefile.am b/libsandbox/Makefile.am
index 0856aa4..b25e4b3 100644
--- a/libsandbox/Makefile.am
+++ b/libsandbox/Makefile.am
@@ -24,7 +24,6 @@ libsandbox_la_LDFLAGS = \
 	-avoid-version \
 	$(LDFLAG_VER),libsandbox.map
 libsandbox_la_SOURCES = \
-	eqawarn.c    \
 	libsandbox.h \
 	libsandbox.c \
 	lock.c       \

diff --git a/libsandbox/canonicalize.c b/libsandbox/canonicalize.c
index 2bef6b1..6519340 100644
--- a/libsandbox/canonicalize.c
+++ b/libsandbox/canonicalize.c
@@ -80,8 +80,7 @@ erealpath(const char *name, char *resolved)
 		/* We can't handle resolving a buffer inline, so demand
 		 * separate read and write strings.
 		 */
-		if (name == resolved)
-			sb_abort();
+		sb_assert(name != resolved);
 		rpath = resolved;
 	}
 	rpath_limit = rpath + path_max;

diff --git a/libsandbox/eqawarn.c b/libsandbox/eqawarn.c
deleted file mode 100644
index e7b0a9c..0000000
--- a/libsandbox/eqawarn.c
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Dump a QA warning
- *
- * Copyright 1999-2009 Gentoo Foundation
- * Licensed under the GPL-2
- */
-
-#include "headers.h"
-#include "libsandbox.h"
-#include "sbutil.h"
-#include "wrappers.h"
-
-/* First try to use the eqawarn program from portage.  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.
- */
-void sb_eqawarn(const char *format, ...)
-{
-	va_list args;
-	FILE *fp;
-	sighandler_t oldsig;
-	bool is_pipe;
-
-	/* If popen() fails, then writes to it will trigger SIGPIPE */
-	oldsig = signal(SIGPIPE, SIG_IGN);
-
-	fp = sb_unwrapped_popen("xargs eqawarn 2>/dev/null", "we");
-	is_pipe = true;
-	if (!fp) {
- do_tty:
-		is_pipe = false;
-		fp = fopen("/dev/tty", "ae");
-		if (!fp)
-			fp = stderr;
-	}
-
-	sb_fprintf(fp, "QA Notice: ");
-	va_start(args, format);
-	sb_vfprintf(fp, format, args);
-	va_end(args);
-
-	if (is_pipe) {
-		int status = pclose(fp);
-		if (WEXITSTATUS(status))
-			goto do_tty;
-	}
-
-	signal(SIGPIPE, oldsig);
-}

diff --git a/libsandbox/libsandbox.c b/libsandbox/libsandbox.c
index e0b291a..eac134e 100644
--- a/libsandbox/libsandbox.c
+++ b/libsandbox/libsandbox.c
@@ -59,9 +59,12 @@ typedef struct {
 } sbcontext_t;
 
 static char *cached_env_vars[MAX_DYN_PREFIXES];
+static char log_path[SB_PATH_MAX];
+static char debug_log_path[SB_PATH_MAX];
 bool sandbox_on = true;
 static bool sb_init = false;
 int (*sbio_open)(const char *, int, mode_t) = sb_unwrapped_open;
+FILE *(*sbio_popen)(const char *, const char *) = sb_unwrapped_popen;
 
 static char *resolve_path(const char *, int);
 static int check_prefixes(char **, int, const char *);
@@ -69,6 +72,8 @@ 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_fallback_path[] = "/dev/tty";
+
 #ifdef SB_MEM_DEBUG
 __attribute__((constructor))
 void libsb_init(void)
@@ -79,29 +84,6 @@ void libsb_init(void)
 }
 #endif
 
-static const char *sb_get_fd_dir(void)
-{
-#if defined(SANDBOX_PROC_SELF_FD)
-	return "/proc/self/fd";
-#elif defined(SANDBOX_DEV_FD)
-	return "/dev/fd";
-#else
-# error "how do i access a proc's fd/ tree ?"
-#endif
-}
-
-static const char *sb_get_cmdline(pid_t pid)
-{
-#if !defined(SANDBOX_PROC_1_CMDLINE) && !defined(SANDBOX_PROC_SELF_CMDLINE) && !defined(SANDBOX_PROC_dd_CMDLINE)
-# error "how do i access a proc's cmdline ?"
-#endif
-	static char path[256];
-	if (!pid)
-		pid = getpid();
-	sprintf(path, "/proc/%i/cmdline", pid);
-	return path;
-}
-
 /* resolve_dirfd_path - get the path relative to a dirfd
  *
  * return value:
@@ -134,9 +116,7 @@ int resolve_dirfd_path(int dirfd, const char *path, char *resolved_path,
 			restore_errno();
 			return 2;
 		}
-		if (is_env_on(ENV_SANDBOX_DEBUG))
-			SB_EINFO("AT_FD LOOKUP", "  fail: %s: %s\n",
-				resolved_path, strerror(errno));
+		sb_debug_dyn("AT_FD LOOKUP fail: %s: %s\n", resolved_path, strerror(errno));
 		/* If the fd isn't found, some guys (glibc) expect errno */
 		if (errno == ENOENT)
 			errno = EBADF;
@@ -173,8 +153,7 @@ int canonicalize(const char *path, char *resolved_path)
 	/* We can't handle resolving a buffer inline (erealpath),
 	 * so demand separate read and write strings.
 	 */
-	if (path == resolved_path)
-		sb_abort();
+	sb_assert(path != resolved_path);
 
 	retval = erealpath(path, resolved_path);
 
@@ -382,80 +361,14 @@ char *egetcwd(char *buf, size_t size)
 	return tmpbuf;
 }
 
-static int sb_copy_file_to_fd(const char *file, int ofd)
+void __sb_dump_backtrace(void)
 {
-	int ret = -1;
-
-	int ifd = sb_open(file, O_RDONLY|O_CLOEXEC, 0);
-	if (ifd == -1)
-		return ret;
-
-	size_t pagesz = getpagesize();
-	char *buf = xmalloc(pagesz);
-	while (1) {
-		size_t len = sb_read(ifd, buf, pagesz);
-		if (len == -1)
-			goto error;
-		else if (!len)
-			break;
-		size_t i;
-		for (i = 0; i < len; ++i)
-			if (!buf[i])
-				buf[i] = ' ';
-		if (sb_write(ofd, buf, len) != len)
-			goto error;
-	}
-
-	ret = 0;
- error:
-	sb_close(ifd);
-	free(buf);
-	return ret;
-}
-
-void sb_dump_backtrace(void)
-{
-#ifdef HAVE_BACKTRACE
-	void *funcs[10];
-	int num_funcs;
-	num_funcs = backtrace(funcs, ARRAY_SIZE(funcs));
-	backtrace_symbols_fd(funcs, num_funcs, STDERR_FILENO);
-#endif
 	const char *cmdline = sb_get_cmdline(trace_pid);
 	sb_printf("%s: ", cmdline);
 	sb_copy_file_to_fd(cmdline, STDERR_FILENO);
 	sb_printf("\n\n");
 }
 
-__attribute__((noreturn))
-void sb_abort(void)
-{
-	sb_dump_backtrace();
-
-#ifndef NDEBUG
-	if (is_env_on("SANDBOX_GDB")) {
-		SB_EINFO("\nattempting to autolaunch gdb", " please wait ...\n\n");
-		pid_t crashed_pid = getpid();
-		switch (fork()) {
-			case -1: break;
-			case 0: {
-				char pid[10];
-				snprintf(pid, sizeof(pid), "%i", crashed_pid);
-				unsetenv(ENV_LD_PRELOAD);
-				/*sb_unwrapped_*/execlp("gdb", "gdb", "--quiet", "--pid", pid, "-ex", "bt full", NULL);
-				break;
-			}
-			default: {
-				int status;
-				wait(&status);
-			}
-		}
-	}
-#endif
-
-	abort();
-}
-
 #define _SB_WRITE_STR(str) \
 	do { \
 		size_t _len = strlen(str); \
@@ -473,18 +386,16 @@ static bool write_logfile(const char *logfile, const char *func, const char *pat
 	stat_ret = lstat(logfile, &log_stat);
 	/* Do not care about failure */
 	errno = 0;
-	if ((0 == stat_ret) &&
-	    (0 == S_ISREG(log_stat.st_mode))) {
-		SB_EERROR("SECURITY BREACH", "  '%s' %s\n", logfile,
+	if (stat_ret == 0 && S_ISREG(log_stat.st_mode) == 0)
+		sb_ebort("SECURITY BREACH: '%s' %s\n", logfile,
 			"already exists and is not a regular file!");
-		sb_abort();
-	}
 
 	logfd = sb_open(logfile,
 		O_APPEND | O_WRONLY | O_CREAT | O_CLOEXEC,
 		S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
 	if (logfd == -1) {
-		SB_EERROR("ISE:write_logfile ", "unable to append logfile\n");
+		sb_eerror("ISE:%s: unable to append logfile: %s\n",
+			__func__, logfile);
 		goto error;
 	}
 
@@ -920,7 +831,6 @@ static int check_syscall(sbcontext_t *sbcontext, int sb_nr, const char *func,
 {
 	char *absolute_path = NULL;
 	char *resolved_path = NULL;
-	char *log_path, *debug_log_path;
 	int old_errno = errno;
 	int result;
 	bool access, debug, verbose;
@@ -931,21 +841,21 @@ static int check_syscall(sbcontext_t *sbcontext, int sb_nr, const char *func,
 		goto error;
 
 	verbose = is_env_on(ENV_SANDBOX_VERBOSE);
-	log_path = getenv(ENV_SANDBOX_LOG);
 	debug = is_env_on(ENV_SANDBOX_DEBUG);
-	if (debug)
-		debug_log_path = getenv(ENV_SANDBOX_DEBUG_LOG);
 
 	result = check_access(sbcontext, sb_nr, func, flags, absolute_path, resolved_path);
 
 	if (verbose) {
 		int sym_len = SB_MAX_STRING_LEN + 1 - strlen(func);
 		if (!result && sbcontext->show_access_violation)
-			SB_EERROR("ACCESS DENIED",   "  %s:%*s%s\n", func, sym_len, "", absolute_path);
+			sb_eerror("%sACCESS DENIED%s:  %s:%*s%s\n",
+				COLOR_RED, COLOR_NORMAL, func, sym_len, "", absolute_path);
 		else if (debug && sbcontext->show_access_violation)
-			SB_EINFO("ACCESS ALLOWED",   "  %s:%*s%s\n", func, sym_len, "", absolute_path);
+			sb_einfo("%sACCESS ALLOWED%s:  %s:%*s%s\n",
+				COLOR_GREEN, COLOR_NORMAL, func, sym_len, "", absolute_path);
 		else if (debug && !sbcontext->show_access_violation)
-			SB_EWARN("ACCESS PREDICTED", "  %s:%*s%s\n", func, sym_len, "", absolute_path);
+			sb_ewarn("%sACCESS PREDICTED%s:  %s:%*s%s\n",
+				COLOR_YELLOW, COLOR_NORMAL, func, sym_len, "", absolute_path);
 	}
 
 	if ((0 == result) && sbcontext->show_access_violation)
@@ -953,13 +863,13 @@ static int check_syscall(sbcontext_t *sbcontext, int sb_nr, const char *func,
 	else
 		access = true;
 
-	if (log_path && !access) {
+	if (!access) {
 		bool worked = write_logfile(log_path, func, file, absolute_path, resolved_path, access);
 		if (!worked && errno)
 			goto error;
 	}
 
-	if (debug && debug_log_path) {
+	if (debug) {
 		bool worked = write_logfile(debug_log_path, func, file, absolute_path, resolved_path, access);
 		if (!worked && errno)
 			goto error;
@@ -989,10 +899,8 @@ static int check_syscall(sbcontext_t *sbcontext, int sb_nr, const char *func,
 		return 2;
 
 	/* If we get here, something bad happened */
-	SB_EERROR("ISE ", "%s(%s): %s\n"
-		"\tabs_path: %s\n" "\tres_path: %s\n",
-		func, file, strerror(errno), absolute_path, resolved_path);
-	sb_abort();
+	sb_ebort("ISE:\n\tabs_path: %s\n\tres_path: %s\n",
+		absolute_path, resolved_path);
 }
 
 bool is_sandbox_on(void)
@@ -1056,6 +964,9 @@ bool before_syscall(int dirfd, int sb_nr, const char *func, const char *file, in
 		/* Get the path and name to this library */
 		get_sandbox_lib(sandbox_lib);
 
+		get_sandbox_log(log_path);
+		get_sandbox_debug_log(debug_log_path);
+
 		init_context(&sbcontext);
 		sb_init = true;
 	}

diff --git a/libsandbox/libsandbox.h b/libsandbox/libsandbox.h
index 3177253..38e983d 100644
--- a/libsandbox/libsandbox.h
+++ b/libsandbox/libsandbox.h
@@ -63,10 +63,6 @@ extern void sb_unlock(void);
 
 void trace_main(const char *filename, char *const argv[]);
 
-__printf(1, 2) void sb_eqawarn(const char *format, ...);
-void sb_dump_backtrace(void);
-__noreturn void sb_abort(void);
-
 /* glibc modified realpath() function */
 char *erealpath(const char *, char *);
 char *egetcwd(char *, size_t);

diff --git a/libsandbox/memory.c b/libsandbox/memory.c
index bc0400f..5609208 100644
--- a/libsandbox/memory.c
+++ b/libsandbox/memory.c
@@ -54,11 +54,9 @@ void free(void *ptr)
 {
 	if (ptr == NULL)
 		return;
-	if (munmap(SB_MALLOC_TO_MMAP(ptr), SB_MALLOC_TO_SIZE(ptr))) {
-		SB_EERROR("sandbox memory corruption", " free(%p): %s\n",
+	if (munmap(SB_MALLOC_TO_MMAP(ptr), SB_MALLOC_TO_SIZE(ptr)))
+		sb_ebort("sandbox memory corruption with free(%p): %s\n",
 			ptr, strerror(errno));
-		sb_dump_backtrace();
-	}
 }
 
 /* Hrm, implement a zalloc() ? */

diff --git a/libsandbox/trace.c b/libsandbox/trace.c
index 5ccab87..a7b7c02 100644
--- a/libsandbox/trace.c
+++ b/libsandbox/trace.c
@@ -17,9 +17,9 @@ static long _do_ptrace(enum __ptrace_request request, const char *srequest, void
 #else
 # define SBDEBUG 0
 #endif
-#define __SB_DEBUG(fmt, args...) do { if (SBDEBUG) sb_printf(fmt, ## args); } while (0)
-#define _SB_DEBUG(fmt, args...)  do { if (SBDEBUG) SB_EWARN("TRACE ", "(pid=%i):%s: " fmt, getpid(), __func__, ## args); } while (0)
-#define SB_DEBUG(fmt, args...)   _SB_DEBUG(fmt "\n", ## args)
+#define __sb_debug(fmt, args...) do { if (SBDEBUG) sb_printf(fmt, ## args); } while (0)
+#define _sb_debug(fmt, args...)  do { if (SBDEBUG) sb_ewarn("TRACE (pid=%i):%s: " fmt, getpid(), __func__, ## args); } while (0)
+#define sb_debug(fmt, args...)   _sb_debug(fmt "\n", ## args)
 
 #include "trace/os.c"
 
@@ -64,9 +64,8 @@ static long _do_ptrace(enum __ptrace_request request, const char *srequest, void
 			    request == PTRACE_PEEKUSER)
 				return ret;
 
-		SB_EERROR("ISE:_do_ptrace ", "ptrace(%s, ..., %p, %p): %s\n",
+		sb_ebort("ISE:_do_ptrace: ptrace(%s, ..., %p, %p): %s\n",
 			srequest, addr, data, strerror(errno));
-		sb_abort();
 	}
 	return ret;
 }
@@ -158,7 +157,7 @@ static const char *strsig(int sig)
 
 static void trace_child_signal(int signo, siginfo_t *info, void *context)
 {
-	SB_DEBUG("got sig %s(%i): code:%s(%i) status:%s(%i)",
+	sb_debug("got sig %s(%i): code:%s(%i) status:%s(%i)",
 		strsig(signo), signo,
 		strcld_chld(info->si_code), info->si_code,
 		strsig(info->si_status), info->si_status);
@@ -169,7 +168,7 @@ static void trace_child_signal(int signo, siginfo_t *info, void *context)
 			trace_exit(128 + info->si_status);
 
 		case CLD_EXITED:
-			__SB_DEBUG(" = %i\n", info->si_status);
+			__sb_debug(" = %i\n", info->si_status);
 			trace_exit(info->si_status);
 
 		case CLD_TRAPPED:
@@ -190,7 +189,7 @@ static void trace_child_signal(int signo, siginfo_t *info, void *context)
 			return;
 	}
 
-	SB_EERROR("ISE:trace_child_signal ", "child (%i) signal %s(%i), code %s(%i), status %s(%i)\n",
+	sb_eerror("ISE:trace_child_signal: child (%i) signal %s(%i), code %s(%i), status %s(%i)\n",
 		trace_pid,
 		strsig(signo), signo,
 		strcld_chld(info->si_code), info->si_code,
@@ -221,7 +220,7 @@ struct syscall_state {
 static bool _trace_check_syscall_C(struct syscall_state *state, int ibase)
 {
 	char *path = do_peekstr(trace_arg(state->regs, ibase));
-	__SB_DEBUG("(\"%s\")", path);
+	__sb_debug("(\"%s\")", path);
 	bool pre_ret, ret;
 	if (state->pre_check)
 		pre_ret = state->pre_check(state->func, path, AT_FDCWD);
@@ -243,7 +242,7 @@ static bool __trace_check_syscall_DCF(struct syscall_state *state, int ibase, in
 {
 	int dirfd = trace_arg(state->regs, ibase);
 	char *path = do_peekstr(trace_arg(state->regs, ibase + 1));
-	__SB_DEBUG("(%i, \"%s\", %x)", dirfd, path, flags);
+	__sb_debug("(%i, \"%s\", %x)", dirfd, path, flags);
 	bool pre_ret, ret;
 	if (state->pre_check)
 		pre_ret = state->pre_check(state->func, path, dirfd);
@@ -340,7 +339,7 @@ static bool trace_check_syscall(const struct syscall_entry *se, void *regs)
 	else if (nr == SB_NR_ACCESS) {
 		char *path = do_peekstr(trace_arg(regs, 1));
 		int flags = trace_arg(regs, 2);
-		__SB_DEBUG("(\"%s\", %x)", path, flags);
+		__sb_debug("(\"%s\", %x)", path, flags);
 		ret = _SB_SAFE_ACCESS(nr, name, path, flags);
 		free(path);
 		return ret;
@@ -349,7 +348,7 @@ static bool trace_check_syscall(const struct syscall_entry *se, void *regs)
 		int dirfd = trace_arg(regs, 1);
 		char *path = do_peekstr(trace_arg(regs, 2));
 		int flags = trace_arg(regs, 3);
-		__SB_DEBUG("(%i, \"%s\", %x)", dirfd, path, flags);
+		__sb_debug("(%i, \"%s\", %x)", dirfd, path, flags);
 		ret = _SB_SAFE_ACCESS_AT(nr, name, dirfd, path, flags);
 		free(path);
 		return ret;
@@ -357,7 +356,7 @@ static bool trace_check_syscall(const struct syscall_entry *se, void *regs)
 	} else if (nr == SB_NR_OPEN) {
 		char *path = do_peekstr(trace_arg(regs, 1));
 		int flags = trace_arg(regs, 2);
-		__SB_DEBUG("(\"%s\", %x)", path, flags);
+		__sb_debug("(\"%s\", %x)", path, flags);
 		if (sb_openat_pre_check(name, path, AT_FDCWD, flags))
 			ret = _SB_SAFE_OPEN_INT(nr, name, path, flags);
 		else
@@ -369,7 +368,7 @@ static bool trace_check_syscall(const struct syscall_entry *se, void *regs)
 		int dirfd = trace_arg(regs, 1);
 		char *path = do_peekstr(trace_arg(regs, 2));
 		int flags = trace_arg(regs, 3);
-		__SB_DEBUG("(%i, \"%s\", %x)", dirfd, path, flags);
+		__sb_debug("(%i, \"%s\", %x)", dirfd, path, flags);
 		if (sb_openat_pre_check(name, path, dirfd, flags))
 			ret = _SB_SAFE_OPEN_INT_AT(nr, name, dirfd, path, flags);
 		else
@@ -379,7 +378,7 @@ static bool trace_check_syscall(const struct syscall_entry *se, void *regs)
 	}
 
  done:
-	__SB_DEBUG("(...)");
+	__sb_debug("(...)");
 	return ret;
 }
 
@@ -422,9 +421,9 @@ static void trace_loop(void)
 			se = lookup_syscall_in_tbl(tbl_at_fork, nr);
 			if (!before_syscall || !se || se->sys != SB_NR_EXECVE) {
 				if (before_syscall)
-					_SB_DEBUG(">%s:%i", se ? se->name : "IDK", nr);
+					_sb_debug(">%s:%i", se ? se->name : "IDK", nr);
 				else
-					__SB_DEBUG("(...pre-exec...) = ...\n");
+					__sb_debug("(...pre-exec...) = ...\n");
 				goto loop_again;
 			}
 			++exec_state;
@@ -437,11 +436,9 @@ static void trace_loop(void)
 		se = lookup_syscall(nr);
 		ret = trace_get_regs(&regs);
 		if (before_syscall) {
-			_SB_DEBUG("%s:%i", se ? se->name : "IDK", nr);
+			_sb_debug("%s:%i", se ? se->name : "IDK", nr);
 			if (!trace_check_syscall(se, &regs)) {
-				if (is_env_on(ENV_SANDBOX_DEBUG))
-					SB_EINFO("trace_loop", " forcing EPERM after %s\n",
-						se->name);
+				sb_debug_dyn("trace_loop: forcing EPERM after %s\n", se->name);
 				trace_set_sysnum(&regs, -1);
 				fake_syscall_ret = true;
 			}
@@ -456,9 +453,9 @@ static void trace_loop(void)
 			} else
 				ret = trace_result(&regs, &err);
 
-			__SB_DEBUG(" = %li", ret);
+			__sb_debug(" = %li", ret);
 			if (err) {
-				__SB_DEBUG(" (errno: %i: %s)", err, strerror(err));
+				__sb_debug(" (errno: %i: %s)", err, strerror(err));
 
 				/* If the exec() failed for whatever reason, kill the
 				 * child and have the parent resume like normal
@@ -469,7 +466,7 @@ static void trace_loop(void)
 					return;
 				}
 			}
-			__SB_DEBUG("\n");
+			__sb_debug("\n");
 
 			exec_state = 2;
 		}
@@ -487,21 +484,16 @@ void trace_main(const char *filename, char *const argv[])
 	sa.sa_sigaction = trace_child_signal;
 	sigaction(SIGCHLD, &sa, &old_sa);
 
-	if (is_env_on(ENV_SANDBOX_DEBUG))
-		SB_EINFO("trace_main", " tracing: %s\n", filename);
+	sb_debug_dyn("trace_main: tracing: %s\n", filename);
 
-	if (trace_pid) {
-		SB_EERROR("ISE:trace_main ", "trace code assumes multiple threads are not forking\n");
-		sb_abort();
-	}
+	if (trace_pid)
+		sb_ebort("ISE: trace code assumes multiple threads are not forking\n");
 
 	trace_pid = fork();
 	if (unlikely(trace_pid == -1)) {
-		SB_EERROR("ISE:trace_main ", "vfork() failed: %s\n",
-			strerror(errno));
-		sb_abort();
+		sb_ebort("ISE: vfork() failed: %s\n", strerror(errno));
 	} else if (trace_pid) {
-		SB_DEBUG("parent waiting for child (pid=%i) to signal", trace_pid);
+		sb_debug("parent waiting for child (pid=%i) to signal", trace_pid);
 		waitpid(trace_pid, NULL, 0);
 #if defined(PTRACE_SETOPTIONS) && defined(PTRACE_O_TRACESYSGOOD)
 		/* Not all kernel versions support this, so ignore return */
@@ -511,7 +503,7 @@ void trace_main(const char *filename, char *const argv[])
 		return;
 	}
 
-	SB_DEBUG("child setting up ...");
+	sb_debug("child setting up ...");
 	sigaction(SIGCHLD, &old_sa, NULL);
 	do_ptrace(PTRACE_TRACEME, NULL, NULL);
 	kill(getpid(), SIGSTOP);

diff --git a/libsandbox/trace/linux/x86_64.c b/libsandbox/trace/linux/x86_64.c
index 0110302..8a214f9 100644
--- a/libsandbox/trace/linux/x86_64.c
+++ b/libsandbox/trace/linux/x86_64.c
@@ -18,7 +18,7 @@ static bool pers_is_32(void)
 	switch (do_peekuser(8 * CS)) {
 		case 0x23: return true;
 		case 0x33: return false;
-		default:   sb_abort();
+		default:   sb_ebort("unknown x86_64 personality");
 	}
 }
 

diff --git a/libsandbox/wrapper-funcs/fopen_pre_check.c b/libsandbox/wrapper-funcs/fopen_pre_check.c
index 9ee3b60..765526e 100644
--- a/libsandbox/wrapper-funcs/fopen_pre_check.c
+++ b/libsandbox/wrapper-funcs/fopen_pre_check.c
@@ -13,9 +13,8 @@ bool sb_fopen_pre_check(const char *func, const char *pathname, const char *mode
 		/* If we're trying to read, fail normally if file does not stat */
 		struct stat st;
 		if (-1 == stat(pathname, &st)) {
-			if (is_env_on(ENV_SANDBOX_DEBUG))
-				SB_EINFO("EARLY FAIL", "  %s(%s): %s\n",
-					func, pathname, strerror(errno));
+			sb_debug_dyn("EARLY FAIL: %s(%s): %s\n",
+				func, pathname, strerror(errno));
 			return false;
 		}
 

diff --git a/libsandbox/wrapper-funcs/mkdirat_pre_check.c b/libsandbox/wrapper-funcs/mkdirat_pre_check.c
index 4fef14c..77a65df 100644
--- a/libsandbox/wrapper-funcs/mkdirat_pre_check.c
+++ b/libsandbox/wrapper-funcs/mkdirat_pre_check.c
@@ -15,9 +15,8 @@ bool sb_mkdirat_pre_check(const char *func, const char *pathname, int dirfd)
 	/* Expand the dirfd path first */
 	switch (resolve_dirfd_path(dirfd, pathname, dirfd_path, sizeof(dirfd_path))) {
 		case -1:
-			if (is_env_on(ENV_SANDBOX_DEBUG))
-				SB_EINFO("EARLY FAIL", "  %s(%s) @ resolve_dirfd_path: %s\n",
-					func, pathname, strerror(errno));
+			sb_debug_dyn("EARLY FAIL: %s(%s) @ resolve_dirfd_path: %s\n",
+				func, pathname, strerror(errno));
 			return false;
 		case 0:
 			pathname = dirfd_path;
@@ -28,9 +27,8 @@ bool sb_mkdirat_pre_check(const char *func, const char *pathname, int dirfd)
 	if (-1 == canonicalize(pathname, canonic))
 		/* see comments in check_syscall() */
 		if (ENAMETOOLONG != errno) {
-			if (is_env_on(ENV_SANDBOX_DEBUG))
-				SB_EINFO("EARLY FAIL", "  %s(%s) @ canonicalize: %s\n",
-					func, pathname, strerror(errno));
+			sb_debug_dyn("EARLY FAIL: %s(%s) @ canonicalize: %s\n",
+				func, pathname, strerror(errno));
 			return false;
 		}
 
@@ -43,9 +41,8 @@ bool sb_mkdirat_pre_check(const char *func, const char *pathname, int dirfd)
 	struct stat st;
 	if (0 == lstat(canonic, &st)) {
 		int new_errno;
-		if (is_env_on(ENV_SANDBOX_DEBUG))
-			SB_EINFO("EARLY FAIL", "  %s(%s[%s]) @ lstat: %s\n",
-				func, pathname, canonic, strerror(errno));
+		sb_debug_dyn("EARLY FAIL: %s(%s[%s]) @ lstat: %s\n",
+			func, pathname, canonic, strerror(errno));
 
 		new_errno = EEXIST;
 

diff --git a/libsandbox/wrapper-funcs/openat_pre_check.c b/libsandbox/wrapper-funcs/openat_pre_check.c
index 23149dc..c827ee6 100644
--- a/libsandbox/wrapper-funcs/openat_pre_check.c
+++ b/libsandbox/wrapper-funcs/openat_pre_check.c
@@ -19,9 +19,8 @@ bool sb_openat_pre_check(const char *func, const char *pathname, int dirfd, int
 	char dirfd_path[SB_PATH_MAX];
 	switch (resolve_dirfd_path(dirfd, pathname, dirfd_path, sizeof(dirfd_path))) {
 		case -1:
-			if (is_env_on(ENV_SANDBOX_DEBUG))
-				SB_EINFO("EARLY FAIL", "  %s(%s) @ resolve_dirfd_path: %s\n",
-					func, pathname, strerror(errno));
+			sb_debug_dyn("EARLY FAIL: %s(%s) @ resolve_dirfd_path: %s\n",
+				func, pathname, strerror(errno));
 			return false;
 		case 0:
 			pathname = dirfd_path;
@@ -31,9 +30,8 @@ bool sb_openat_pre_check(const char *func, const char *pathname, int dirfd, int
 	/* Doesn't exist -> skip permission checks */
 	struct stat st;
 	if (-1 == stat(pathname, &st)) {
-		if (is_env_on(ENV_SANDBOX_DEBUG))
-			SB_EINFO("EARLY FAIL", "  %s(%s): %s\n",
-				func, pathname, strerror(errno));
+		sb_debug_dyn("EARLY FAIL: %s(%s): %s\n",
+			func, pathname, strerror(errno));
 		return false;
 	}
 

diff --git a/libsandbox/wrapper-funcs/unlinkat_pre_check.c b/libsandbox/wrapper-funcs/unlinkat_pre_check.c
index 1c4f7e3..9f5e7d7 100644
--- a/libsandbox/wrapper-funcs/unlinkat_pre_check.c
+++ b/libsandbox/wrapper-funcs/unlinkat_pre_check.c
@@ -15,9 +15,8 @@ bool sb_unlinkat_pre_check(const char *func, const char *pathname, int dirfd)
 	/* Expand the dirfd path first */
 	switch (resolve_dirfd_path(dirfd, pathname, dirfd_path, sizeof(dirfd_path))) {
 		case -1:
-			if (is_env_on(ENV_SANDBOX_DEBUG))
-				SB_EINFO("EARLY FAIL", "  %s(%s) @ resolve_dirfd_path: %s\n",
-					func, pathname, strerror(errno));
+			sb_debug_dyn("EARLY FAIL: %s(%s) @ resolve_dirfd_path: %s\n",
+				func, pathname, strerror(errno));
 			return false;
 		case 0:
 			pathname = dirfd_path;
@@ -28,9 +27,8 @@ bool sb_unlinkat_pre_check(const char *func, const char *pathname, int dirfd)
 	if (-1 == canonicalize(pathname, canonic))
 		/* see comments in check_syscall() */
 		if (ENAMETOOLONG != errno) {
-			if (is_env_on(ENV_SANDBOX_DEBUG))
-				SB_EINFO("EARLY FAIL", "  %s(%s) @ canonicalize: %s\n",
-					func, pathname, strerror(errno));
+			sb_debug_dyn("EARLY FAIL: %s(%s) @ canonicalize: %s\n",
+				func, pathname, strerror(errno));
 			return false;
 		}
 
@@ -40,9 +38,8 @@ bool sb_unlinkat_pre_check(const char *func, const char *pathname, int dirfd)
 	    0 == strcmp(canonic, "/dev/zero"))
 	{
 		errno = EACCES;
-		if (is_env_on(ENV_SANDBOX_DEBUG))
-			SB_EINFO("EARLY FAIL", "  %s(%s): %s\n",
-				func, pathname, strerror(errno));
+		sb_debug_dyn("EARLY FAIL: %s(%s): %s\n",
+			func, pathname, strerror(errno));
 		return false;
 	}
 

diff --git a/libsbutil/Makefile.am b/libsbutil/Makefile.am
index f1feca3..49a7d3b 100644
--- a/libsbutil/Makefile.am
+++ b/libsbutil/Makefile.am
@@ -20,11 +20,15 @@ libsbutil_la_SOURCES =                        \
 	get_tmp_dir.c                         \
 	is_env_on.c                           \
 	is_env_off.c                          \
+	sb_backtrace.c                        \
+	sb_efuncs.c                           \
 	sb_open.c                             \
 	sb_read.c                             \
 	sb_write.c                            \
+	sb_write_fd.c                         \
 	sb_close.c                            \
 	sb_printf.c                           \
+	sb_proc.c                             \
 	sb_memory.c                           \
 	include/rcscripts/rcutil.h            \
 	include/rcscripts/util/str_list.h     \

diff --git a/libsbutil/sb_backtrace.c b/libsbutil/sb_backtrace.c
new file mode 100644
index 0000000..e3d1ed7
--- /dev/null
+++ b/libsbutil/sb_backtrace.c
@@ -0,0 +1,15 @@
+/*
+ * sb_backtrace.c
+ *
+ * Need to keep in a dedicated file so libsandbox can override.
+ *
+ * Copyright 1999-2012 Gentoo Foundation
+ * Licensed under the GPL-2
+ */
+
+#include "headers.h"
+#include "sbutil.h"
+
+void __sb_dump_backtrace(void)
+{
+}

diff --git a/libsbutil/sb_efuncs.c b/libsbutil/sb_efuncs.c
new file mode 100644
index 0000000..248c2bd
--- /dev/null
+++ b/libsbutil/sb_efuncs.c
@@ -0,0 +1,190 @@
+/*
+ * sb_efuncs.c
+ *
+ * Helpers for doing pretty output.
+ *
+ * Copyright 1999-2012 Gentoo Foundation
+ * Licensed under the GPL-2
+ */
+
+#include "headers.h"
+#include "sbutil.h"
+
+static bool nocolor, init_color = false;
+void sb_efunc(const char *color, const char *hilight, const char *format, ...)
+{
+	save_errno();
+
+	int fd = STDERR_FILENO;
+
+	if (!init_color) {
+		nocolor = is_env_on(ENV_NOCOLOR);
+		init_color = true;
+	}
+
+	if (!nocolor)
+		sb_fdprintf(fd, "%s%s%s", color, hilight, COLOR_NORMAL);
+	else
+		sb_fdprintf(fd, "%s", hilight);
+
+	va_list args;
+	va_start(args, format);
+	sb_vfdprintf(fd, format, args);
+	va_end(args);
+
+	restore_errno();
+}
+
+const char *colors[] = {
+	"\033[0m",
+	"\033[32;01m",
+	"\033[33;01m",
+	"\033[31;01m",
+};
+__attribute__((constructor))
+static void sbio_init(void)
+{
+	if (is_env_on(ENV_NOCOLOR))
+		memset(colors, 0, sizeof(colors));
+}
+
+static bool try_portage_helpers = false;
+
+/*
+ * 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.
+ */
+static void sb_vefunc(const char *prog, const char *color, const char *format, va_list args)
+{
+	char shellcode[128];
+	FILE *fp;
+	sighandler_t oldsig;
+	bool is_pipe = false;
+
+	if (try_portage_helpers) {
+		/* If popen() fails, then writes to it will trigger SIGPIPE */
+		/* XXX: convert this to sigaction */
+		oldsig = signal(SIGPIPE, SIG_IGN);
+
+		sprintf(shellcode, "xargs %s 2>/dev/null", prog);
+		fp = sbio_popen(shellcode, "we");
+		is_pipe = true;
+	} 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;
+	}
+
+	sb_fprintf(fp, " %s*%s ", color, COLOR_NORMAL);
+	sb_vfprintf(fp, format, args);
+
+	if (is_pipe) {
+		int status = pclose(fp);
+		if (WEXITSTATUS(status))
+			goto do_tty;
+	} else if (fp != stderr)
+		fclose(fp);
+
+	if (try_portage_helpers)
+		signal(SIGPIPE, oldsig);
+}
+
+void sb_einfo(const char *format, ...)
+{
+	va_list args;
+	va_start(args, format);
+	sb_vefunc("einfo", COLOR_GREEN, format, args);
+	va_end(args);
+}
+
+void sb_debug_dyn(const char *format, ...)
+{
+	if (!is_env_on(ENV_SANDBOX_DEBUG))
+		return;
+
+	va_list args;
+	va_start(args, format);
+	sb_vefunc("einfo", COLOR_GREEN, format, args);
+	va_end(args);
+}
+
+void sb_ewarn(const char *format, ...)
+{
+	va_list args;
+	va_start(args, format);
+	sb_vefunc("ewarn", COLOR_YELLOW, format, args);
+	va_end(args);
+}
+
+void sb_eerror(const char *format, ...)
+{
+	va_list args;
+	va_start(args, format);
+	sb_vefunc("eerror", COLOR_RED, format, args);
+	va_end(args);
+}
+
+void sb_eqawarn(const char *format, ...)
+{
+	va_list args;
+	va_start(args, format);
+	sb_vefunc("eqawarn", COLOR_YELLOW, format, args);
+	va_end(args);
+}
+
+void sb_dump_backtrace(void)
+{
+#ifdef HAVE_BACKTRACE
+	void *funcs[10];
+	int num_funcs;
+	num_funcs = backtrace(funcs, ARRAY_SIZE(funcs));
+	backtrace_symbols_fd(funcs, num_funcs, STDERR_FILENO);
+#endif
+	__sb_dump_backtrace();
+}
+
+void __sb_ebort(const char *file, const char *func, size_t line_num, const char *format, ...)
+{
+	va_list args;
+
+	sb_eerror("%s:%s():%zu: failure (%s):\n", file, func, line_num, strerror(errno));
+
+	va_start(args, format);
+	sb_vefunc("eerror", COLOR_RED, format, args);
+	va_end(args);
+
+	sb_dump_backtrace();
+
+#ifndef NDEBUG
+	if (is_env_on("SANDBOX_GDB")) {
+		sb_einfo("attempting to autolaunch gdb; please wait ...\n\n");
+		pid_t crashed_pid = getpid();
+		switch (fork()) {
+			case -1: break;
+			case 0: {
+				char pid[10];
+				snprintf(pid, sizeof(pid), "%i", crashed_pid);
+				unsetenv(ENV_LD_PRELOAD);
+				/*sb_unwrapped_*/execlp("gdb", "gdb", "--quiet", "--pid", pid, "-ex", "bt full", NULL);
+				break;
+			}
+			default: {
+				int status;
+				wait(&status);
+			}
+		}
+	}
+#endif
+
+	abort();
+}

diff --git a/libsbutil/sb_memory.c b/libsbutil/sb_memory.c
index 40a4762..bdc054f 100644
--- a/libsbutil/sb_memory.c
+++ b/libsbutil/sb_memory.c
@@ -1,5 +1,5 @@
 /*
- * debug.c
+ * sb_memory.c
  *
  * Simle debugging/logging macro's and functions.
  *
@@ -16,11 +16,8 @@ __xcalloc(size_t nmemb, size_t size, const char *file, const char *func, size_t
 {
 	void *ret = calloc(nmemb, size);
 
-	if (ret == NULL) {
-		SB_EERROR("calloc()", " %s:%s():%zu: calloc(%zu, %zu) failed: %s\n",
-			file, func, line, nmemb, size, strerror(errno));
-		abort();
-	}
+	if (ret == NULL)
+		__sb_ebort(file, func, line, "calloc(%zu, %zu)\n", nmemb, size);
 
 	return ret;
 }
@@ -30,11 +27,8 @@ __xmalloc(size_t size, const char *file, const char *func, size_t line)
 {
 	void *ret = malloc(size);
 
-	if (ret == NULL) {
-		SB_EERROR("malloc()", " %s:%s():%zu: malloc(%zu) failed: %s\n",
-			file, func, line, size, strerror(errno));
-		abort();
-	}
+	if (ret == NULL)
+		__sb_ebort(file, func, line, "malloc(%zu)\n", size);
 
 	return ret;
 }
@@ -50,11 +44,8 @@ __xrealloc(void *ptr, size_t size, const char *file, const char *func, size_t li
 {
 	void *ret = realloc(ptr, size);
 
-	if (ret == NULL) {
-		SB_EERROR("realloc()", " %s:%s():%zu: realloc(%p, %zu) failed: %s\n",
-			file, func, line, ptr, size, strerror(errno));
-		abort();
-	}
+	if (ret == NULL)
+		__sb_ebort(file, func, line, "realloc(%p, %zu)\n", ptr, size);
 
 	return ret;
 }
@@ -64,11 +55,8 @@ __xstrdup(const char *str, const char *file, const char *func, size_t line)
 {
 	char *ret = strdup(str);
 
-	if (ret == NULL) {
-		SB_EERROR("strdup()", " %s:%s():%zu: strdup(%p) failed: %s\n",
-			file, func, line, str, strerror(errno));
-		abort();
-	}
+	if (ret == NULL)
+		__sb_ebort(file, func, line, "strdup(%p)\n", str);
 
 	return ret;
 }
@@ -94,11 +82,8 @@ __xstrndup(const char *str, size_t size, const char *file, const char *func, siz
 {
 	char *ret = strndup(str, size);
 
-	if (ret == NULL) {
-		SB_EERROR("strndup()", " %s:%s():%zu: strndup(%p, %zu) failed: %s\n",
-			file, func, line, str, size, strerror(errno));
-		abort();
-	}
+	if (ret == NULL)
+		__sb_ebort(file, func, line, "strndup(%p, %zu)\n", str, size);
 
 	return ret;
 }

diff --git a/libsbutil/sb_printf.c b/libsbutil/sb_printf.c
index d3a27df..1ad9e23 100644
--- a/libsbutil/sb_printf.c
+++ b/libsbutil/sb_printf.c
@@ -187,28 +187,3 @@ void sb_printf(const char *format, ...)
 	sb_vfdprintf(STDERR_FILENO, format, args);
 	va_end(args);
 }
-
-static bool nocolor, init_color = false;
-void sb_efunc(const char *color, const char *hilight, const char *format, ...)
-{
-	save_errno();
-
-	int fd = STDERR_FILENO;
-
-	if (!init_color) {
-		nocolor = is_env_on(ENV_NOCOLOR);
-		init_color = true;
-	}
-
-	if (!nocolor)
-		sb_fdprintf(fd, "%s%s%s", color, hilight, COLOR_NORMAL);
-	else
-		sb_fdprintf(fd, "%s", hilight);
-
-	va_list args;
-	va_start(args, format);
-	sb_vfdprintf(fd, format, args);
-	va_end(args);
-
-	restore_errno();
-}

diff --git a/libsbutil/sb_proc.c b/libsbutil/sb_proc.c
new file mode 100644
index 0000000..c583d95
--- /dev/null
+++ b/libsbutil/sb_proc.c
@@ -0,0 +1,31 @@
+/*
+ * funcs for poking around /proc
+ *
+ * Copyright 1999-2012 Gentoo Foundation
+ * Licensed under the GPL-2
+ */
+
+#include "headers.h"
+#include "sbutil.h"
+
+const char sb_fd_dir[] =
+#if defined(SANDBOX_PROC_SELF_FD)
+	"/proc/self/fd"
+#elif defined(SANDBOX_DEV_FD)
+	"/dev/fd"
+#else
+# error "how do i access a proc's fd/ tree ?"
+#endif
+;
+
+const char *sb_get_cmdline(pid_t pid)
+{
+#if !defined(SANDBOX_PROC_1_CMDLINE) && !defined(SANDBOX_PROC_SELF_CMDLINE) && !defined(SANDBOX_PROC_dd_CMDLINE)
+# error "how do i access a proc's cmdline ?"
+#endif
+	static char path[256];
+	if (!pid)
+		pid = getpid();
+	sprintf(path, "/proc/%i/cmdline", pid);
+	return path;
+}

diff --git a/libsbutil/sb_write_fd.c b/libsbutil/sb_write_fd.c
new file mode 100644
index 0000000..f19d7de
--- /dev/null
+++ b/libsbutil/sb_write_fd.c
@@ -0,0 +1,42 @@
+/*
+ * helper for sucking up a file and writing it to a fd.
+ * good for copying the contents of small status files
+ * into a log file.
+ *
+ * Copyright 1999-2012 Gentoo Foundation
+ * Licensed under the GPL-2
+ */
+
+#include "headers.h"
+#include "sbutil.h"
+
+int sb_copy_file_to_fd(const char *file, int ofd)
+{
+	int ret = -1;
+
+	int ifd = sb_open(file, O_RDONLY|O_CLOEXEC, 0);
+	if (ifd == -1)
+		return ret;
+
+	size_t pagesz = getpagesize();
+	char *buf = xmalloc(pagesz);
+	while (1) {
+		size_t len = sb_read(ifd, buf, pagesz);
+		if (len == -1)
+			goto error;
+		else if (!len)
+			break;
+		size_t i;
+		for (i = 0; i < len; ++i)
+			if (!buf[i])
+				buf[i] = ' ';
+		if (sb_write(ofd, buf, len) != len)
+			goto error;
+	}
+
+	ret = 0;
+ error:
+	sb_close(ifd);
+	free(buf);
+	return ret;
+}

diff --git a/libsbutil/sbutil.h b/libsbutil/sbutil.h
index f45402e..f275514 100644
--- a/libsbutil/sbutil.h
+++ b/libsbutil/sbutil.h
@@ -42,8 +42,7 @@
 #define ENV_SANDBOX_VERBOSE    "SANDBOX_VERBOSE"
 #define ENV_SANDBOX_DEBUG      "SANDBOX_DEBUG"
 
-extern const char env_sandbox_testing[];
-#define ENV_SANDBOX_TESTING    env_sandbox_testing
+#define ENV_SANDBOX_TESTING    "__SANDBOX_TESTING"
 
 #define ENV_SANDBOX_LIB        "SANDBOX_LIB"
 #define ENV_SANDBOX_BASHRC     "SANDBOX_BASHRC"
@@ -67,15 +66,11 @@ extern const char env_sandbox_testing[];
 
 #define SB_BUF_LEN             2048
 
-#define COLOR_NORMAL           "\033[0m"
-#define COLOR_GREEN            "\033[32;01m"
-#define COLOR_YELLOW           "\033[33;01m"
-#define COLOR_RED              "\033[31;01m"
-
-/* Gentoo style e* printing macro's */
-#define SB_EINFO(_hilight, _args...) sb_efunc(COLOR_GREEN, _hilight, _args)
-#define SB_EWARN(_hilight, _args...) sb_efunc(COLOR_YELLOW, _hilight, _args)
-#define SB_EERROR(_hilight, _args...) sb_efunc(COLOR_RED, _hilight, _args)
+extern const char *colors[];
+#define COLOR_NORMAL           colors[0]
+#define COLOR_GREEN            colors[1]
+#define COLOR_YELLOW           colors[2]
+#define COLOR_RED              colors[3]
 
 char *get_sandbox_conf(void);
 char *get_sandbox_confd(char *path);
@@ -87,19 +82,41 @@ int get_tmp_dir(char *path);
 bool is_env_on (const char *);
 bool is_env_off (const char *);
 
+/* proc helpers */
+extern const char sb_fd_dir[];
+#define sb_get_fd_dir() sb_fd_dir
+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_fallback_path[];
 /* Convenience functions to reliably open, read and write to a file */
 int sb_open(const char *path, int flags, mode_t mode);
 size_t sb_read(int fd, void *buf, size_t count);
 size_t sb_write(int fd, const void *buf, size_t count);
 int sb_close(int fd);
+int sb_copy_file_to_fd(const char *file, int ofd);
 
 /* Reliable output */
 __printf(1, 2) void sb_printf(const char *format, ...);
 __printf(2, 3) void sb_fdprintf(int fd, const char *format, ...);
 __printf(2, 0) void sb_vfdprintf(int fd, const char *format, va_list args);
 __printf(3, 4) void sb_efunc(const char *color, const char *hilight, const char *format, ...);
+__printf(1, 2) void sb_einfo(const char *format, ...);
+__printf(1, 2) void sb_ewarn(const char *format, ...);
+__printf(1, 2) void sb_eerror(const char *format, ...);
+__printf(1, 2) void sb_eqawarn(const char *format, ...);
+__printf(1, 2) void sb_debug_dyn(const char *format, ...);
+__printf(4, 5) void __sb_ebort(const char *file, const char *func, size_t line_num, const char *format, ...) __noreturn;
+#define sb_ebort(format, ...) __sb_ebort(__FILE__, __func__, __LINE__, format, ## __VA_ARGS__)
+void sb_dump_backtrace(void);
+void __sb_dump_backtrace(void);
+#define sb_assert(cond) \
+	do { \
+		if (!(cond)) \
+			sb_ebort("assertion failure !(%s)\n", #cond); \
+	} while (0)
 #define sb_fprintf(fp, ...) sb_fdprintf(fileno(fp), __VA_ARGS__)
 #define sb_vfprintf(fp, ...) sb_vfdprintf(fileno(fp), __VA_ARGS__)
 

diff --git a/src/Makefile.am b/src/Makefile.am
index 3e7e31c..c3c1f45 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -13,9 +13,3 @@ sandbox_SOURCES = \
 	environ.c \
 	sandbox.h \
 	sandbox.c
-
-install-exec-hook:
-	sed -i.tmp \
-		's:__SANDBOX_TESTING:\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00:' \
-		$(DESTDIR)$(bindir)/sandbox
-	rm -f $(DESTDIR)$(bindir)/sandbox.tmp

diff --git a/src/sandbox.c b/src/sandbox.c
index 69ab18e..54fbb98 100644
--- a/src/sandbox.c
+++ b/src/sandbox.c
@@ -19,14 +19,14 @@ static int print_debug = 0;
 #define dprintf(fmt, args...) do { if (print_debug) printf(fmt, ## args); } while (0)
 #define dputs(str) do { if (print_debug) puts(str); } while (0)
 int (*sbio_open)(const char *, int, mode_t) = (void *)open;
+FILE *(*sbio_popen)(const char *, const char *) = popen;
 
 volatile static int stop_called = 0;
 volatile static pid_t child_pid = 0;
 
 static const char sandbox_banner[] = "============================= Gentoo path sandbox ==============================";
 static const char sandbox_footer[] = "--------------------------------------------------------------------------------";
-
-const char env_sandbox_testing[] = "__SANDBOX_TESTING";
+const char sbio_fallback_path[] = "/dev/stderr";
 
 static int setup_sandbox(struct sandbox_info_t *sandbox_info, bool interactive)
 {
@@ -87,7 +87,7 @@ static void print_sandbox_log(char *sandbox_log)
 {
 	int sandbox_log_file;
 	size_t len;
-	char buffer[1024];
+	char buffer[8192];
 
 	sandbox_log_file = sb_open(sandbox_log, O_RDONLY, 0);
 	if (-1 == sandbox_log_file) {
@@ -95,8 +95,8 @@ static void print_sandbox_log(char *sandbox_log)
 		return;
 	}
 
-	SB_EERROR("--------------------------- ACCESS VIOLATION SUMMARY ---------------------------", "\n");
-	SB_EERROR("LOG FILE", " \"%s\"\n\n", sandbox_log);
+	sb_eerror("--------------------------- ACCESS VIOLATION SUMMARY ---------------------------\n");
+	sb_eerror("LOG FILE: \"%s\"\n", sandbox_log);
 
 	while (1) {
 		len = sb_read(sandbox_log_file, buffer, sizeof(buffer));
@@ -105,14 +105,11 @@ static void print_sandbox_log(char *sandbox_log)
 			break;
 		} else if (!len)
 			break;
-		if (sb_write(STDERR_FILENO, buffer, len) != len) {
-			sb_pwarn("sb_write(logfile) failed");
-			break;
-		}
+		sb_eerror("\n%s", buffer);
 	}
 	sb_close(sandbox_log_file);
 
-	SB_EERROR("--------------------------------------------------------------------------------", "\n");
+	sb_eerror("--------------------------------------------------------------------------------\n");
 }
 
 static void stop(int signum)

diff --git a/tests/sb_printf_tst.c b/tests/sb_printf_tst.c
index 443c2c2..1db7c33 100644
--- a/tests/sb_printf_tst.c
+++ b/tests/sb_printf_tst.c
@@ -8,6 +8,10 @@
 		_T(sb_printf, fmt, ## args); \
 	} while (0)
 
+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";
+
 int main(int argc, char *argv[])
 {
 	/* sandbox outputs to stderr, so unify it */



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

only message in thread, other threads:[~2012-06-23 22:08 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-06-23 22:08 [gentoo-commits] proj/sandbox:master commit in: src/, libsbutil/, libsandbox/trace/linux/, /, libsandbox/wrapper-funcs/, Mike Frysinger

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