diff --git a/Makefile b/Makefile index de3175d..e972e88 100644 --- a/Makefile +++ b/Makefile @@ -83,7 +83,7 @@ static: CFLAGS += -static -DGLIBC_NO_STATIC_NSS static: clean all seccomp.h: *.c $(filter-out seccomp.h,$(wildcard *.h)) - @ ./seccomp.sh + @ EXTRA_SYSCALLS=$(EXTRA_SYSCALLS) ./seccomp.sh passt: $(filter-out qrap.c,$(wildcard *.c)) \ $(filter-out qrap.h,$(wildcard *.h)) seccomp.h @@ -108,6 +108,12 @@ qrap: qrap.c passt.h $(CC) $(CFLAGS) \ qrap.c -o qrap +valgrind: EXTRA_SYSCALLS="rt_sigprocmask rt_sigtimedwait rt_sigaction \ + getpid gettid kill clock_gettime mmap munmap open \ + unlink exit_group gettimeofday" +valgrind: CFLAGS:=-g -O0 $(filter-out -O%,$(CFLAGS)) +valgrind: all + .PHONY: clean clean: -${RM} passt passt.avx2 *.o seccomp.h qrap pasta pasta.avx2 pasta.1 \ diff --git a/seccomp.sh b/seccomp.sh index 6ac59a1..74eeb4b 100755 --- a/seccomp.sh +++ b/seccomp.sh @@ -234,6 +234,7 @@ 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])" + __calls="${__calls} ${EXTRA_SYSCALLS:-}" __calls="$(filter ${__calls})" echo "seccomp profile ${__p} allows: ${__calls}" | tr '\n' ' ' | fmt -t diff --git a/test/README.md b/test/README.md index b50c430..623e6e5 100644 --- a/test/README.md +++ b/test/README.md @@ -31,7 +31,7 @@ Example for Debian, and possibly most Debian-based distributions: build-essential git jq strace iperf3 qemu-system-x86 tmux sipcalc bc clang-tidy cppcheck isc-dhcp-common udhcpc psmisc linux-cpupower netcat-openbsd fakeroot lz4 lm-sensors qemu-system-arm qemu-system-ppc - qemu-system-misc qemu-system-x86` + qemu-system-misc qemu-system-x86 valgrind ### Other tools diff --git a/test/lib/setup b/test/lib/setup index a39eb80..823c706 100755 --- a/test/lib/setup +++ b/test/lib/setup @@ -51,8 +51,12 @@ setup_passt() { [ ${DEBUG} -eq 1 ] && __opts="${__opts} -d" [ ${TRACE} -eq 1 ] && __opts="${__opts} --trace" - pane_run PASST "./passt ${__opts} -f -t 10001 -u 10001" - sleep 1 + pane_run PASST "make clean" + pane_wait PASST + pane_run PASST "make valgrind" + pane_wait PASST + pane_run PASST "valgrind --max-stackframe=$((4 * 1024 * 1024)) --trace-children=yes --vgdb=no --error-exitcode=1 --suppressions=test/valgrind.supp ./passt ${__opts} -f -t 10001 -u 10001 -P passt.pid" + sleep 5 pane_run GUEST './qrap 5 kvm -m '${VMEM}' -cpu host -smp '${VCPUS} \ ' -kernel ' "/boot/vmlinuz-$(uname -r)" \ @@ -133,7 +137,7 @@ setup_passt_in_ns() { rm "${__pid_file}" pane_run GUEST "nsenter -t ${__ns_pid} -U -n --preserve-credentials" - pane_run NS "nsenter -t ${__ns_pid} -U -n --preserve-credentials" + pane_run NS "nsenter -t ${__ns_pid} -U -n -p --preserve-credentials" pane_wait GUEST pane_wait NS @@ -151,9 +155,20 @@ setup_passt_in_ns() { [ ${DEBUG} -eq 1 ] && __opts="${__opts} -d" [ ${TRACE} -eq 1 ] && __opts="${__opts} --trace" - #pane_run PASST "valgrind --max-stackframe=3000000 ./passt -f ${__opts} -t 10001,10011,10021,10031 -u 10001,10011,10021,10031" - pane_run PASST "./passt -f ${__opts} -t 10001,10011,10021,10031 -u 10001,10011,10021,10031" - sleep 1 + if [ ${VALGRIND} -eq 1 ]; then + pane_run PASST "make clean" + pane_wait PASST + pane_run PASST "make valgrind" + pane_wait PASST + pane_run PASST "valgrind --max-stackframe=$((4 * 1024 * 1024)) --trace-children=yes --vgdb=no --error-exitcode=1 --suppressions=test/valgrind.supp ./passt -f ${__opts} -t 10001,10011,10021,10031 -u 10001,10011,10021,10031 -P passt.pid" + else + pane_run PASST "make clean" + pane_wait PASST + pane_run PASST "make" + pane_wait PASST + pane_run PASST "./passt -f ${__opts} -t 10001,10011,10021,10031 -u 10001,10011,10021,10031 -P passt.pid" + fi + sleep 5 pane_run GUEST './qrap 5 kvm -m '${VMEM}' -cpu host -smp '${VCPUS} \ ' -kernel ' "/boot/vmlinuz-$(uname -r)" \ @@ -264,12 +279,11 @@ setup_two_guests() { pane_wait GUEST_2 } -# teardown_passt() - Kill qemu and passt +# teardown_passt() - Kill qemu, remove passt PID file teardown_passt() { - tmux send-keys -t ${PANE_PASST} "C-c" - pane_wait PASST tmux send-keys -t ${PANE_GUEST} "C-c" pane_wait GUEST + rm passt.pid } # teardown_passt() - Exit namespace, kill pasta process @@ -280,14 +294,14 @@ teardown_pasta() { pane_wait NS } -# teardown_passt_in_ns() - Exit namespace, kill qemu, passt and pasta +# teardown_passt_in_ns() - Exit namespace, kill qemu and pasta, remove pid file teardown_passt_in_ns() { tmux send-keys -t ${PANE_GUEST} "C-c" pane_wait GUEST tmux send-keys -t ${PANE_GUEST} "C-d" - tmux send-keys -t ${PANE_PASST} "C-c" - pane_wait PASST + [ ${VALGRIND} -eq 0 ] && tmux send-keys -t ${PANE_PASST} "C-c" + [ ${VALGRIND} -eq 0 ] && pane_wait GUEST tmux send-keys -t ${PANE_PASST} "C-d" tmux send-keys -t ${PANE_NS} "C-d" @@ -295,6 +309,8 @@ teardown_passt_in_ns() { pane_wait GUEST pane_wait NS pane_wait PASST + + rm passt.pid } # teardown_two_guests() - Exit namespaces, kill qemu processes, passt and pasta diff --git a/test/run b/test/run index 385267e..b2819ef 100755 --- a/test/run +++ b/test/run @@ -78,14 +78,23 @@ run() { test dhcp test tcp test udp + test valgrind teardown passt + VALGRIND=1 setup passt_in_ns test ndp test dhcp test icmp test tcp test udp + test valgrind + teardown passt_in_ns + + VALGRIND=0 + setup passt_in_ns + test ndp + test dhcp test perf teardown passt_in_ns diff --git a/test/valgrind.supp b/test/valgrind.supp new file mode 100644 index 0000000..1228056 --- /dev/null +++ b/test/valgrind.supp @@ -0,0 +1,9 @@ +# tcp_sock_consume() calls recv() with MSG_TRUNC and no buffer to discard data +{ + passt_recv_MSG_TRUNC_into_NULL_buffer + Memcheck:Param + socketcall.recvfrom(buf) + fun:recv + ... + fun:tcp_sock_consume* +} diff --git a/test/valgrind/passt b/test/valgrind/passt new file mode 100644 index 0000000..3af943a --- /dev/null +++ b/test/valgrind/passt @@ -0,0 +1,22 @@ +# SPDX-License-Identifier: AGPL-3.0-or-later +# +# PASST - Plug A Simple Socket Transport +# for qemu/UNIX domain socket mode +# +# PASTA - Pack A Subtle Tap Abstraction +# for network namespace/tap device mode +# +# test/valgrind/passt - Terminate passt and check valgrind exit code +# +# Copyright (c) 2022 Red Hat GmbH +# Author: Stefano Brivio + +onlyfor passt +test valgrind: exit code + +hout PASST_PID cat passt.pid +host kill __PASST_PID__ +sleep 1 + +pout VALGRIND_EXIT echo $? +check [ "__VALGRIND_EXIT__" = "0" ] diff --git a/test/valgrind/passt_in_ns b/test/valgrind/passt_in_ns new file mode 100644 index 0000000..bf50c7e --- /dev/null +++ b/test/valgrind/passt_in_ns @@ -0,0 +1,22 @@ +# SPDX-License-Identifier: AGPL-3.0-or-later +# +# PASST - Plug A Simple Socket Transport +# for qemu/UNIX domain socket mode +# +# PASTA - Pack A Subtle Tap Abstraction +# for network namespace/tap device mode +# +# test/valgrind/passt_in_ns - Terminate passt and check valgrind exit code +# +# Copyright (c) 2022 Red Hat GmbH +# Author: Stefano Brivio + +onlyfor passt_in_ns +test valgrind: exit code + +nsout PASST_PID cat passt.pid +ns kill __PASST_PID__ +sleep 1 + +pout VALGRIND_EXIT echo $? +check [ "__VALGRIND_EXIT__" = "0" ]