aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'libsandbox/libsandbox.c')
-rw-r--r--libsandbox/libsandbox.c139
1 files changed, 25 insertions, 114 deletions
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;
}