xref: /aosp_15_r20/external/minijail/signal_handler.c (revision 4b9c6d91573e8b3a96609339b46361b5476dd0f9)
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