]>
iEval git - linux-seccomp.git/blob - libseccomp/tools/scmp_bpf_sim.c
a0cf6d1d6f5397de44f2110d1c472a8f4ff2a6bb
4 * Copyright (c) 2012 Red Hat <pmoore@redhat.com>
5 * Author: Paul Moore <paul@paul-moore.com>
9 * This library is free software; you can redistribute it and/or modify it
10 * under the terms of version 2.1 of the GNU Lesser General Public License as
11 * published by the Free Software Foundation.
13 * This library is distributed in the hope that it will be useful, but WITHOUT
14 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
18 * You should have received a copy of the GNU Lesser General Public License
19 * along with this library; if not, see <http://www.gnu.org/licenses>.
30 #include <linux/audit.h>
31 #include <sys/types.h>
37 #define BPF_PRG_MAX_LEN 4096
40 * BPF simulator machine state
44 uint32_t temp
[BPF_SCRATCH_SIZE
];
52 static unsigned int opt_verbose
= 0;
55 * Print the usage information to stderr and exit
56 * @param program the name of the current program being invoked
58 * Print the usage information and exit with EINVAL.
61 static void exit_usage(const char *program
)
64 "usage: %s -f <bpf_file> [-v] [-h]"
65 " -a <arch> -s <syscall_num> [-0 <a0>] ... [-5 <a5>]\n",
71 * Handle a simulator fault
72 * @param rc the error or return code
74 * Print a "FAULT" to stderr to indicate a simulator fault, and an errno value
75 * if the simulator is running in verbose mode, then exit with EFAULT.
78 static void exit_fault(unsigned int rc
)
81 fprintf(stderr
, "FAULT: errno = %d\n", rc
);
83 fprintf(stderr
, "FAULT\n");
88 * Handle a BPF program error
89 * @param rc the error or return code
90 * @param line the line number
92 * Print an "ERROR" to stderr to indicate a program error, and an errno value
93 * if the simulator is running in verbose mode, then exit with ENOEXEC.
96 static void exit_error(unsigned int rc
, unsigned int line
)
99 fprintf(stderr
, "ERROR: errno = %d, line = %d\n", rc
, line
);
101 fprintf(stderr
, "ERROR\n");
106 * Handle a simulator return/action
107 * @param action the return value
108 * @param line the line number
110 * Display the action to stdout and exit with 0.
113 static void end_action(uint32_t action
, unsigned int line
)
115 uint32_t act
= action
& SECCOMP_RET_ACTION
;
116 uint32_t data
= action
& SECCOMP_RET_DATA
;
119 case SECCOMP_RET_KILL
:
120 fprintf(stdout
, "KILL\n");
122 case SECCOMP_RET_TRAP
:
123 fprintf(stdout
, "TRAP\n");
125 case SECCOMP_RET_ERRNO
:
126 fprintf(stdout
, "ERRNO(%u)\n", data
);
128 case SECCOMP_RET_TRACE
:
129 fprintf(stdout
, "TRACE(%u)\n", data
);
131 case SECCOMP_RET_ALLOW
:
132 fprintf(stdout
, "ALLOW\n");
135 exit_error(EDOM
, line
);
142 * Execute a BPF program
143 * @param prg the loaded BPF program
144 * @param sys_data the syscall record being tested
146 * Simulate the BPF program with the given syscall record.
149 static void bpf_execute(const struct bpf_program
*prg
,
150 const struct seccomp_data
*sys_data
)
152 unsigned int ip
, ip_c
;
153 struct sim_state state
;
155 unsigned char *sys_data_b
= (unsigned char *)sys_data
;
161 /* initialize the machine state */
164 memset(&state
, 0, sizeof(state
));
166 while (ip
< prg
->i_cnt
) {
167 /* get the instruction and bump the ip */
171 code
= ttoh16(arch
, bpf
->code
);
174 k
= ttoh32(arch
, bpf
->k
);
177 case BPF_LD
+BPF_W
+BPF_ABS
:
178 if (k
< BPF_SYSCALL_MAX
) {
179 uint32_t val
= *((uint32_t *)&sys_data_b
[k
]);
180 state
.acc
= ttoh32(arch
, val
);
182 exit_error(ERANGE
, ip_c
);
184 case BPF_ALU
+BPF_OR
+BPF_K
:
187 case BPF_ALU
+BPF_AND
+BPF_K
:
193 case BPF_JMP
+BPF_JEQ
+BPF_K
:
199 case BPF_JMP
+BPF_JGT
+BPF_K
:
205 case BPF_JMP
+BPF_JGE
+BPF_K
:
215 /* since we don't support the full bpf language just
216 * yet, this could be either a fault or an error, we'll
217 * treat it as a fault until we provide full support */
218 exit_fault(EOPNOTSUPP
);
222 /* if we've reached here there is a problem with the program */
223 exit_error(ERANGE
, ip_c
);
229 int main(int argc
, char *argv
[])
233 char *opt_file
= NULL
;
235 size_t file_read_len
;
236 struct seccomp_data sys_data
;
237 struct bpf_program bpf_prg
;
239 /* initialize the syscall record */
240 memset(&sys_data
, 0, sizeof(sys_data
));
242 /* parse the command line */
243 while ((opt
= getopt(argc
, argv
, "a:f:hs:v0:1:2:3:4:5:")) > 0) {
246 if (strcmp(optarg
, "x86") == 0)
247 arch
= AUDIT_ARCH_I386
;
248 else if (strcmp(optarg
, "x86_64") == 0)
249 arch
= AUDIT_ARCH_X86_64
;
250 else if (strcmp(optarg
, "x32") == 0)
251 arch
= AUDIT_ARCH_X86_64
;
252 else if (strcmp(optarg
, "arm") == 0)
253 arch
= AUDIT_ARCH_ARM
;
254 else if (strcmp(optarg
, "aarch64") == 0)
255 arch
= AUDIT_ARCH_AARCH64
;
256 else if (strcmp(optarg
, "mips") == 0)
257 arch
= AUDIT_ARCH_MIPS
;
258 else if (strcmp(optarg
, "mipsel") == 0)
259 arch
= AUDIT_ARCH_MIPSEL
;
260 else if (strcmp(optarg
, "mips64") == 0)
261 arch
= AUDIT_ARCH_MIPS64
;
262 else if (strcmp(optarg
, "mipsel64") == 0)
263 arch
= AUDIT_ARCH_MIPSEL64
;
264 else if (strcmp(optarg
, "mips64n32") == 0)
265 arch
= AUDIT_ARCH_MIPS64N32
;
266 else if (strcmp(optarg
, "mipsel64n32") == 0)
267 arch
= AUDIT_ARCH_MIPSEL64N32
;
268 else if (strcmp(optarg
, "ppc") == 0)
269 arch
= AUDIT_ARCH_PPC
;
270 else if (strcmp(optarg
, "ppc64") == 0)
271 arch
= AUDIT_ARCH_PPC64
;
272 else if (strcmp(optarg
, "ppc64le") == 0)
273 arch
= AUDIT_ARCH_PPC64LE
;
274 else if (strcmp(optarg
, "s390") == 0)
275 arch
= AUDIT_ARCH_S390
;
276 else if (strcmp(optarg
, "s390x") == 0)
277 arch
= AUDIT_ARCH_S390X
;
282 opt_file
= strdup(optarg
);
283 if (opt_file
== NULL
)
287 sys_data
.nr
= strtol(optarg
, NULL
, 0);
293 sys_data
.args
[0] = strtoull(optarg
, NULL
, 0);
296 sys_data
.args
[1] = strtoull(optarg
, NULL
, 0);
299 sys_data
.args
[2] = strtoull(optarg
, NULL
, 0);
302 sys_data
.args
[3] = strtoull(optarg
, NULL
, 0);
305 sys_data
.args
[4] = strtoull(optarg
, NULL
, 0);
308 sys_data
.args
[5] = strtoull(optarg
, NULL
, 0);
312 /* usage information */
317 /* adjust the endianess of sys_data to match the target */
318 sys_data
.nr
= htot32(arch
, sys_data
.nr
);
319 sys_data
.arch
= htot32(arch
, arch
);
320 sys_data
.instruction_pointer
= htot64(arch
,
321 sys_data
.instruction_pointer
);
322 for (iter
= 0; iter
< BPF_SYS_ARG_MAX
; iter
++)
323 sys_data
.args
[iter
] = htot64(arch
, sys_data
.args
[iter
]);
325 /* allocate space for the bpf program */
326 /* XXX - we should make this dynamic */
328 bpf_prg
.i
= calloc(BPF_PRG_MAX_LEN
, sizeof(*bpf_prg
.i
));
329 if (bpf_prg
.i
== NULL
)
332 /* load the bpf program */
333 file
= fopen(opt_file
, "r");
337 file_read_len
= fread(&(bpf_prg
.i
[bpf_prg
.i_cnt
]),
338 sizeof(*bpf_prg
.i
), 1, file
);
339 if (file_read_len
== 1)
343 if (bpf_prg
.i_cnt
== BPF_PRG_MAX_LEN
)
345 } while (file_read_len
> 0);
348 /* execute the bpf program */
349 bpf_execute(&bpf_prg
, &sys_data
);
351 /* we should never reach here */
This page took 0.062054 seconds and 4 git commands to generate.