mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-14 07:03:44 +01:00
Log a backtrace when the sandbox finds a failure
This involves some duplicate code between backtrace.c and sandbox.c, but I don't see a way around it: calling more functions would mean adding more steps to our call stack, and running clean_backtrace() against the wrong point on the stack.
This commit is contained in:
parent
196895ed7e
commit
cc9e86db61
@ -5,7 +5,6 @@
|
|||||||
#define _GNU_SOURCE 1
|
#define _GNU_SOURCE 1
|
||||||
|
|
||||||
#include "orconfig.h"
|
#include "orconfig.h"
|
||||||
#include "backtrace.h"
|
|
||||||
#include "compat.h"
|
#include "compat.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "torlog.h"
|
#include "torlog.h"
|
||||||
@ -31,6 +30,9 @@
|
|||||||
#include <ucontext.h>
|
#include <ucontext.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define EXPOSE_CLEAN_BACKTRACE
|
||||||
|
#include "backtrace.h"
|
||||||
|
|
||||||
#if defined(HAVE_EXECINFO_H) && defined(HAVE_BACKTRACE) && \
|
#if defined(HAVE_EXECINFO_H) && defined(HAVE_BACKTRACE) && \
|
||||||
defined(HAVE_BACKTRACE_SYMBOLS_FD) && defined(HAVE_SIGACTION)
|
defined(HAVE_BACKTRACE_SYMBOLS_FD) && defined(HAVE_SIGACTION)
|
||||||
#define USE_BACKTRACE
|
#define USE_BACKTRACE
|
||||||
@ -59,7 +61,7 @@ static tor_mutex_t cb_buf_mutex;
|
|||||||
* onto the stack. Fortunately, we usually have the program counter in the
|
* onto the stack. Fortunately, we usually have the program counter in the
|
||||||
* ucontext_t structure.
|
* ucontext_t structure.
|
||||||
*/
|
*/
|
||||||
static void
|
void
|
||||||
clean_backtrace(void **stack, int depth, const ucontext_t *ctx)
|
clean_backtrace(void **stack, int depth, const ucontext_t *ctx)
|
||||||
{
|
{
|
||||||
#ifdef PC_FROM_UCONTEXT
|
#ifdef PC_FROM_UCONTEXT
|
||||||
@ -165,6 +167,18 @@ install_bt_handler(void)
|
|||||||
rv = -1;
|
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;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,9 +4,15 @@
|
|||||||
#ifndef TOR_BACKTRACE_H
|
#ifndef TOR_BACKTRACE_H
|
||||||
#define TOR_BACKTRACE_H
|
#define TOR_BACKTRACE_H
|
||||||
|
|
||||||
|
#include "orconfig.h"
|
||||||
|
|
||||||
void log_backtrace(int severity, int domain, const char *msg);
|
void log_backtrace(int severity, int domain, const char *msg);
|
||||||
int configure_backtrace_handler(const char *tor_version);
|
int configure_backtrace_handler(const char *tor_version);
|
||||||
void clean_up_backtrace_handler(void);
|
void clean_up_backtrace_handler(void);
|
||||||
|
|
||||||
|
#ifdef EXPOSE_CLEAN_BACKTRACE
|
||||||
|
void clean_backtrace(void **stack, int depth, const ucontext_t *ctx);
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -56,6 +56,17 @@
|
|||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <poll.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.*/
|
/**Determines if at least one sandbox is active.*/
|
||||||
static int sandbox_active = 0;
|
static int sandbox_active = 0;
|
||||||
/** Holds the parameter list configuration for the sandbox.*/
|
/** Holds the parameter list configuration for the sandbox.*/
|
||||||
@ -1308,6 +1319,11 @@ install_syscall_filter(sandbox_cfg_t* cfg)
|
|||||||
return (rc < 0 ? -rc : rc);
|
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
|
* 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
|
* user that an error has occurred and either terminates or allows the
|
||||||
@ -1319,6 +1335,12 @@ sigsys_debugging(int nr, siginfo_t *info, void *void_context)
|
|||||||
ucontext_t *ctx = (ucontext_t *) (void_context);
|
ucontext_t *ctx = (ucontext_t *) (void_context);
|
||||||
char number[32];
|
char number[32];
|
||||||
int syscall;
|
int syscall;
|
||||||
|
#ifdef USE_BACKTRACE
|
||||||
|
int depth;
|
||||||
|
int n_fds, i;
|
||||||
|
const int *fds = NULL;
|
||||||
|
#endif
|
||||||
|
|
||||||
(void) nr;
|
(void) nr;
|
||||||
|
|
||||||
if (info->si_code != SYS_SECCOMP)
|
if (info->si_code != SYS_SECCOMP)
|
||||||
@ -1329,12 +1351,25 @@ sigsys_debugging(int nr, siginfo_t *info, void *void_context)
|
|||||||
|
|
||||||
syscall = (int) ctx->uc_mcontext.gregs[REG_SYSCALL];
|
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));
|
format_dec_number_sigsafe(syscall, number, sizeof(number));
|
||||||
tor_log_err_sigsafe("(Sandbox) Caught a bad syscall attempt (syscall ",
|
tor_log_err_sigsafe("(Sandbox) Caught a bad syscall attempt (syscall ",
|
||||||
number,
|
number,
|
||||||
")\n",
|
")\n",
|
||||||
NULL);
|
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)
|
#if defined(DEBUGGING_CLOSE)
|
||||||
_exit(1);
|
_exit(1);
|
||||||
#endif // DEBUGGING_CLOSE
|
#endif // DEBUGGING_CLOSE
|
||||||
|
Loading…
Reference in New Issue
Block a user