diff options
Diffstat (limited to 'src/arch-syscall-validate')
-rwxr-xr-x | src/arch-syscall-validate | 323 |
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 |