summaryrefslogtreecommitdiffstats
path: root/sandbox/linux/seccomp/debug.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sandbox/linux/seccomp/debug.cc')
-rw-r--r--sandbox/linux/seccomp/debug.cc363
1 files changed, 0 insertions, 363 deletions
diff --git a/sandbox/linux/seccomp/debug.cc b/sandbox/linux/seccomp/debug.cc
deleted file mode 100644
index 5d6de49..0000000
--- a/sandbox/linux/seccomp/debug.cc
+++ /dev/null
@@ -1,363 +0,0 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef NDEBUG
-
-#include "debug.h"
-
-namespace playground {
-
-bool Debug::enabled_;
-int Debug::numSyscallNames_;
-const char **Debug::syscallNames_;
-std::map<int, std::string> Debug::syscallNamesMap_;
-
-Debug Debug::debug_;
-
-Debug::Debug() {
- // Logging is disabled by default, but can be turned on by setting an
- // appropriate environment variable. Initialize this code from a global
- // constructor, so that it runs before the sandbox is turned on.
- enabled_ = !!getenv("SECCOMP_SANDBOX_DEBUGGING");
-
- // Read names of system calls from header files, if available. Symbolic
- // names make debugging so much nicer.
- if (enabled_) {
- static const char *filenames[] = {
- #if __WORDSIZE == 64
- "/usr/include/asm/unistd_64.h",
- #elif __WORDSIZE == 32
- "/usr/include/asm/unistd_32.h",
- #endif
- "/usr/include/asm/unistd.h",
- NULL };
- numSyscallNames_ = 0;
- for (const char **fn = filenames; *fn; ++fn) {
- FILE *fp = fopen(*fn, "r");
- if (fp) {
- std::string baseName;
- int baseNum = -1;
- char buf[80];
- while (fgets(buf, sizeof(buf), fp)) {
- // Check if the line starts with "#define"
- static const char* whitespace = " \t\r\n";
- char *token, *save;
- token = strtok_r(buf, whitespace, &save);
- if (token && !strcmp(token, "#define")) {
-
- // Only parse identifiers that start with "__NR_"
- token = strtok_r(NULL, whitespace, &save);
- if (token) {
- if (strncmp(token, "__NR_", 5)) {
- continue;
- }
- std::string syscallName(token + 5);
-
- // Parse the value of the symbol. Try to be forgiving in what
- // we accept, as the file format might change over time.
- token = strtok_r(NULL, "\r\n", &save);
- if (token) {
- // Some values are defined relative to previous values, we
- // detect these examples by finding an earlier symbol name
- // followed by a '+' plus character.
- bool isRelative = false;
- char *base = strstr(token, baseName.c_str());
- if (baseNum >= 0 && base) {
- base += baseName.length();
- while (*base == ' ' || *base == '\t') {
- ++base;
- }
- if (*base == '+') {
- isRelative = true;
- token = base;
- }
- }
-
- // Skip any characters that are not part of the syscall number.
- while (*token < '0' || *token > '9') {
- token++;
- }
-
- // If we now have a valid datum, enter it into our map.
- if (*token) {
- int sysnum = atoi(token);
-
- // Deal with symbols that are defined relative to earlier
- // ones.
- if (isRelative) {
- sysnum += baseNum;
- } else {
- baseNum = sysnum;
- baseName = syscallName;
- }
-
- // Keep track of the highest syscall number that we know
- // about.
- if (sysnum >= numSyscallNames_) {
- numSyscallNames_ = sysnum + 1;
- }
-
- syscallNamesMap_[sysnum] = syscallName;
- }
- }
- }
- }
- }
- fclose(fp);
- break;
- }
- }
- if (numSyscallNames_) {
- // We cannot make system calls at the time, when we are looking up
- // the names. So, copy them into a data structure that can be
- // accessed without having to allocated memory (i.e. no more STL).
- syscallNames_ = reinterpret_cast<const char **>(
- calloc(sizeof(char *), numSyscallNames_));
- for (std::map<int, std::string>::const_iterator iter =
- syscallNamesMap_.begin();
- iter != syscallNamesMap_.end();
- ++iter) {
- syscallNames_[iter->first] = iter->second.c_str();
- }
- }
- }
-}
-
-bool Debug::enter() {
- // Increment the recursion level in TLS storage. This allows us to
- // make system calls from within our debugging functions, without triggering
- // additional debugging output.
- //
- // This function can be called from both the sandboxed process and from the
- // trusted process. Only the sandboxed process needs to worry about
- // recursively calling system calls. The trusted process doesn't intercept
- // system calls and thus doesn't have this problem. It also doesn't have
- // a TLS. We explicitly set the segment selector to zero, when in the
- // trusted process, so that we can avoid tracking recursion levels.
- int level;
- #if defined(__x86_64__)
- asm volatile("mov %%gs, %0\n"
- "test %0, %0\n"
- "jz 1f\n"
- "movl %%gs:0x1050-0xE0, %0\n"
- "incl %%gs:0x1050-0xE0\n"
- "1:\n"
- : "=r"(level)
- :
- : "memory");
- #elif defined(__i386__)
- asm volatile("mov %%fs, %0\n"
- "test %0, %0\n"
- "jz 1f\n"
- "movl %%fs:0x1034-0x58, %0\n"
- "incl %%fs:0x1034-0x58\n"
- "1:\n"
- : "=r"(level)
- :
- : "memory");
- #else
- #error "Unsupported target platform"
- #endif
- return !level;
-}
-
-bool Debug::leave() {
- // Decrement the recursion level in TLS storage. This allows us to
- // make system calls from within our debugging functions, without triggering
- // additional debugging output.
- //
- // This function can be called from both the sandboxed process and from the
- // trusted process. Only the sandboxed process needs to worry about
- // recursively calling system calls. The trusted process doesn't intercept
- // system calls and thus doesn't have this problem. It also doesn't have
- // a TLS. We explicitly set the segment selector to zero, when in the
- // trusted process, so that we can avoid tracking recursion levels.
- int level;
- #if defined(__x86_64__)
- asm volatile("mov %%gs, %0\n"
- "test %0, %0\n"
- "jz 1f\n"
- "decl %%gs:0x1050-0xE0\n"
- "movl %%gs:0x1050-0xE0, %0\n"
- "1:\n"
- : "=r"(level)
- :
- : "memory");
- #elif defined(__i386__)
- asm volatile("mov %%fs, %0\n"
- "test %0, %0\n"
- "jz 1f\n"
- "decl %%fs:0x1034-0x58\n"
- "movl %%fs:0x1034-0x58, %0\n"
- "1:\n"
- : "=r"(level)
- :
- : "memory");
- #else
- #error Unsupported target platform
- #endif
- return !level;
-}
-
-void Debug::_message(const char* msg) {
- if (enabled_) {
- Sandbox::SysCalls sys;
- size_t len = strlen(msg);
- if (len && msg[len-1] != '\n') {
- // Write operations should be atomic, so that we don't interleave
- // messages from multiple threads. Append a newline, if it is not
- // already there.
- char copy[len + 1];
- memcpy(copy, msg, len);
- copy[len] = '\n';
- Sandbox::write(sys, 2, copy, len + 1);
- } else {
- Sandbox::write(sys, 2, msg, len);
- }
- }
-}
-
-void Debug::message(const char* msg) {
- if (enabled_) {
- if (enter()) {
- _message(msg);
- }
- leave();
- }
-}
-
-void Debug::gettimeofday(long long* tm) {
- if (tm) {
- struct timeval tv;
- #if defined(__i386__)
- // Zero out the lastSyscallNum, so that we don't try to coalesce
- // calls to gettimeofday(). For debugging purposes, we need the
- // exact time.
- asm volatile("movl $0, %fs:0x102C-0x58");
- #elif !defined(__x86_64__)
- #error Unsupported target platform
- #endif
- ::gettimeofday(&tv, NULL);
- *tm = 1000ULL*1000ULL*static_cast<unsigned>(tv.tv_sec) +
- static_cast<unsigned>(tv.tv_usec);
- }
-}
-
-void Debug::syscall(long long* tm, int sysnum, const char* msg, int call) {
- // This function gets called from the system call wrapper. Avoid calling
- // any library functions that themselves need system calls.
- if (enabled_) {
- if (enter() || !tm) {
- gettimeofday(tm);
-
- const char *sysname = NULL;
- if (sysnum >= 0 && sysnum < numSyscallNames_) {
- sysname = syscallNames_[sysnum];
- }
- static const char kUnnamedMessage[] = "Unnamed syscall #";
- char unnamed[40];
- if (!sysname) {
- memcpy(unnamed, kUnnamedMessage, sizeof(kUnnamedMessage) - 1);
- itoa(unnamed + sizeof(kUnnamedMessage) - 1, sysnum);
- sysname = unnamed;
- }
- #if defined(__NR_socketcall) || defined(__NR_ipc)
- char extra[40];
- *extra = '\000';
- #if defined(__NR_socketcall)
- if (sysnum == __NR_socketcall) {
- static const char* socketcall_name[] = {
- 0, "socket", "bind", "connect", "listen", "accept", "getsockname",
- "getpeername", "socketpair", "send", "recv", "sendto","recvfrom",
- "shutdown", "setsockopt", "getsockopt", "sendmsg", "recvmsg",
- "accept4"
- };
- if (call >= 1 &&
- call < (int)(sizeof(socketcall_name)/sizeof(char *))) {
- strcat(strcpy(extra, " "), socketcall_name[call]);
- } else {
- itoa(strcpy(extra, " #") + 2, call);
- }
- }
- #endif
- #if defined(__NR_ipc)
- if (sysnum == __NR_ipc) {
- static const char* ipc_name[] = {
- 0, "semop", "semget", "semctl", "semtimedop", 0, 0, 0, 0, 0, 0,
- "msgsnd", "msgrcv", "msgget", "msgctl", 0, 0, 0, 0, 0, 0,
- "shmat", "shmdt", "shmget", "shmctl" };
- if (call >= 1 && call < (int)(sizeof(ipc_name)/sizeof(char *)) &&
- ipc_name[call]) {
- strcat(strcpy(extra, " "), ipc_name[call]);
- } else {
- itoa(strcpy(extra, " #") + 2, call);
- }
- }
- #endif
- #else
- static const char extra[1] = { 0 };
- #endif
- char buf[strlen(sysname) + strlen(extra) + (msg ? strlen(msg) : 0) + 4];
- strcat(strcat(strcat(strcat(strcpy(buf, sysname), extra), ": "),
- msg ? msg : ""), "\n");
- _message(buf);
- }
- leave();
- }
-}
-
-char* Debug::itoa(char* s, int n) {
- // Remember return value
- char *ret = s;
-
- // Insert sign for negative numbers
- if (n < 0) {
- *s++ = '-';
- n = -n;
- }
-
- // Convert to decimal (in reverse order)
- char *start = s;
- do {
- *s++ = '0' + (n % 10);
- n /= 10;
- } while (n);
- *s-- = '\000';
-
- // Reverse order of digits
- while (start < s) {
- char ch = *s;
- *s-- = *start;
- *start++ = ch;
- }
-
- return ret;
-}
-
-void Debug::elapsed(long long tm, int sysnum, int call) {
- if (enabled_) {
- if (enter()) {
- // Compute the time that has passed since the system call started.
- long long delta;
- gettimeofday(&delta);
- delta -= tm;
-
- // Format "Elapsed time: %d.%03dms" without using sprintf().
- char buf[80];
- itoa(strrchr(strcpy(buf, "Elapsed time: "), '\000'), delta/1000);
- delta %= 1000;
- strcat(buf, delta < 100 ? delta < 10 ? ".00" : ".0" : ".");
- itoa(strrchr(buf, '\000'), delta);
- strcat(buf, "ms");
-
- // Print system call name and elapsed time.
- syscall(NULL, sysnum, buf, call);
- }
- leave();
- }
-}
-
-} // namespace
-
-#endif // NDEBUG