/* Copyright (c) 2012 The Chromium OS Authors. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include <signal.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include "signal_handler.h" #include "util.h" /* * si_syscall was added in glibc-2.17+, but Android still uses glibc-2.15 * for its prebuilt binary host toolchains. Add a compat hack for it. */ static int get_si_syscall(const siginfo_t *info) { #if defined(si_syscall) return info->si_syscall; #endif typedef struct { void *ip; int nr; unsigned int arch; } local_siginfo_t; union { const siginfo_t *info; const local_siginfo_t *local_info; } local_info = { .info = info, }; return local_info.local_info->nr; } void log_sigsys_handler(int sig attribute_unused, siginfo_t *info, void *void_context attribute_unused) { const char *syscall_name; int nr = get_si_syscall(info); syscall_name = lookup_syscall_name(nr); if (syscall_name) die("blocked syscall: %s", syscall_name); else die("blocked syscall: %d", nr); /* * We trapped on a syscall that should have killed the process. * This should never ever return, but we're paranoid. */ for (;;) _exit(1); } int install_sigsys_handler() { int ret = 0; struct sigaction act; sigset_t mask; memset(&act, 0, sizeof(act)); act.sa_sigaction = &log_sigsys_handler; act.sa_flags = SA_SIGINFO; sigemptyset(&mask); sigaddset(&mask, SIGSYS); ret = sigaction(SIGSYS, &act, NULL); if (ret < 0) return ret; ret = sigprocmask(SIG_UNBLOCK, &mask, NULL); if (ret < 0) return ret; return 0; }