• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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