Loading changes/bug11465 0 → 100644 +9 −0 Original line number Diff line number Diff line o Minor features: - When the Linux syscall sandbox finds an illegal system call, it now tries to log a stack trace before exiting. Resolves ticket 11465. o Minor bugfixes: - Using the Linux syscall sandbox no longer prevents stack-trace logging on crashes or errors. Fixes part 11465; bugfix on 0.2.5.1-alpha. src/common/backtrace.c +16 −2 Original line number Diff line number Diff line Loading @@ -5,7 +5,6 @@ #define _GNU_SOURCE 1 #include "orconfig.h" #include "backtrace.h" #include "compat.h" #include "util.h" #include "torlog.h" Loading @@ -31,6 +30,9 @@ #include <ucontext.h> #endif #define EXPOSE_CLEAN_BACKTRACE #include "backtrace.h" #if defined(HAVE_EXECINFO_H) && defined(HAVE_BACKTRACE) && \ defined(HAVE_BACKTRACE_SYMBOLS_FD) && defined(HAVE_SIGACTION) #define USE_BACKTRACE Loading Loading @@ -59,7 +61,7 @@ static tor_mutex_t cb_buf_mutex; * onto the stack. Fortunately, we usually have the program counter in the * ucontext_t structure. */ static void void clean_backtrace(void **stack, int depth, const ucontext_t *ctx) { #ifdef PC_FROM_UCONTEXT Loading Loading @@ -165,6 +167,18 @@ install_bt_handler(void) rv = -1; } } { /* Now, generate (but do not log) a backtrace. This ensures that * libc has pre-loaded the symbols we need to dump things, so that later * reads won't be denied by the sandbox code */ char **symbols; int depth = backtrace(cb_buf, MAX_DEPTH); symbols = backtrace_symbols(cb_buf, depth); if (symbols) free(symbols); } return rv; } Loading src/common/backtrace.h +6 −0 Original line number Diff line number Diff line Loading @@ -4,9 +4,15 @@ #ifndef TOR_BACKTRACE_H #define TOR_BACKTRACE_H #include "orconfig.h" void log_backtrace(int severity, int domain, const char *msg); int configure_backtrace_handler(const char *tor_version); void clean_up_backtrace_handler(void); #ifdef EXPOSE_CLEAN_BACKTRACE void clean_backtrace(void **stack, int depth, const ucontext_t *ctx); #endif #endif src/common/sandbox.c +36 −0 Original line number Diff line number Diff line Loading @@ -56,6 +56,17 @@ #include <time.h> #include <poll.h> #if defined(HAVE_EXECINFO_H) && defined(HAVE_BACKTRACE) && \ defined(HAVE_BACKTRACE_SYMBOLS_FD) && defined(HAVE_SIGACTION) #define USE_BACKTRACE #define EXPOSE_CLEAN_BACKTRACE #include "backtrace.h" #endif #ifdef USE_BACKTRACE #include <execinfo.h> #endif /**Determines if at least one sandbox is active.*/ static int sandbox_active = 0; /** Holds the parameter list configuration for the sandbox.*/ Loading Loading @@ -119,6 +130,7 @@ static int filter_nopar_gen[] = { SCMP_SYS(stat), SCMP_SYS(uname), SCMP_SYS(write), SCMP_SYS(writev), SCMP_SYS(exit_group), SCMP_SYS(exit), Loading Loading @@ -1307,6 +1319,11 @@ install_syscall_filter(sandbox_cfg_t* cfg) return (rc < 0 ? -rc : rc); } #ifdef USE_BACKTRACE #define MAX_DEPTH 256 static void *syscall_cb_buf[MAX_DEPTH]; #endif /** * Function called when a SIGSYS is caught by the application. It notifies the * user that an error has occurred and either terminates or allows the Loading @@ -1318,6 +1335,12 @@ sigsys_debugging(int nr, siginfo_t *info, void *void_context) ucontext_t *ctx = (ucontext_t *) (void_context); char number[32]; int syscall; #ifdef USE_BACKTRACE int depth; int n_fds, i; const int *fds = NULL; #endif (void) nr; if (info->si_code != SYS_SECCOMP) Loading @@ -1328,12 +1351,25 @@ sigsys_debugging(int nr, siginfo_t *info, void *void_context) syscall = (int) ctx->uc_mcontext.gregs[REG_SYSCALL]; #ifdef USE_BACKTRACE depth = backtrace(syscall_cb_buf, MAX_DEPTH); /* Clean up the top stack frame so we get the real function * name for the most recently failing function. */ clean_backtrace(syscall_cb_buf, depth, ctx); #endif format_dec_number_sigsafe(syscall, number, sizeof(number)); tor_log_err_sigsafe("(Sandbox) Caught a bad syscall attempt (syscall ", number, ")\n", NULL); #ifdef USE_BACKTRACE n_fds = tor_log_get_sigsafe_err_fds(&fds); for (i=0; i < n_fds; ++i) backtrace_symbols_fd(syscall_cb_buf, depth, fds[i]); #endif #if defined(DEBUGGING_CLOSE) _exit(1); #endif // DEBUGGING_CLOSE Loading Loading
changes/bug11465 0 → 100644 +9 −0 Original line number Diff line number Diff line o Minor features: - When the Linux syscall sandbox finds an illegal system call, it now tries to log a stack trace before exiting. Resolves ticket 11465. o Minor bugfixes: - Using the Linux syscall sandbox no longer prevents stack-trace logging on crashes or errors. Fixes part 11465; bugfix on 0.2.5.1-alpha.
src/common/backtrace.c +16 −2 Original line number Diff line number Diff line Loading @@ -5,7 +5,6 @@ #define _GNU_SOURCE 1 #include "orconfig.h" #include "backtrace.h" #include "compat.h" #include "util.h" #include "torlog.h" Loading @@ -31,6 +30,9 @@ #include <ucontext.h> #endif #define EXPOSE_CLEAN_BACKTRACE #include "backtrace.h" #if defined(HAVE_EXECINFO_H) && defined(HAVE_BACKTRACE) && \ defined(HAVE_BACKTRACE_SYMBOLS_FD) && defined(HAVE_SIGACTION) #define USE_BACKTRACE Loading Loading @@ -59,7 +61,7 @@ static tor_mutex_t cb_buf_mutex; * onto the stack. Fortunately, we usually have the program counter in the * ucontext_t structure. */ static void void clean_backtrace(void **stack, int depth, const ucontext_t *ctx) { #ifdef PC_FROM_UCONTEXT Loading Loading @@ -165,6 +167,18 @@ install_bt_handler(void) rv = -1; } } { /* Now, generate (but do not log) a backtrace. This ensures that * libc has pre-loaded the symbols we need to dump things, so that later * reads won't be denied by the sandbox code */ char **symbols; int depth = backtrace(cb_buf, MAX_DEPTH); symbols = backtrace_symbols(cb_buf, depth); if (symbols) free(symbols); } return rv; } Loading
src/common/backtrace.h +6 −0 Original line number Diff line number Diff line Loading @@ -4,9 +4,15 @@ #ifndef TOR_BACKTRACE_H #define TOR_BACKTRACE_H #include "orconfig.h" void log_backtrace(int severity, int domain, const char *msg); int configure_backtrace_handler(const char *tor_version); void clean_up_backtrace_handler(void); #ifdef EXPOSE_CLEAN_BACKTRACE void clean_backtrace(void **stack, int depth, const ucontext_t *ctx); #endif #endif
src/common/sandbox.c +36 −0 Original line number Diff line number Diff line Loading @@ -56,6 +56,17 @@ #include <time.h> #include <poll.h> #if defined(HAVE_EXECINFO_H) && defined(HAVE_BACKTRACE) && \ defined(HAVE_BACKTRACE_SYMBOLS_FD) && defined(HAVE_SIGACTION) #define USE_BACKTRACE #define EXPOSE_CLEAN_BACKTRACE #include "backtrace.h" #endif #ifdef USE_BACKTRACE #include <execinfo.h> #endif /**Determines if at least one sandbox is active.*/ static int sandbox_active = 0; /** Holds the parameter list configuration for the sandbox.*/ Loading Loading @@ -119,6 +130,7 @@ static int filter_nopar_gen[] = { SCMP_SYS(stat), SCMP_SYS(uname), SCMP_SYS(write), SCMP_SYS(writev), SCMP_SYS(exit_group), SCMP_SYS(exit), Loading Loading @@ -1307,6 +1319,11 @@ install_syscall_filter(sandbox_cfg_t* cfg) return (rc < 0 ? -rc : rc); } #ifdef USE_BACKTRACE #define MAX_DEPTH 256 static void *syscall_cb_buf[MAX_DEPTH]; #endif /** * Function called when a SIGSYS is caught by the application. It notifies the * user that an error has occurred and either terminates or allows the Loading @@ -1318,6 +1335,12 @@ sigsys_debugging(int nr, siginfo_t *info, void *void_context) ucontext_t *ctx = (ucontext_t *) (void_context); char number[32]; int syscall; #ifdef USE_BACKTRACE int depth; int n_fds, i; const int *fds = NULL; #endif (void) nr; if (info->si_code != SYS_SECCOMP) Loading @@ -1328,12 +1351,25 @@ sigsys_debugging(int nr, siginfo_t *info, void *void_context) syscall = (int) ctx->uc_mcontext.gregs[REG_SYSCALL]; #ifdef USE_BACKTRACE depth = backtrace(syscall_cb_buf, MAX_DEPTH); /* Clean up the top stack frame so we get the real function * name for the most recently failing function. */ clean_backtrace(syscall_cb_buf, depth, ctx); #endif format_dec_number_sigsafe(syscall, number, sizeof(number)); tor_log_err_sigsafe("(Sandbox) Caught a bad syscall attempt (syscall ", number, ")\n", NULL); #ifdef USE_BACKTRACE n_fds = tor_log_get_sigsafe_err_fds(&fds); for (i=0; i < n_fds; ++i) backtrace_symbols_fd(syscall_cb_buf, depth, fds[i]); #endif #if defined(DEBUGGING_CLOSE) _exit(1); #endif // DEBUGGING_CLOSE Loading