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