-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathbpf-filter.c
130 lines (98 loc) · 3.07 KB
/
bpf-filter.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
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#include "common.h"
#include "bpf-filter.h"
#include "trusted_thread.h"
#include <signal.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ucontext.h>
#include "x86_decoder.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "library.h"
#include "sandbox.h"
#include "tls.h"
#include "syscall_x64.h"
#include <sys/syscall.h>
#define __USE_GNU 1
#define _GNU_SOURCE 1
int find_function_boundaries( char * instr, char **start, char ** end )
{
char * ptr=instr;
for (unsigned short i; *ptr != '\xC3'; )
i=next_inst((const char **)&ptr, true,0, 0, 0, 0, 0);
*end=ptr;
ptr=instr;
for (int nopcount=0; nopcount < 2 ; ptr--)
if(*ptr == '\x90')
nopcount++;
else
nopcount=0;
*start=ptr;
return SUCCESS;
}
void emulator(int nr, siginfo_t *info, void *void_context)
{
ucontext_t *ctx = (ucontext_t *)(void_context);
register_size _syscall,pc, stack_base, stack;
syscall_request syscall_request;
syscall_result syscall_result;
/*char *start=NULL, *end=NULL; */
if (info->si_code != SYS_SECCOMP)
return;
if (!ctx)
return;
_syscall = ctx->uc_mcontext.gregs[REG_SYSCALL];
/* pc=ctx->uc_mcontext.gregs[REG_PC];*/
/*stack=ctx->uc_mcontext.gregs[REG_STACK];*/
/*stack_base=ctx->uc_mcontext.gregs[REG_BASE];*/
pid_t tid= (pid_t)get_local_tid();
/*// Note si_call_addr points to the instruction after the syscall instruction */
DPRINT(DEBUG_INFO, "== [%d] Start emulation of %s \n", tid ,syscall_names[_syscall]);
DPRINT(DEBUG_INFO, "Syscall instruction address %p\n", info->si_call_addr);
// let assume that the boundaries are correct
/* find_function_boundaries((char *)info->si_call_addr, &start, &end); */
/*DPRINT(DEBUG_INFO, "Function start %p end %p \n",start, end);*/
// disable the patch mechanism
/*patch_syscalls_in_func(start, end);*/
fill_syscall_request(ctx, &syscall_request);
if(send_syscall_request(&syscall_request) < 0 )
die("Failed to send system call request");
if(get_syscall_result(&syscall_result) < 0)
die("Failed to receive the syscall result");
ctx->uc_mcontext.gregs[REG_RESULT] = syscall_result.result;
DPRINT(DEBUG_INFO, "== [%d] End emulation of %s\n", tid,syscall_names[_syscall]);
return;
}
int install_filter(int fd)
{
struct sock_filter f[] =
{
VALIDATE_ARCHITECTURE,
EXAMINE_SYSCALL,
ALLOW_SYSCALL(rt_sigreturn),
ALLOW_SYSCALL(rt_sigprocmask),
ALLOW_ARGUMENT(write, 0, fd),
ALLOW_ARGUMENT(read, 0, fd),
#ifdef DEBUG
ALLOW_ARGUMENT(write , 0, STDERR_FILENO),
#endif
TRAP_PROCESS,
KILL_PROCESS,
};
struct sock_fprog prog =
{
.len = (unsigned short)(sizeof(f)/sizeof(f[0])),
.filter = f,
};
// I need to allow read and write
if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0))
die("prctl(NO_NEW_PRIVS)");
DPRINT(DEBUG_INFO, "Released priviledge\n");
if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog))
perror("prctl(BPF FILTER)");
DPRINT(DEBUG_INFO, "In seccomp BPF mode\n");
return SUCCESS;
}