aboutgitcodebugslistschat
path: root/seccomp.sh
diff options
context:
space:
mode:
authorStefano Brivio <sbrivio@redhat.com>2022-01-25 19:21:31 +0100
committerStefano Brivio <sbrivio@redhat.com>2022-01-26 16:29:34 +0100
commitdaf8d057cebf4b304c11b10cd6e6c98e19710630 (patch)
tree7c159040e772b525ea27d8949594998e13381a42 /seccomp.sh
parent1eb14d730502d3f87111ae50d997e48def660623 (diff)
downloadpasst-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>
Diffstat (limited to 'seccomp.sh')
-rwxr-xr-xseccomp.sh57
1 files changed, 48 insertions, 9 deletions
diff --git a/seccomp.sh b/seccomp.sh
index c710ce4..f5ee98e 100755
--- a/seccomp.sh
+++ b/seccomp.sh
@@ -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}