summaryrefslogtreecommitdiff
path: root/src/arch-syscall-validate
diff options
context:
space:
mode:
authorPaul Moore <pmoore@redhat.com>2014-06-24 15:04:33 -0400
committerPaul Moore <pmoore@redhat.com>2014-06-24 18:02:22 -0400
commit111eb1b7468afa80b4be973ad642345de53c5f78 (patch)
tree2f128fc04ad87da7ca99f3f2ed6cd3fc71d575dd /src/arch-syscall-validate
parentb52b18c76803199a999cdc75c3823a957bb50c93 (diff)
downloadlibseccomp-111eb1b7468afa80b4be973ad642345de53c5f78.tar.gz
tests: provide a simple syscall validation tool
Signed-off-by: Paul Moore <pmoore@redhat.com>
Diffstat (limited to 'src/arch-syscall-validate')
-rwxr-xr-xsrc/arch-syscall-validate323
1 files changed, 323 insertions, 0 deletions
diff --git a/src/arch-syscall-validate b/src/arch-syscall-validate
new file mode 100755
index 0000000..5d2e9aa
--- /dev/null
+++ b/src/arch-syscall-validate
@@ -0,0 +1,323 @@
+#!/bin/bash
+
+#
+# libseccomp syscall validation script
+#
+# Copyright (c) 2014 Red Hat <pmoore@redhat.com>
+# Author: Paul Moore <pmoore@redhat.com>
+#
+
+#
+# This library is free software; you can redistribute it and/or modify it
+# under the terms of version 2.1 of the GNU Lesser General Public License as
+# published by the Free Software Foundation.
+#
+# This library is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+# for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this library; if not, see <http://www.gnu.org/licenses>.
+#
+
+LIB_SYS_DUMP="./arch-syscall-dump"
+
+####
+# functions
+
+#
+# Dependency check
+#
+# Arguments:
+# 1 Dependency to check for
+#
+function check_deps() {
+ [[ -z "$1" ]] && return
+ which "$1" >& /dev/null
+ return $?
+}
+
+#
+# Dependency verification
+#
+# Arguments:
+# 1 Dependency to check for
+#
+function verify_deps() {
+ [[ -z "$1" ]] && return
+ if ! check_deps "$1"; then
+ echo "error: install \"$1\" and include it in your \$PATH"
+ exit 1
+ fi
+}
+
+#
+# Print out script usage details
+#
+function usage() {
+cat << EOF
+usage: arch-syscall-validate [-h] [-a <arch>] <kernel_directory>
+
+libseccomp syscall validation script
+optional arguments:
+ -h show this help message and exit
+ -a architecture
+EOF
+}
+
+#
+# Dump the x86 system syscall table
+#
+# Arguments:
+# 1 path to the kernel source
+#
+# Dump the architecture's syscall table to stdout.
+#
+function dump_sys_x86() {
+ cat $1/arch/x86/include/generated/uapi/asm/unistd_32.h | \
+ grep "^#define __NR_" | sort | \
+ sed -e 's/#define[ \t]\+__NR_\([^ \t]\+\)[ \t]\+\(.*\).*/\1\t\2/'
+}
+
+#
+# Dump the x86 library syscall table
+#
+# Dump the library's syscall table to stdout.
+#
+function dump_lib_x86() {
+ $LIB_SYS_DUMP -a x86 | sed -e '/[^\t]\+\t-[0-9]\+/d'
+}
+
+#
+# Dump the x86_64 system syscall table
+#
+# Arguments:
+# 1 path to the kernel source
+#
+# Dump the architecture's syscall table to stdout.
+#
+function dump_sys_x86_64() {
+ cat $1/arch/x86/include/generated/uapi/asm/unistd_64.h | \
+ grep "^#define __NR_" | sort | \
+ sed -e 's/#define[ \t]\+__NR_\([^ \t]\+\)[ \t]\+\(.*\).*/\1\t\2/'
+}
+
+#
+# Dump the x86_64 library syscall table
+#
+# Dump the library's syscall table to stdout.
+#
+function dump_lib_x86_64() {
+ $LIB_SYS_DUMP -a x86_64 | sed -e '/[^\t]\+\t-[0-9]\+/d'
+}
+
+#
+# Dump the x32 system syscall table
+#
+# Arguments:
+# 1 path to the kernel source
+#
+# Dump the architecture's syscall table to stdout.
+#
+function dump_sys_x32() {
+ cat $1/arch/x86/include/generated/uapi/asm/unistd_x32.h | \
+ grep "^#define __NR_" | sort | \
+ sed -e 's/#define[ \t]\+__NR_\([^ \t]\+\)[ \t]\+(__X32_SYSCALL_BIT[ \t]*+[ \t]*\([0-9]\+\)).*/\1\t\2/'
+}
+
+#
+# Dump the x32 library syscall table
+#
+# Dump the library's syscall table to stdout.
+#
+function dump_lib_x32() {
+ # 1073741824 == 0x40000000
+ $LIB_SYS_DUMP -a x32 -o 1073741824 | sed -e '/[^\t]\+\t-[0-9]\+/d'
+}
+
+#
+# Dump the arm system syscall table
+#
+# Arguments:
+# 1 path to the kernel source
+#
+# Dump the architecture's syscall table to stdout.
+#
+function dump_sys_arm() {
+ # NOTE: arm_sync_file_range() and sync_file_range2() share values
+ cat $1/arch/arm/include/uapi/asm/unistd.h | \
+ grep "^#define __NR_" | sort | \
+ grep -v "^#define __NR_OABI_SYSCALL_BASE" | \
+ grep -v "^#define __NR_SYSCALL_BASE" | \
+ sed -e 's/#define[ \t]\+__NR_\([^ \t]\+\)[ \t]\+(__NR_SYSCALL_BASE[ \t]*+[ \t]*\([0-9]\+\)).*/\1\t\2/' | \
+ sed -e '/#define __NR_sync_file_range2[ \t]\+__NR_arm_sync_file_range/d'
+}
+
+#
+# Dump the arm library syscall table
+#
+# Dump the library's syscall table to stdout.
+#
+function dump_lib_arm() {
+ # NOTE: arm_sync_file_range() and sync_file_range2() share values
+ $LIB_SYS_DUMP -a arm | sed -e '/[^\t]\+\t-[0-9]\+/d' | \
+ sed -e '/sync_file_range2[ \t]\+341/d'
+}
+
+#
+# Dump the mips system syscall table
+#
+# Arguments:
+# 1 path to the kernel source
+#
+# Dump the architecture's syscall table to stdout.
+#
+function dump_sys_mips() {
+ # _MIPS_SIM values:
+ # _MIPS_SIM_ABI32 == 1
+ # _MIPS_SIM_NABI32 == 2
+ # _MIPS_SIM_ABI64 == 3
+ gcc -E -dM -I$1/arch/mips/include/uapi -D_MIPS_SIM=1 $1/arch/mips/include/uapi/asm/unistd.h | \
+ grep "^#define __NR_" | sort | \
+ grep -v "^#define __NR_O32_" | \
+ grep -v "^#define __NR_N32_" | \
+ grep -v "^#define __NR_64_" | \
+ grep -v "^#define __NR_Linux" | \
+ grep -v "^#define __NR_unused" | \
+ grep -v "^#define __NR_reserved" | \
+ sed -e 's/#define[ \t]\+__NR_\([^ \t]\+\)[ \t]\+(__NR_Linux[ \t]*+[ \t]*\([0-9]\+\)).*/\1\t\2/'
+}
+
+#
+# Dump the mips library syscall table
+#
+# Dump the library's syscall table to stdout.
+#
+function dump_lib_mips() {
+ $LIB_SYS_DUMP -a mips -o 4000 | sed -e '/[^\t]\+\t-[0-9]\+/d'
+}
+
+#
+# Dump the system syscall table
+#
+# Arguments:
+# 1 architecture
+# 2 path to the kernel source
+#
+# Dump the system's syscall table to stdout using the given architecture.
+#
+function dump_sys() {
+ case $1 in
+ x86)
+ dump_sys_x86 "$2"
+ ;;
+ x86_64)
+ dump_sys_x86_64 "$2"
+ ;;
+ x32)
+ dump_sys_x32 "$2"
+ ;;
+ arm)
+ dump_sys_arm "$2"
+ ;;
+ mips)
+ dump_sys_mips "$2"
+ ;;
+ *)
+ echo ""
+ ;;
+ esac
+}
+
+#
+# Dump the library syscall table
+#
+# Arguments:
+# 1 architecture
+#
+# Dump the library's syscall table to stdout using the given architecture.
+#
+function dump_lib() {
+ case $1 in
+ x86)
+ dump_lib_x86 "$2"
+ ;;
+ x86_64)
+ dump_lib_x86_64 "$2"
+ ;;
+ x32)
+ dump_lib_x32 "$2"
+ ;;
+ arm)
+ dump_lib_arm "$2"
+ ;;
+ mips)
+ dump_lib_mips "$2"
+ ;;
+ *)
+ echo ""
+ ;;
+ esac
+}
+
+####
+# main
+
+verify_deps diff
+verify_deps gcc
+verify_deps grep
+verify_deps mktemp
+verify_deps sed
+if [[ ! -x $LIB_SYS_DUMP ]]; then
+ echo "error: \"$LIB_SYS_DUMP\" is not in the current working directory"
+ exit 1
+fi
+
+arches=""
+
+while getopts "a:h" opt; do
+ case $opt in
+ a)
+ arches+="$OPTARG "
+ ;;
+ h|*)
+ usage
+ exit 1
+ ;;
+ esac
+done
+shift $(($OPTIND - 1))
+
+# defaults
+[[ $arches == "" ]] && arches="x86 x86_64 x32 arm mips"
+
+# sanity checks
+kernel_dir="$1"
+if [[ -z $kernel_dir ]]; then
+ usage
+ exit 1
+fi
+if [[ ! -d $kernel_dir ]]; then
+ echo "error: \"$1\" is not a valid directory"
+ exit 1
+fi
+
+# generate some temp files
+tmp_orig=$(mktemp -t syscall_validate_XXXXXX)
+tmp_new=$(mktemp -t syscall_validate_XXXXXX)
+
+# loop through the architectures
+for i in $arches; do
+ # dump the syscall tables
+ dump_lib $i > $tmp_orig
+ dump_sys $i "$kernel_dir" > $tmp_new
+
+ # do the comparison
+ diff -u --label="$i [library]" $tmp_orig --label "$i [system]" $tmp_new
+done
+
+# cleanup and exit
+rm -f $tmp_orig $tmp_new
+
+exit 0