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/* These header files need to be included before asm/siginfo.h such that
7 * pid_t, timer_t, and clock_t are defined. */
8#include <stdlib.h>
9#include <unistd.h>
10
11#include <asm/siginfo.h>
12#define __have_siginfo_t 1
13#define __have_sigval_t 1
14#define __have_sigevent_t 1
15
16#include <signal.h>
17#include <string.h>
18
19#include "signal_handler.h"
20
21#include "util.h"
22
23struct local_sigsys {
24	void		*ip;
25	int		nr;
26	unsigned int	arch;
27};
28
29void log_sigsys_handler(int nr, siginfo_t *info, void *void_context)
30{
31	struct local_sigsys sigsys;
32	const char *syscall_name;
33	memcpy(&sigsys, &info->_sifields, sizeof(sigsys));
34	syscall_name = lookup_syscall_name(sigsys.nr);
35
36	(void) void_context;
37
38	if (syscall_name)
39		die("blocked syscall: %s", syscall_name);
40	else
41		die("blocked syscall: %d", nr);
42
43	/*
44	 * We trapped on a syscall that should have killed the process.
45	 * This should never ever return, but we're paranoid.
46	 */
47	for (;;)
48		_exit(1);
49}
50
51int install_sigsys_handler()
52{
53	int ret = 0;
54	struct sigaction act;
55	sigset_t mask;
56
57	memset(&act, 0, sizeof(act));
58	act.sa_sigaction = &log_sigsys_handler;
59	act.sa_flags = SA_SIGINFO;
60
61	sigemptyset(&mask);
62	sigaddset(&mask, SIGSYS);
63
64	ret = sigaction(SIGSYS, &act, NULL);
65	if (ret < 0)
66		return ret;
67
68	ret = sigprocmask(SIG_UNBLOCK, &mask, NULL);
69	if (ret < 0)
70		return ret;
71
72	return 0;
73}
74