From 13590ca98ac2fd4939b683adbfdd63392b559f3f Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sat, 28 Nov 2015 14:58:01 +0100 Subject: Strip down procd to the necessary code, update copyright --- trace/trace.c | 225 ---------------------------------------------------------- 1 file changed, 225 deletions(-) delete mode 100644 trace/trace.c (limited to 'trace/trace.c') diff --git a/trace/trace.c b/trace/trace.c deleted file mode 100644 index b0005b8..0000000 --- a/trace/trace.c +++ /dev/null @@ -1,225 +0,0 @@ -/* - * Copyright (C) 2015 John Crispin - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 2.1 - * as published by the Free Software Foundation - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#define _GNU_SOURCE -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "../syscall-names.h" - -#define _offsetof(a, b) __builtin_offsetof(a,b) -#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) - -#ifdef __amd64__ -#define reg_syscall_nr _offsetof(struct user, regs.orig_rax) -#elif defined(__i386__) -#define reg_syscall_nr _offsetof(struct user, regs.orig_eax) -#elif defined(__mips) -# ifndef EF_REG2 -# define EF_REG2 8 -# endif -#define reg_syscall_nr (EF_REG2 / 4) -#elif defined(__arm__) -#define reg_syscall_nr _offsetof(struct user, regs.uregs[7]) -#else -#error tracing is not supported on this architecture -#endif - -#define INFO(fmt, ...) do { \ - fprintf(stderr, "utrace: "fmt, ## __VA_ARGS__); \ -} while (0) - -#define ERROR(fmt, ...) do { \ - syslog(LOG_ERR, "utrace: "fmt, ## __VA_ARGS__); \ - fprintf(stderr, "utrace: "fmt, ## __VA_ARGS__); \ -} while (0) - -static struct uloop_process tracer; -static int *syscall_count; -static struct blob_buf b; -static int syscall_max; -static int in_syscall; -static int debug; - -static int max_syscall = ARRAY_SIZE(syscall_names); - -static void set_syscall(const char *name, int val) -{ - int i; - - for (i = 0; i < max_syscall; i++) - if (syscall_names[i] && !strcmp(syscall_names[i], name)) { - syscall_count[i] = val; - return; - } -} - -static void print_syscalls(int policy, const char *json) -{ - void *c; - int i; - - set_syscall("rt_sigaction", 1); - set_syscall("sigreturn", 1); - set_syscall("rt_sigreturn", 1); - set_syscall("exit_group", 1); - set_syscall("exit", 1); - - blob_buf_init(&b, 0); - c = blobmsg_open_array(&b, "whitelist"); - - for (i = 0; i < ARRAY_SIZE(syscall_names); i++) { - if (!syscall_count[i]) - continue; - if (syscall_names[i]) { - if (debug) - printf("syscall %d (%s) was called %d times\n", - i, syscall_names[i], syscall_count[i]); - blobmsg_add_string(&b, NULL, syscall_names[i]); - } else { - ERROR("no name found for syscall(%d)\n", i); - } - } - blobmsg_close_array(&b, c); - blobmsg_add_u32(&b, "policy", policy); - if (json) { - FILE *fp = fopen(json, "w"); - if (fp) { - fprintf(fp, "%s", blobmsg_format_json_indent(b.head, true, 0)); - fclose(fp); - INFO("saving syscall trace to %s\n", json); - } else { - ERROR("failed to open %s\n", json); - } - } else { - printf("%s\n", - blobmsg_format_json_indent(b.head, true, 0)); - } - -} - -static void tracer_cb(struct uloop_process *c, int ret) -{ - if (WIFSTOPPED(ret) && WSTOPSIG(ret) & 0x80) { - if (!in_syscall) { - int syscall = ptrace(PTRACE_PEEKUSER, c->pid, reg_syscall_nr); - - if (syscall < syscall_max) { - syscall_count[syscall]++; - if (debug) - fprintf(stderr, "%s()\n", syscall_names[syscall]); - } else if (debug) { - fprintf(stderr, "syscal(%d)\n", syscall); - } - } - in_syscall = !in_syscall; - } else if (WIFEXITED(ret)) { - uloop_end(); - return; - } - ptrace(PTRACE_SYSCALL, c->pid, 0, 0); - uloop_process_add(&tracer); -} - -int main(int argc, char **argv, char **envp) -{ - char *json = NULL; - int status, ch, policy = EPERM; - pid_t child; - - while ((ch = getopt(argc, argv, "f:p:")) != -1) { - switch (ch) { - case 'f': - json = optarg; - break; - case 'p': - policy = atoi(optarg); - break; - } - } - - argc -= optind; - argv += optind; - - if (!argc) - return -1; - - if (getenv("TRACE_DEBUG")) - debug = 1; - unsetenv("TRACE_DEBUG"); - - child = fork(); - - if (child == 0) { - char **_argv = calloc(argc + 1, sizeof(char *)); - char **_envp; - char preload[] = "LD_PRELOAD=/lib/libpreload-trace.so"; - int envc = 1; - int ret; - - memcpy(_argv, argv, argc * sizeof(char *)); - - while (envp[envc++]) - ; - - _envp = calloc(envc, sizeof(char *)); - memcpy(&_envp[1], _envp, envc * sizeof(char *)); - *envp = preload; - - ret = execve(_argv[0], _argv, envp); - ERROR("failed to exec %s: %s\n", _argv[0], strerror(errno)); - return ret; - } - - if (child < 0) - return -1; - - syscall_max = ARRAY_SIZE(syscall_names); - syscall_count = calloc(syscall_max, sizeof(int)); - waitpid(child, &status, 0); - if (!WIFSTOPPED(status)) { - ERROR("failed to start %s\n", *argv); - return -1; - } - - ptrace(PTRACE_SETOPTIONS, child, 0, PTRACE_O_TRACESYSGOOD); - ptrace(PTRACE_SYSCALL, child, 0, 0); - - uloop_init(); - tracer.pid = child; - tracer.cb = tracer_cb; - uloop_process_add(&tracer); - uloop_run(); - uloop_done(); - - if (!json) - if (asprintf(&json, "/tmp/%s.%u.json", basename(*argv), child) < 0) - ERROR("failed to allocate output path: %s\n", strerror(errno)); - - print_syscalls(policy, json); - - return 0; -} -- cgit v1.2.3