forked from SUNET/pkcs11-proxy
-
Notifications
You must be signed in to change notification settings - Fork 0
/
syscall-reporter.c
80 lines (74 loc) · 1.81 KB
/
syscall-reporter.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
/*
* syscall reporting example for seccomp
*
* Copyright (c) 2012 The Chromium OS Authors <chromium-os-dev@chromium.org>
* Authors:
* Will Drewry <wad@chromium.org>
* Kees Cook <keescook@chromium.org>
*
* The code may be used by anyone for any purpose, and can serve as a
* starting point for developing applications using mode 2 seccomp.
*/
#include "syscall-reporter.h"
#include "syscall-names.h"
const char * const msg_needed = "Looks like you also need syscall: ";
/* Since "sprintf" is technically not signal-safe, reimplement %d here. */
static void write_uint(char *buf, unsigned int val)
{
int width = 0;
unsigned int tens;
if (val == 0) {
strcpy(buf, "0");
return;
}
for (tens = val; tens; tens /= 10)
++ width;
buf[width] = '\0';
for (tens = val; tens; tens /= 10)
buf[--width] = '0' + (tens % 10);
}
static void reporter(int nr, siginfo_t *info, void *void_context)
{
#ifdef SECCOMP
char buf[128];
ucontext_t *ctx = (ucontext_t *)(void_context);
unsigned int syscall;
if (info->si_code != SYS_SECCOMP)
return;
if (!ctx)
return;
syscall = ctx->uc_mcontext.gregs[REG_SYSCALL];
strcpy(buf, msg_needed);
if (syscall < sizeof(syscall_names)) {
strcat(buf, syscall_names[syscall]);
strcat(buf, "(");
}
write_uint(buf + strlen(buf), syscall);
if (syscall < sizeof(syscall_names))
strcat(buf, ")");
strcat(buf, "\n");
write(STDERR_FILENO, buf, strlen(buf));
_exit(1);
#endif
}
int install_syscall_reporter(void)
{
#ifdef SECCOMP
struct sigaction act;
sigset_t mask;
memset(&act, 0, sizeof(act));
sigemptyset(&mask);
sigaddset(&mask, SIGSYS);
act.sa_sigaction = &reporter;
act.sa_flags = SA_SIGINFO;
if (sigaction(SIGSYS, &act, NULL) < 0) {
perror("sigaction");
return -1;
}
if (sigprocmask(SIG_UNBLOCK, &mask, NULL)) {
perror("sigprocmask");
return -1;
}
#endif
return 0;
}