static void test_sigsafe_err(void *arg) { const char *fn=get_fname("sigsafe_err_log"); char *content=NULL; log_severity_list_t include_bug; smartlist_t *lines = smartlist_new(); (void)arg; set_log_severity_config(LOG_WARN, LOG_ERR, &include_bug); init_logging(1); mark_logs_temp(); add_file_log(&include_bug, fn, 0); tor_log_update_sigsafe_err_fds(); close_temp_logs(); close(STDERR_FILENO); log_err(LD_BUG, "Say, this isn't too cool."); tor_log_err_sigsafe("Minimal.\n", NULL); set_log_time_granularity(100*1000); tor_log_err_sigsafe("Testing any ", "attempt to manually log ", "from a signal.\n", NULL); mark_logs_temp(); close_temp_logs(); close(STDERR_FILENO); content = read_file_to_str(fn, 0, NULL); tt_assert(content != NULL); tor_split_lines(lines, content, (int)strlen(content)); tt_int_op(smartlist_len(lines), OP_GE, 5); if (strstr(smartlist_get(lines, 0), "opening new log file")) smartlist_del_keeporder(lines, 0); tt_assert(strstr(smartlist_get(lines, 0), "Say, this isn't too cool")); /* Next line is blank. */ tt_assert(!strcmpstart(smartlist_get(lines, 1), "==============")); tt_assert(!strcmpstart(smartlist_get(lines, 2), "Minimal.")); /* Next line is blank. */ tt_assert(!strcmpstart(smartlist_get(lines, 3), "==============")); tt_str_op(smartlist_get(lines, 4), OP_EQ, "Testing any attempt to manually log from a signal."); done: tor_free(content); smartlist_free(lines); }
/** * 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 * application to continue execution, based on the DEBUGGING_CLOSE symbol. */ static void sigsys_debugging(int nr, siginfo_t *info, void *void_context) { ucontext_t *ctx = (ucontext_t *) (void_context); char number[32]; int syscall; (void) nr; if (info->si_code != SYS_SECCOMP) return; if (!ctx) return; syscall = ctx->uc_mcontext.gregs[REG_SYSCALL]; format_dec_number_sigsafe(syscall, number, sizeof(number)); tor_log_err_sigsafe("(Sandbox) Caught a bad syscall attempt (syscall ", number, ")\n", NULL); #if defined(DEBUGGING_CLOSE) _exit(1); #endif // DEBUGGING_CLOSE }
/** Signal handler: write a crash message with a stack trace, and die. */ static void crash_handler(int sig, siginfo_t *si, void *ctx_) { char buf[40]; int depth; ucontext_t *ctx = (ucontext_t *) ctx_; int n_fds, i; const int *fds = NULL; (void) si; depth = backtrace(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(cb_buf, depth, ctx); format_dec_number_sigsafe((unsigned)sig, buf, sizeof(buf)); tor_log_err_sigsafe(bt_version, " died: Caught signal ", buf, "\n", NULL); n_fds = tor_log_get_sigsafe_err_fds(&fds); for (i=0; i < n_fds; ++i) backtrace_symbols_fd(cb_buf, depth, fds[i]); abort(); }
/** * 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 * application to continue execution, based on the DEBUGGING_CLOSE symbol. */ static void sigsys_debugging(int nr, siginfo_t *info, void *void_context) { ucontext_t *ctx = (ucontext_t *) (void_context); const char *syscall_name; int syscall; #ifdef USE_BACKTRACE size_t depth; int n_fds, i; const int *fds = NULL; #endif (void) nr; if (info->si_code != SYS_SECCOMP) return; if (!ctx) return; syscall = (int) ctx->uc_mcontext.M_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 syscall_name = get_syscall_name(syscall); tor_log_err_sigsafe("(Sandbox) Caught a bad syscall attempt (syscall ", syscall_name, ")\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, (int)depth, fds[i]); #endif #if defined(DEBUGGING_CLOSE) _exit(1); #endif // DEBUGGING_CLOSE }