diff options
author | Mike Frysinger <vapier@gentoo.org> | 2009-03-14 13:27:20 -0400 |
---|---|---|
committer | Mike Frysinger <vapier@gentoo.org> | 2009-03-18 01:06:20 -0400 |
commit | f06150540e02b694ee87e89d61db8da95f42ed50 (patch) | |
tree | 3268a7cb4d1d31dd42d978c415ec677aa2017eba /libsandbox | |
parent | bump to sandbox-1.7 (diff) | |
download | sandbox-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.am | 1 | ||||
-rw-r--r-- | libsandbox/eqawarn.c | 49 | ||||
-rw-r--r-- | libsandbox/libsandbox.h | 1 | ||||
-rw-r--r-- | libsandbox/wrapper-funcs/__wrapper_exec.c | 58 | ||||
-rw-r--r-- | libsandbox/wrappers.h | 2 |
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 |