aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Frysinger <vapier@gentoo.org>2009-03-14 13:27:20 -0400
committerMike Frysinger <vapier@gentoo.org>2009-03-18 01:06:20 -0400
commitf06150540e02b694ee87e89d61db8da95f42ed50 (patch)
tree3268a7cb4d1d31dd42d978c415ec677aa2017eba /libsandbox
parentbump to sandbox-1.7 (diff)
downloadsandbox-f06150540e02b694ee87e89d61db8da95f42ed50.tar.gz
sandbox-f06150540e02b694ee87e89d61db8da95f42ed50.tar.bz2
sandbox-f06150540e02b694ee87e89d61db8da95f42ed50.zip
libsandbox: add an eqawarn() func
Break out most of the QA static ELF warning code into a new eqawarn() func. This way we can handle dynamic stuff like calling portage's eqawarn func to handle dirty details like logging. Signed-off-by: Mike Frysinger <vapier@gentoo.org>
Diffstat (limited to 'libsandbox')
-rw-r--r--libsandbox/Makefile.am1
-rw-r--r--libsandbox/eqawarn.c49
-rw-r--r--libsandbox/libsandbox.h1
-rw-r--r--libsandbox/wrapper-funcs/__wrapper_exec.c58
-rw-r--r--libsandbox/wrappers.h2
5 files changed, 90 insertions, 21 deletions
diff --git a/libsandbox/Makefile.am b/libsandbox/Makefile.am
index 97d8864..bdc16ed 100644
--- a/libsandbox/Makefile.am
+++ b/libsandbox/Makefile.am
@@ -27,6 +27,7 @@ libsandbox_la_LDFLAGS = \
-avoid-version \
$(LDFLAG_VER),libsandbox.map
libsandbox_la_SOURCES = \
+ eqawarn.c \
libsandbox.h \
libsandbox.c \
memory.c \
diff --git a/libsandbox/eqawarn.c b/libsandbox/eqawarn.c
new file mode 100644
index 0000000..e7b0a9c
--- /dev/null
+++ b/libsandbox/eqawarn.c
@@ -0,0 +1,49 @@
+/*
+ * 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.h b/libsandbox/libsandbox.h
index 111973e..6fd4cf8 100644
--- a/libsandbox/libsandbox.h
+++ b/libsandbox/libsandbox.h
@@ -46,6 +46,7 @@ bool before_syscall_open_char(int, int, const char *, const char *, const char *
extern char sandbox_lib[SB_PATH_MAX];
extern volatile bool sandbox_on;
+__attribute__((__format__(__printf__, 1, 2))) void sb_eqawarn(const char *format, ...);
void sb_dump_backtrace(void);
/* glibc modified realpath() function */
diff --git a/libsandbox/wrapper-funcs/__wrapper_exec.c b/libsandbox/wrapper-funcs/__wrapper_exec.c
index e007ac8..98e0dae 100644
--- a/libsandbox/wrapper-funcs/__wrapper_exec.c
+++ b/libsandbox/wrapper-funcs/__wrapper_exec.c
@@ -20,7 +20,32 @@ static WRAPPER_RET_TYPE (*WRAPPER_TRUE_NAME)(WRAPPER_ARGS_PROTO) = NULL;
#ifndef SB_EXEC_COMMON
#define SB_EXEC_COMMON
-static FILE *tty_fp = NULL;
+static char *flatten_args(char *const argv[])
+{
+ char *ret;
+ size_t i, len;
+
+ len = 1;
+ for (i = 0; argv[i]; ++i) {
+ len += strlen(argv[i]) + 1;
+ if (strchr(argv[i], ' '))
+ len += 2;
+ }
+
+ ret = xmalloc(len);
+ ret[0] = '\0';
+ for (i = 0; argv[i]; ++i) {
+ if (strchr(argv[i], ' ')) {
+ strcat(ret, "'");
+ strcat(ret, argv[i]);
+ strcat(ret, "'");
+ } else
+ strcat(ret, argv[i]);
+ strcat(ret, " ");
+ }
+
+ return ret;
+}
/* See to see if this an ELF and if so, is it static which we can't wrap */
static void sb_check_exec(const char *filename, char *const argv[])
@@ -29,20 +54,21 @@ static void sb_check_exec(const char *filename, char *const argv[])
unsigned char *elf;
struct stat st;
- if (!tty_fp)
- tty_fp = fopen("/dev/tty", "ae");
- if (!tty_fp)
- return;
-
#ifdef __linux__
- /* Filter some common safe static things */
+ /* Filter some common safe static things ...
+ * Should make a whitelist system for this ...
+ */
if (!strncmp(argv[0], "/lib", 4) && strstr(argv[0], ".so.")) {
/* Packages often run `ldd /some/binary` which will in
* turn run `/lib/ld-linux.so.2 --verify /some/binary`
*/
if (!strcmp(argv[1], "--verify"))
return;
- }
+
+ } else if (argv[1] && !strcmp(argv[1], "prelink") &&
+ argv[2] && !strcmp(argv[2], "--version"))
+ /* Portage likes to run `prelink --version` */
+ return;
#endif
fd = open(filename, O_RDONLY);
@@ -82,19 +108,9 @@ static void sb_check_exec(const char *filename, char *const argv[])
else
PARSE_ELF(64);
- /* Write to tty_fd because stderr is not always 100% safe. If running
- * tests and validating output, this may break things. #261957
- * Writing to /dev/tty directly might annoy some people ... perhaps
- * we should attempt to hijack the log fd from portage ...
- */
- sb_fprintf(tty_fp, "QA: Static ELF: %s: ", filename);
- size_t i;
- for (i = 0; argv[i]; ++i)
- if (strchr(argv[i], ' '))
- sb_fprintf(tty_fp, "'%s' ", argv[i]);
- else
- sb_fprintf(tty_fp, "%s ", argv[i]);
- sb_fprintf(tty_fp, "\n");
+ char *args = flatten_args(argv);
+ sb_eqawarn("Static ELF: %s: %s\n", filename, args);
+ free(args);
done:
diff --git a/libsandbox/wrappers.h b/libsandbox/wrappers.h
index 22b073b..fddbe1b 100644
--- a/libsandbox/wrappers.h
+++ b/libsandbox/wrappers.h
@@ -19,5 +19,7 @@ attribute_hidden int sb_unwrapped_access (const char *, int);
attribute_hidden char *sb_unwrapped_getcwd (char *, size_t);
#define sb_unwrapped_open sb_unwrapped_open_DEFAULT
attribute_hidden int sb_unwrapped_open (const char *, int, mode_t);
+#define sb_unwrapped_popen sb_unwrapped_popen_DEFAULT
+attribute_hidden FILE *sb_unwrapped_popen (const char *, const char *);
#endif