Bundle libseccomp 2.3.1
[linux-seccomp.git] / libseccomp / src / arch-syscall-validate
1 #!/bin/bash
2
3 #
4 # libseccomp syscall validation script
5 #
6 # Copyright (c) 2014 Red Hat <pmoore@redhat.com>
7 # Author: Paul Moore <paul@paul-moore.com>
8 #
9
10 #
11 # This library is free software; you can redistribute it and/or modify it
12 # under the terms of version 2.1 of the GNU Lesser General Public License as
13 # published by the Free Software Foundation.
14 #
15 # This library is distributed in the hope that it will be useful, but WITHOUT
16 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17 # FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
18 # for more details.
19 #
20 # You should have received a copy of the GNU Lesser General Public License
21 # along with this library; if not, see <http://www.gnu.org/licenses>.
22 #
23
24 LIB_SYS_DUMP="./arch-syscall-dump"
25
26 ####
27 # functions
28
29 #
30 # Dependency check
31 #
32 # Arguments:
33 # 1 Dependency to check for
34 #
35 function check_deps() {
36 [[ -z "$1" ]] && return
37 which "$1" >& /dev/null
38 return $?
39 }
40
41 #
42 # Dependency verification
43 #
44 # Arguments:
45 # 1 Dependency to check for
46 #
47 function verify_deps() {
48 [[ -z "$1" ]] && return
49 if ! check_deps "$1"; then
50 echo "error: install \"$1\" and include it in your \$PATH"
51 exit 1
52 fi
53 }
54
55 #
56 # Print out script usage details
57 #
58 function usage() {
59 cat << EOF
60 usage: arch-syscall-validate [-h] [-a <arch>] <kernel_directory>
61
62 libseccomp syscall validation script
63 optional arguments:
64 -h show this help message and exit
65 -a architecture
66 -l output the library's syscall definitions
67 -s output the system's syscall definitions
68 EOF
69 }
70
71 #
72 # Dump the library syscall table for a given architecture
73 #
74 # Arguments:
75 # 1 architecture
76 # 2 offset (optional)
77 #
78 #
79 # Dump the library's syscall table to stdout.
80 #
81 function dump_lib_arch() {
82 local offset_str=""
83
84 [[ -z $1 ]] && return
85
86 [[ -n $2 ]] && offset_str="-o $2"
87 $LIB_SYS_DUMP -a $1 $offset_str | sed -e '/[^\t]\+\t-[0-9]\+/d'
88 }
89
90 #
91 # Dump the x86 system syscall table
92 #
93 # Arguments:
94 # 1 path to the kernel source
95 #
96 # Dump the architecture's syscall table to stdout.
97 #
98 function dump_sys_x86() {
99 cat $1/arch/x86/entry/syscalls/syscall_32.tbl | \
100 grep -v "^#" | awk '{ print $3"\t"$1 }' | sed '/^[ \t]*$/d' | \
101 sort
102 }
103
104 #
105 # Dump the x86 library syscall table
106 #
107 # Dump the library's syscall table to stdout.
108 #
109 function dump_lib_x86() {
110 dump_lib_arch x86
111 }
112
113 #
114 # Dump the x86_64 system syscall table
115 #
116 # Arguments:
117 # 1 path to the kernel source
118 #
119 # Dump the architecture's syscall table to stdout.
120 #
121 function dump_sys_x86_64() {
122 cat $1/arch/x86/entry/syscalls/syscall_64.tbl | \
123 grep -v "^#" | awk '{ print $2,$3,$1 }' | sed -e '/^x32/d' | \
124 awk '{ print $2"\t"$3 }' | sed '/^[ \t]*$/d' | sort
125 }
126
127 #
128 # Dump the x86_64 library syscall table
129 #
130 # Dump the library's syscall table to stdout.
131 #
132 function dump_lib_x86_64() {
133 dump_lib_arch x86_64
134 }
135
136 #
137 # Dump the x32 system syscall table
138 #
139 # Arguments:
140 # 1 path to the kernel source
141 #
142 # Dump the architecture's syscall table to stdout.
143 #
144 function dump_sys_x32() {
145 cat $1/arch/x86/entry/syscalls/syscall_64.tbl | \
146 grep -v "^#" | awk '{ print $2,$3,$1 }' | sed -e '/^64/d' | \
147 awk '{ print $2"\t"$3 }' | sed '/^[ \t]*$/d' | sort
148 }
149
150 #
151 # Dump the x32 library syscall table
152 #
153 # Dump the library's syscall table to stdout.
154 #
155 function dump_lib_x32() {
156 # 1073741824 == 0x40000000
157 dump_lib_arch x32 1073741824
158 }
159
160 #
161 # Dump the arm system syscall table
162 #
163 # Arguments:
164 # 1 path to the kernel source
165 #
166 # Dump the architecture's syscall table to stdout.
167 #
168 function dump_sys_arm() {
169 # NOTE: arm_sync_file_range() and sync_file_range2() share values
170 gcc -E -dM -D__ARM_EABI__ $1/arch/arm/include/uapi/asm/unistd.h | \
171 grep "^#define __\(ARM_\)*NR_" | \
172 grep -v "^#define __NR_OABI_SYSCALL_BASE" | \
173 grep -v "^#define __NR_SYSCALL_BASE" | \
174 grep -v "^#define __ARM_NR_BASE" | \
175 sed -e 's/#define[ \t]\+__NR_\([^ \t]\+\)[ \t]\+(__NR_SYSCALL_BASE[ \t]*+[ \t]*\([0-9]\+\)).*/\1\t\2/;s/#define[ \t]\+__ARM_NR_\([^ \t]\+\)[ \t]\+(__ARM_NR_BASE[ \t]*+[ \t]*\([0-9]\+\)).*/\1\t983040 + \2/' | \
176 while read line; do \
177 if echo "$line" | grep -q "+"; then \
178 echo "$line" | awk '{ print $1"\t"$2+$4 }'; \
179 else \
180 echo "$line"; \
181 fi; \
182 done | \
183 sed -e '/#define __NR_sync_file_range2[ \t]\+__NR_arm_sync_file_range/d' | \
184 sort
185 }
186
187 #
188 # Dump the arm library syscall table
189 #
190 # Dump the library's syscall table to stdout.
191 #
192 function dump_lib_arm() {
193 # NOTE: arm_sync_file_range() and sync_file_range2() share values
194 dump_lib_arch arm | sed -e '/sync_file_range2[ \t]\+341/d'
195 }
196
197 #
198 # Dump the aarch64 system syscall table
199 #
200 # Arguments:
201 # 1 path to the kernel source
202 #
203 # Dump the architecture's syscall table to stdout.
204 #
205 function dump_sys_aarch64() {
206 gcc -E -dM -I$1/include/uapi -D__BITS_PER_LONG=64 $1/include/uapi/asm-generic/unistd.h | \
207 grep "^#define __NR_" | \
208 sed -e '/__NR_syscalls/d' | \
209 sed -e '/__NR_arch_specific_syscall/d' | \
210 sed -e 's/#define[ \t]\+__NR_\([^ \t]\+\)[ \t]\+\(.*\)/\1\t\2/' | \
211 sed -e 's/__NR3264_statfs/43/' | \
212 sed -e 's/__NR3264_ftruncate/46/' | \
213 sed -e 's/__NR3264_truncate/45/' | \
214 sed -e 's/__NR3264_lseek/62/' | \
215 sed -e 's/__NR3264_sendfile/71/' | \
216 sed -e 's/__NR3264_fstatat/79/' | \
217 sed -e 's/__NR3264_fstatfs/44/' | \
218 sed -e 's/__NR3264_fcntl/25/' | \
219 sed -e 's/__NR3264_fadvise64/223/' | \
220 sed -e 's/__NR3264_mmap/222/' | \
221 sed -e 's/__NR3264_fstat/80/' | \
222 sed -e 's/__NR3264_lstat/1039/' | \
223 sed -e 's/__NR3264_stat/1038/' | \
224 sort
225 }
226
227 #
228 # Dump the aarch64 library syscall table
229 #
230 # Dump the library's syscall table to stdout.
231 #
232 function dump_lib_aarch64() {
233 dump_lib_arch aarch64
234 }
235
236 #
237 # Dump the mips system syscall table
238 #
239 # Arguments:
240 # 1 path to the kernel source
241 #
242 # Dump the architecture's syscall table to stdout.
243 #
244 function dump_sys_mips() {
245 # _MIPS_SIM values:
246 # _MIPS_SIM_ABI32 == 1
247 # _MIPS_SIM_NABI32 == 2
248 # _MIPS_SIM_ABI64 == 3
249 gcc -E -dM -I$1/arch/mips/include/uapi -D_MIPS_SIM=1 $1/arch/mips/include/uapi/asm/unistd.h | \
250 grep "^#define __NR_" | \
251 grep -v "^#define __NR_O32_" | \
252 grep -v "^#define __NR_N32_" | \
253 grep -v "^#define __NR_64_" | \
254 grep -v "^#define __NR_Linux" | \
255 grep -v "^#define __NR_unused" | \
256 grep -v "^#define __NR_reserved" | \
257 sed -e 's/#define[ \t]\+__NR_\([^ \t]\+\)[ \t]\+(__NR_Linux[ \t]*+[ \t]*\([0-9]\+\)).*/\1\t\2/' | \
258 sort
259 }
260
261 #
262 # Dump the mips library syscall table
263 #
264 # Dump the library's syscall table to stdout.
265 #
266 function dump_lib_mips() {
267 dump_lib_arch mips 4000
268 }
269
270 #
271 # Dump the mips64 system syscall table
272 #
273 # Arguments:
274 # 1 path to the kernel source
275 #
276 # Dump the architecture's syscall table to stdout.
277 #
278 function dump_sys_mips64() {
279 # _MIPS_SIM values:
280 # _MIPS_SIM_ABI32 == 1
281 # _MIPS_SIM_NABI32 == 2
282 # _MIPS_SIM_ABI64 == 3
283 gcc -E -dM -I$1/arch/mips/include/uapi -D_MIPS_SIM=3 $1/arch/mips/include/uapi/asm/unistd.h | \
284 grep "^#define __NR_" | \
285 grep -v "^#define __NR_O32_" | \
286 grep -v "^#define __NR_N32_" | \
287 grep -v "^#define __NR_64_" | \
288 grep -v "^#define __NR_Linux" | \
289 grep -v "^#define __NR_unused" | \
290 grep -v "^#define __NR_reserved" | \
291 sed -e 's/#define[ \t]\+__NR_\([^ \t]\+\)[ \t]\+(__NR_Linux[ \t]*+[ \t]*\([0-9]\+\)).*/\1\t\2/' | \
292 sort
293 }
294
295 #
296 # Dump the mips64 library syscall table
297 #
298 # Dump the library's syscall table to stdout.
299 #
300 function dump_lib_mips64() {
301 dump_lib_arch mips64 5000
302 }
303
304 #
305 # Dump the mips64n32 system syscall table
306 #
307 # Arguments:
308 # 1 path to the kernel source
309 #
310 # Dump the architecture's syscall table to stdout.
311 #
312 function dump_sys_mips64n32() {
313 # _MIPS_SIM values:
314 # _MIPS_SIM_ABI32 == 1
315 # _MIPS_SIM_NABI32 == 2
316 # _MIPS_SIM_ABI64 == 3
317 gcc -E -dM -I$1/arch/mips/include/uapi -D_MIPS_SIM=2 $1/arch/mips/include/uapi/asm/unistd.h | \
318 grep "^#define __NR_" | \
319 grep -v "^#define __NR_O32_" | \
320 grep -v "^#define __NR_N32_" | \
321 grep -v "^#define __NR_64_" | \
322 grep -v "^#define __NR_Linux" | \
323 grep -v "^#define __NR_unused" | \
324 grep -v "^#define __NR_reserved" | \
325 sed -e 's/#define[ \t]\+__NR_\([^ \t]\+\)[ \t]\+(__NR_Linux[ \t]*+[ \t]*\([0-9]\+\)).*/\1\t\2/' | \
326 sort
327 }
328
329 #
330 # Dump the mips64n32 library syscall table
331 #
332 # Dump the library's syscall table to stdout.
333 #
334 function dump_lib_mips64n32() {
335 dump_lib_arch mips64n32 6000
336 }
337
338 #
339 # Dump the ppc system syscall table
340 #
341 # Arguments:
342 # 1 path to the kernel source
343 #
344 # Dump the architecture's syscall table to stdout.
345 #
346 function dump_sys_ppc() {
347 gcc -E -dM $1/arch/powerpc/include/uapi/asm/unistd.h | \
348 grep "^#define __NR_" | \
349 sed -e 's/#define[ \t]\+__NR_\([a-z0-9_]\+\)[ \t]\+\([0-9]\+\)/\1\t\2/' | \
350 sort
351 }
352
353 #
354 # Dump the ppc library syscall table
355 #
356 # Dump the library's syscall table to stdout.
357 #
358 function dump_lib_ppc() {
359 dump_lib_arch ppc
360 }
361
362 #
363 # Dump the ppc64 system syscall table
364 #
365 # Arguments:
366 # 1 path to the kernel source
367 #
368 # Dump the architecture's syscall table to stdout.
369 #
370 function dump_sys_ppc64() {
371 gcc -E -dM -D__powerpc64__ $1/arch/powerpc/include/uapi/asm/unistd.h | \
372 grep "^#define __NR_" | \
373 sed -e 's/#define[ \t]\+__NR_\([a-z0-9_]\+\)[ \t]\+\([0-9]\+\)/\1\t\2/' | \
374 sort
375 }
376
377 #
378 # Dump the ppc64 library syscall table
379 #
380 # Dump the library's syscall table to stdout.
381 #
382 function dump_lib_ppc64() {
383 dump_lib_arch ppc64
384 }
385
386 #
387 # Dump the s390 system syscall table
388 #
389 # Arguments:
390 # 1 path to the kernel source
391 #
392 # Dump the architecture's syscall table to stdout.
393 #
394 function dump_sys_s390() {
395 gcc -E -dM $1/arch/s390/include/uapi/asm/unistd.h | grep __NR | \
396 sed -e 's/#define[ \t]\+__NR_\([^ \t]\+\)[ \t]\+(__NR_timer_create[ \t]*+[ \t]*\([0-9]\+\)).*/\1\t254 + \2/' | \
397 while read line; do \
398 if echo "$line" | grep -q "+"; then \
399 echo "$line" | awk '{ print $1"\t"$2+$4 }'; \
400 else \
401 echo "$line"; \
402 fi; \
403 done | \
404 sed 's/#define __NR_//g' | sed 's/ /\t/g' | sort
405 }
406
407 #
408 # Dump the s390 library syscall table
409 #
410 # Dump the library's syscall table to stdout.
411 #
412 function dump_lib_s390() {
413 dump_lib_arch s390
414 }
415
416 #
417 # Dump the s390x system syscall table
418 #
419 # Arguments:
420 # 1 path to the kernel source
421 #
422 # Dump the architecture's syscall table to stdout.
423 #
424 function dump_sys_s390x() {
425 gcc -E -dM -D __s390x__ $1/arch/s390/include/uapi/asm/unistd.h | grep __NR | \
426 sed -e 's/#define[ \t]\+__NR_\([^ \t]\+\)[ \t]\+(__NR_timer_create[ \t]*+[ \t]*\([0-9]\+\)).*/\1\t254 + \2/' | \
427 while read line; do \
428 if echo "$line" | grep -q "+"; then \
429 echo "$line" | awk '{ print $1"\t"$2+$4 }'; \
430 else \
431 echo "$line"; \
432 fi; \
433 done | \
434 sed 's/#define __NR_//g' | sed 's/ /\t/g' | sort
435 }
436
437 #
438 # Dump the s390x library syscall table
439 #
440 # Dump the library's syscall table to stdout.
441 #
442 function dump_lib_s390x() {
443 dump_lib_arch s390x
444 }
445
446 #
447 # Dump the system syscall table
448 #
449 # Arguments:
450 # 1 architecture
451 # 2 path to the kernel source
452 #
453 # Dump the system's syscall table to stdout using the given architecture.
454 #
455 function dump_sys() {
456 case $1 in
457 x86)
458 dump_sys_x86 "$2"
459 ;;
460 x86_64)
461 dump_sys_x86_64 "$2"
462 ;;
463 x32)
464 dump_sys_x32 "$2"
465 ;;
466 arm)
467 dump_sys_arm "$2"
468 ;;
469 aarch64)
470 dump_sys_aarch64 "$2"
471 ;;
472 mips)
473 dump_sys_mips "$2"
474 ;;
475 mips64)
476 dump_sys_mips64 "$2"
477 ;;
478 mips64n32)
479 dump_sys_mips64n32 "$2"
480 ;;
481 ppc)
482 dump_sys_ppc "$2"
483 ;;
484 ppc64)
485 dump_sys_ppc64 "$2"
486 ;;
487 s390)
488 dump_sys_s390 "$2"
489 ;;
490 s390x)
491 dump_sys_s390x "$2"
492 ;;
493 *)
494 echo ""
495 return 1
496 ;;
497 esac
498
499 return 0
500 }
501
502 #
503 # Dump the library syscall table
504 #
505 # Arguments:
506 # 1 architecture
507 #
508 # Dump the library's syscall table to stdout using the given architecture.
509 #
510 function dump_lib() {
511 case $1 in
512 x86)
513 dump_lib_x86
514 ;;
515 x86_64)
516 dump_lib_x86_64
517 ;;
518 x32)
519 dump_lib_x32
520 ;;
521 arm)
522 dump_lib_arm
523 ;;
524 aarch64)
525 dump_lib_aarch64
526 ;;
527 mips)
528 dump_lib_mips
529 ;;
530 mips64)
531 dump_lib_mips64
532 ;;
533 mips64n32)
534 dump_lib_mips64n32
535 ;;
536 ppc)
537 dump_lib_ppc "$2"
538 ;;
539 ppc64)
540 dump_lib_ppc64 "$2"
541 ;;
542 s390)
543 dump_lib_s390 "$2"
544 ;;
545 s390x)
546 dump_lib_s390x "$2"
547 ;;
548 *)
549 echo ""
550 return 1
551 ;;
552 esac
553
554 return 0
555 }
556
557 ####
558 # main
559
560 verify_deps diff
561 verify_deps gcc
562 verify_deps grep
563 verify_deps mktemp
564 verify_deps sed
565 if [[ ! -x $LIB_SYS_DUMP ]]; then
566 echo "error: \"$LIB_SYS_DUMP\" is not in the current working directory"
567 exit 1
568 fi
569
570 opt_arches=""
571 opt_sys=""
572 opt_lib=""
573
574 while getopts "a:slh" opt; do
575 case $opt in
576 a)
577 opt_arches+="$OPTARG "
578 ;;
579 s)
580 opt_sys=1
581 opt_lib=0
582 ;;
583 l)
584 opt_sys=0
585 opt_lib=1
586 ;;
587 h|*)
588 usage
589 exit 1
590 ;;
591 esac
592 done
593 shift $(($OPTIND - 1))
594
595 # defaults
596 if [[ $opt_arches == "" ]]; then
597 opt_arches=" \
598 x86 x86_64 x32 \
599 arm aarch64 \
600 mips mips64 mips64n32 \
601 ppc ppc64 \
602 s390 s390x"
603 fi
604
605 # sanity checks
606 kernel_dir="$1"
607 if [[ -z $kernel_dir ]]; then
608 usage
609 exit 1
610 fi
611 if [[ ! -d $kernel_dir ]]; then
612 echo "error: \"$1\" is not a valid directory"
613 exit 1
614 fi
615
616 # generate some temp files
617 tmp_lib=$(mktemp -t syscall_validate_XXXXXX)
618 tmp_sys=$(mktemp -t syscall_validate_XXXXXX)
619
620 # loop through the architectures and compare
621 for i in $opt_arches; do
622 # dump the syscall tables
623 dump_lib $i > $tmp_lib
624 if [[ $? -ne 0 ]]; then
625 echo "error: unknown arch $i"
626 exit 1
627 fi
628 dump_sys $i "$kernel_dir" > $tmp_sys
629 if [[ $? -ne 0 ]]; then
630 echo "error: unknown arch $i"
631 exit 1
632 fi
633
634 if [[ $opt_lib -eq 1 ]]; then
635 cat $tmp_lib
636 elif [[ $opt_sys -eq 1 ]]; then
637 cat $tmp_sys
638 else
639 # compare the lib and sys output
640 diff -u --label="$i [library]" $tmp_lib \
641 --label "$i [system]" $tmp_sys
642 fi
643 done
644
645 # cleanup and exit
646 rm -f $tmp_lib $tmp_sys
647
648 exit 0
This page took 0.042103 seconds and 4 git commands to generate.