diff options
author | Stefano Brivio <sbrivio@redhat.com> | 2022-01-25 19:21:31 +0100 |
---|---|---|
committer | Stefano Brivio <sbrivio@redhat.com> | 2022-01-26 16:29:34 +0100 |
commit | daf8d057cebf4b304c11b10cd6e6c98e19710630 (patch) | |
tree | 7c159040e772b525ea27d8949594998e13381a42 | |
parent | 1eb14d730502d3f87111ae50d997e48def660623 (diff) | |
download | passt-daf8d057cebf4b304c11b10cd6e6c98e19710630.tar passt-daf8d057cebf4b304c11b10cd6e6c98e19710630.tar.gz passt-daf8d057cebf4b304c11b10cd6e6c98e19710630.tar.bz2 passt-daf8d057cebf4b304c11b10cd6e6c98e19710630.tar.lz passt-daf8d057cebf4b304c11b10cd6e6c98e19710630.tar.xz passt-daf8d057cebf4b304c11b10cd6e6c98e19710630.tar.zst passt-daf8d057cebf4b304c11b10cd6e6c98e19710630.zip |
seccomp: Introduce mechanism to allow per-arch syscalls
Some C library functions are commonly implemented by different syscalls
on different architectures. Add a mechanism to allow selected syscalls
for a single architecture, syntax in #syscalls comment is:
#syscalls <arch>:<name>
e.g. s390x:socketcall, given that socketcall() is commonly used there
instead of socket().
This is now implemented by a compiler probe for syscall numbers,
auditd tools (ausyscall) are not required anymore as a result.
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
-rwxr-xr-x | seccomp.sh | 57 |
1 files changed, 48 insertions, 9 deletions
@@ -63,6 +63,7 @@ sub() { sed -i "${__line_no}s#.*#${__template}#" "${TMP}" + IFS=' ' for __def in ${@}; do __key="@${__def%%:*}@" __value="${__def#*:}" @@ -79,6 +80,7 @@ finish() { __out="$(eval printf '%s' "\${${1}}")" shift + IFS=' ' for __def in ${@}; do __key="@${__def%%:*}@" __value="${__def#*:}" @@ -101,15 +103,54 @@ log2() { echo ${__x} } -# cc_syscall_nr - Try to get syscall number from compiler +# syscall_nr - Get syscall number from compiler # $1: Name of syscall -cc_syscall_nr() { - __in="$(printf "#include <sys/syscall.h>\n__NR_%s" ${1})" +syscall_nr() { + __in="$(printf "#include <asm-generic/unistd.h>\n#include <sys/syscall.h>\n__NR_%s" ${1})" __out="$(echo "${__in}" | cc -E -xc - -o - | tail -1)" [ "${__out}" = "__NR_$1" ] && return 1 echo "${__out}" } +filter() { + __filtered= + for __c in ${@}; do + __arch_match=0 + case ${__c} in + *:*) + case ${__c} in + $(uname -m):*) + __arch_match=1 + __c=${__c##*:} + ;; + esac + ;; + *) + __arch_match=1 + ;; + esac + [ ${__arch_match} -eq 0 ] && continue + + IFS='| ' + __found=0 + for __name in ${__c}; do + syscall_nr "${__name}" >/dev/null && __found=1 && break + done + unset IFS + + if [ ${__found} -eq 0 ]; then + echo + echo "Warning: no syscall number for ${__c}" >&2 + echo " none of these syscalls will be allowed" >&2 + continue + fi + + __filtered="${__filtered} ${__name}" + done + + echo "${__filtered}" | tr ' ' '\n' | sort -u +} + # gen_profile() - Build struct sock_filter for a single profile # $1: Profile name # $@: Names of allowed system calls, amount padded to next power of two @@ -127,9 +168,7 @@ gen_profile() { done for __i in $(seq 1 ${__statements_calls} ); do __syscall_name="$(eval echo \${${__i}})" - if { ! command -V ausyscall >/dev/null 2>&1 || \ - ! ausyscall "${__syscall_name}" --exact >> "${TMP}"; } && \ - ! cc_syscall_nr "${__syscall_name}" >> "${TMP}"; then + if ! syscall_nr ${__syscall_name} >> "${TMP}"; then echo "Cannot get syscall number for ${__syscall_name}" exit 1 fi @@ -191,8 +230,8 @@ gen_profile() { printf '%s\n' "${HEADER}" > "${OUT}" __profiles="$(sed -n 's/[\t ]*\*[\t ]*#syscalls:\([^ ]*\).*/\1/p' *.[ch] | sort -u)" for __p in ${__profiles}; do - __calls="$(sed -n 's/[\t ]*\*[\t ]*#syscalls\(:'"${__p}"'\|\)[\t ]\{1,\}\(.*\)/\2/p' *.[ch] | tr ' ' '\n' | sort -u)" - + __calls="$(sed -n 's/[\t ]*\*[\t ]*#syscalls\(:'"${__p}"'\|\)[\t ]\{1,\}\(.*\)/\2/p' *.[ch])" + __calls="$(filter ${__calls})" echo "seccomp profile ${__p} allows: ${__calls}" | tr '\n' ' ' | fmt -t # Pad here to keep gen_profile() "simple" @@ -200,7 +239,7 @@ for __p in ${__profiles}; do for __c in ${__calls}; do __count=$(( __count + 1 )); done __padded=$(( 1 << (( $(log2 ${__count}) + 1 )) )) for __i in $( seq ${__count} $(( __padded - 1 )) ); do - __calls="${__calls} tuxcall" + __calls="${__calls} read" done gen_profile "${__p}" ${__calls} |