1*4b9c6d91SCole Faust /* Copyright 2012 The ChromiumOS Authors
2*4b9c6d91SCole Faust * Use of this source code is governed by a BSD-style license that can be
3*4b9c6d91SCole Faust * found in the LICENSE file.
4*4b9c6d91SCole Faust */
5*4b9c6d91SCole Faust
6*4b9c6d91SCole Faust #include <signal.h>
7*4b9c6d91SCole Faust #include <stdlib.h>
8*4b9c6d91SCole Faust #include <string.h>
9*4b9c6d91SCole Faust #include <unistd.h>
10*4b9c6d91SCole Faust
11*4b9c6d91SCole Faust #include "signal_handler.h"
12*4b9c6d91SCole Faust
13*4b9c6d91SCole Faust #include "util.h"
14*4b9c6d91SCole Faust
15*4b9c6d91SCole Faust /*
16*4b9c6d91SCole Faust * si_syscall was added in glibc-2.17+, but Android still uses glibc-2.15
17*4b9c6d91SCole Faust * for its prebuilt binary host toolchains. Add a compat hack for it.
18*4b9c6d91SCole Faust */
get_si_syscall(const siginfo_t * info)19*4b9c6d91SCole Faust static int get_si_syscall(const siginfo_t *info)
20*4b9c6d91SCole Faust {
21*4b9c6d91SCole Faust #if defined(si_syscall)
22*4b9c6d91SCole Faust return info->si_syscall;
23*4b9c6d91SCole Faust #endif
24*4b9c6d91SCole Faust
25*4b9c6d91SCole Faust typedef struct {
26*4b9c6d91SCole Faust void *ip;
27*4b9c6d91SCole Faust int nr;
28*4b9c6d91SCole Faust unsigned int arch;
29*4b9c6d91SCole Faust } local_siginfo_t;
30*4b9c6d91SCole Faust
31*4b9c6d91SCole Faust union {
32*4b9c6d91SCole Faust const siginfo_t *info;
33*4b9c6d91SCole Faust const local_siginfo_t *local_info;
34*4b9c6d91SCole Faust } local_info = {
35*4b9c6d91SCole Faust .info = info,
36*4b9c6d91SCole Faust };
37*4b9c6d91SCole Faust return local_info.local_info->nr;
38*4b9c6d91SCole Faust }
39*4b9c6d91SCole Faust
log_sigsys_handler(int sig attribute_unused,siginfo_t * info,void * void_context attribute_unused)40*4b9c6d91SCole Faust void log_sigsys_handler(int sig attribute_unused, siginfo_t *info,
41*4b9c6d91SCole Faust void *void_context attribute_unused)
42*4b9c6d91SCole Faust {
43*4b9c6d91SCole Faust const char *syscall_name;
44*4b9c6d91SCole Faust int nr = get_si_syscall(info);
45*4b9c6d91SCole Faust syscall_name = lookup_syscall_name(nr);
46*4b9c6d91SCole Faust
47*4b9c6d91SCole Faust if (syscall_name)
48*4b9c6d91SCole Faust die("blocked syscall: %s", syscall_name);
49*4b9c6d91SCole Faust else
50*4b9c6d91SCole Faust die("blocked syscall: %d", nr);
51*4b9c6d91SCole Faust
52*4b9c6d91SCole Faust /*
53*4b9c6d91SCole Faust * We trapped on a syscall that should have killed the process.
54*4b9c6d91SCole Faust * This should never ever return, but we're paranoid.
55*4b9c6d91SCole Faust */
56*4b9c6d91SCole Faust for (;;)
57*4b9c6d91SCole Faust _exit(1);
58*4b9c6d91SCole Faust }
59*4b9c6d91SCole Faust
install_sigsys_handler()60*4b9c6d91SCole Faust int install_sigsys_handler()
61*4b9c6d91SCole Faust {
62*4b9c6d91SCole Faust int ret = 0;
63*4b9c6d91SCole Faust struct sigaction act;
64*4b9c6d91SCole Faust sigset_t mask;
65*4b9c6d91SCole Faust
66*4b9c6d91SCole Faust memset(&act, 0, sizeof(act));
67*4b9c6d91SCole Faust act.sa_sigaction = &log_sigsys_handler;
68*4b9c6d91SCole Faust act.sa_flags = SA_SIGINFO;
69*4b9c6d91SCole Faust
70*4b9c6d91SCole Faust sigemptyset(&mask);
71*4b9c6d91SCole Faust sigaddset(&mask, SIGSYS);
72*4b9c6d91SCole Faust
73*4b9c6d91SCole Faust ret = sigaction(SIGSYS, &act, NULL);
74*4b9c6d91SCole Faust if (ret < 0)
75*4b9c6d91SCole Faust return ret;
76*4b9c6d91SCole Faust
77*4b9c6d91SCole Faust ret = sigprocmask(SIG_UNBLOCK, &mask, NULL);
78*4b9c6d91SCole Faust if (ret < 0)
79*4b9c6d91SCole Faust return ret;
80*4b9c6d91SCole Faust
81*4b9c6d91SCole Faust return 0;
82*4b9c6d91SCole Faust }
83