blob: 175c9ebf026b36c4cec877145b13877e3f74731c [file] [log] [blame]
Jorge Lucangeli Obesbda833c2012-07-31 16:25:56 -07001/* 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
Jorge Lucangeli Obesbda833c2012-07-31 16:25:56 -07006#include <signal.h>
Mike Frysingerb40895c2018-05-30 17:12:59 -04007#include <stdlib.h>
Jorge Lucangeli Obesbda833c2012-07-31 16:25:56 -07008#include <string.h>
Mike Frysingerb40895c2018-05-30 17:12:59 -04009#include <unistd.h>
Jorge Lucangeli Obesbda833c2012-07-31 16:25:56 -070010
Jorge Lucangeli Obesa21c8fc2015-07-15 16:22:34 -070011#include "signal_handler.h"
Jorge Lucangeli Obesbda833c2012-07-31 16:25:56 -070012
13#include "util.h"
14
Mike Frysingerb40895c2018-05-30 17:12:59 -040015/*
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 */
19static 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}
Jorge Lucangeli Obesbda833c2012-07-31 16:25:56 -070039
Mike Frysinger33d051a2018-05-30 16:41:10 -040040void log_sigsys_handler(int sig attribute_unused, siginfo_t *info,
Mike Frysingerd9ef07c2018-05-30 16:51:36 -040041 void *void_context attribute_unused)
Jorge Lucangeli Obesbda833c2012-07-31 16:25:56 -070042{
Jorge Lucangeli Obesbda833c2012-07-31 16:25:56 -070043 const char *syscall_name;
Mike Frysingerb40895c2018-05-30 17:12:59 -040044 int nr = get_si_syscall(info);
45 syscall_name = lookup_syscall_name(nr);
Jorge Lucangeli Obesbda833c2012-07-31 16:25:56 -070046
Jeff Vander Stoep00c57912016-02-03 15:48:06 -080047 if (syscall_name)
48 die("blocked syscall: %s", syscall_name);
49 else
Mike Frysingerb40895c2018-05-30 17:12:59 -040050 die("blocked syscall: %d", nr);
Jeff Vander Stoep00c57912016-02-03 15:48:06 -080051
Jorge Lucangeli Obesbda833c2012-07-31 16:25:56 -070052 /*
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
60int 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}