Index: experimental/webtry/syscall_reporter.cpp |
diff --git a/experimental/webtry/syscall_reporter.cpp b/experimental/webtry/syscall_reporter.cpp |
new file mode 100644 |
index 0000000000000000000000000000000000000000..1b7a49e5ab7f215e4e2a5d173cc713aa057b0aae |
--- /dev/null |
+++ b/experimental/webtry/syscall_reporter.cpp |
@@ -0,0 +1,110 @@ |
+/* |
jcgregorio
2014/04/09 14:10:31
Deleting this file.
|
+ * syscall reporting example for seccomp |
+ * |
+ * Copyright (c) 2012 The Chromium OS Authors <chromium-os-dev@chromium.org> |
+ * Authors: |
+ * Will Drewry <wad@chromium.org> |
+ * Kees Cook <keescook@chromium.org> |
+ * |
+ * Use of this source code is governed by a BSD-style license that can be |
+ * found in the LICENSE file. |
+ */ |
+#include <execinfo.h> |
+#include <map> |
+ |
+#include "syscall_reporter.h" |
+#include "syscall_names.h" |
+ |
+const char * const msg_needed = "Looks like you also need syscall: "; |
+ |
+/* Since "sprintf" is technically not signal-safe, reimplement %d here. */ |
mtklein
2014/04/08 19:00:23
Badass
|
+static void write_uint(char *buf, unsigned int val) |
+{ |
+ int width = 0; |
+ unsigned int tens; |
+ |
+ if (val == 0) { |
+ strcpy(buf, "0"); |
+ return; |
+ } |
+ for (tens = val; tens; tens /= 10) |
+ ++ width; |
+ buf[width] = '\0'; |
+ for (tens = val; tens; tens /= 10) |
+ buf[--width] = '0' + (tens % 10); |
+} |
+ |
+void tracer() { |
+ int j, nptrs; |
+#define SIZE 100 |
mtklein
2014/04/08 19:00:23
I'm getting the impression that this file was just
|
+ void *buffer[100]; |
+ char **strings; |
+ |
+ nptrs = backtrace(buffer, SIZE); |
+ printf("backtrace() returned %d addresses\n", nptrs); |
+ |
+ /* The call backtrace_symbols_fd(buffer, nptrs, STDOUT_FILENO) |
+ would produce similar output to the following: */ |
+ |
+ strings = backtrace_symbols(buffer, nptrs); |
+ if (strings == NULL) { |
+ perror("backtrace_symbols"); |
+ exit(EXIT_FAILURE); |
+ } |
+ |
+ for (j = 0; j < nptrs; j++) |
+ printf("%s\n", strings[j]); |
+ |
+ free(strings); |
+} |
+ |
+static void reporter(int nr, siginfo_t *info, void *void_context) |
+{ |
mtklein
2014/04/08 19:00:23
This code has some of the oddest formatting I've e
|
+ char buf[128]; |
+ ucontext_t *ctx = (ucontext_t *)(void_context); |
+ unsigned int syscall; |
+ if (info->si_code != SYS_SECCOMP) |
+ return; |
+ if (!ctx) |
+ return; |
+ syscall = ctx->uc_mcontext.gregs[REG_SYSCALL]; |
+ strcpy(buf, msg_needed); |
+ std::map<int, const char*>::iterator i; |
+ i = syscall_names.find(syscall); |
+ if (i != syscall_names.end()) { |
+ strcat(buf, syscall_names[syscall]); |
+ strcat(buf, "("); |
+ } else { |
+ strcat(buf, "Unknown call?!?"); |
+ } |
+ write_uint(buf + strlen(buf), syscall); |
+ if (i != syscall_names.end()) { |
+ strcat(buf, ")"); |
+ } |
+ strcat(buf, "\n"); |
+ int ret = write(STDOUT_FILENO, buf, strlen(buf)); |
mtklein
2014/04/08 19:00:23
WTF do these next 4 lines do?
|
+ tracer(); |
+ ret = ret; |
mtklein
2014/04/08 19:00:23
Particularly WTF. Is there some implicit register
|
+ _exit(1); |
+} |
+ |
+int install_syscall_reporter(void) { |
+ struct sigaction act; |
+ syscall_names_init(); |
+ sigset_t mask; |
+ memset(&act, 0, sizeof(act)); |
+ sigemptyset(&mask); |
+ sigaddset(&mask, SIGSYS); |
+ |
+ act.sa_sigaction = &reporter; |
+ act.sa_flags = SA_SIGINFO; |
+ if (sigaction(SIGSYS, &act, NULL) < 0) { |
+ perror("sigaction"); |
+ return -1; |
+ } |
+ if (sigprocmask(SIG_UNBLOCK, &mask, NULL)) { |
+ perror("sigprocmask"); |
+ return -1; |
+ } |
+ return 0; |
+} |