From e7880e25b9d400feeaacb82f115fae676ce6c65d Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Thu, 21 Oct 2021 17:41:08 +0100 Subject: [PATCH] tests: Add basic test coverage for our seccomp filters In particular, this checks that CVE-2017-5226, CVE-2019-10063 and CVE-2021-41133 are still prevented. Signed-off-by: Simon McVittie (cherry picked from commit 7c5aec474caef7aa004286cc9359611ad21d227b) (cherry picked from commit ff0f5a15b26dac28c8efd88c8d47e51751df8043) --- tests/Makefile-test-matrix.am.inc | 1 + tests/Makefile.am.inc | 1 + tests/test-seccomp.sh | 94 +++++++++++++++++++++++++++++++ 3 files changed, 96 insertions(+) create mode 100755 tests/test-seccomp.sh diff --git a/tests/Makefile-test-matrix.am.inc b/tests/Makefile-test-matrix.am.inc index f56c169e60..e1ec09ffb0 100644 --- a/tests/Makefile-test-matrix.am.inc +++ b/tests/Makefile-test-matrix.am.inc @@ -43,6 +43,7 @@ TEST_MATRIX_DIST= \ tests/test-override.sh \ tests/test-auth.sh \ tests/test-unused.sh \ + tests/test-seccomp.sh \ $(NULL) TEST_MATRIX_EXTRA_DIST= \ tests/test-run.sh \ diff --git a/tests/Makefile.am.inc b/tests/Makefile.am.inc index 2548080254..fd13c0cd3d 100644 --- a/tests/Makefile.am.inc +++ b/tests/Makefile.am.inc @@ -237,6 +237,7 @@ TEST_MATRIX_SOURCE = \ tests/test-unused.sh \ tests/test-summaries.sh{user+system} \ tests/test-subset.sh{user+system} \ + tests/test-seccomp.sh \ $(NULL) update-test-matrix: diff --git a/tests/test-seccomp.sh b/tests/test-seccomp.sh new file mode 100755 index 0000000000..72b0dad231 --- /dev/null +++ b/tests/test-seccomp.sh @@ -0,0 +1,94 @@ +#!/bin/bash +# Copyright 2021 Collabora Ltd. +# SPDX-License-Identifier: LGPL-2.0-or-later + +set -euo pipefail + +. $(dirname $0)/libtest.sh + +skip_without_bwrap + +echo "1..16" + +setup_repo +install_repo + +cp -a "$G_TEST_BUILDDIR/try-syscall" "$test_tmpdir/try-syscall" + +# How this works: +# try-syscall tries to make various syscalls, some benign, some not. +# +# The parameters are chosen to make them fail with EBADF or EFAULT if +# not blocked. If they are blocked, we get ENOSYS or EPERM. If the syscall +# is impossible for a particular architecture, we get ENOENT. +# +# The exit status is an errno value, which we can compare with the expected +# errno value. + +eval "$("$test_tmpdir/try-syscall" print-errno-values)" + +try_syscall () { + ${FLATPAK} run \ + --filesystem="$test_tmpdir" \ + --command="$test_tmpdir/try-syscall" \ + $extra_argv \ + org.test.Hello "$@" +} + +for extra_argv in "" "--allow=multiarch"; do + echo "# testing with extra argv: '$extra_argv'" + + echo "# chmod (benign)" + e=0 + try_syscall chmod || e="$?" + assert_streq "$e" "$EFAULT" + ok "chmod not blocked" + + echo "# chroot (harmful)" + e=0 + try_syscall chroot || e="$?" + assert_streq "$e" "$EPERM" + ok "chroot blocked with EPERM" + + echo "# clone3 (harmful)" + e=0 + try_syscall clone3 || e="$?" + # This is either ENOSYS because the kernel genuinely doesn't implement it, + # or because we successfully blocked it. We can't tell which. + assert_streq "$e" "$ENOSYS" + ok "clone3 blocked with ENOSYS (CVE-2021-41133)" + + echo "# ioctl TIOCNOTTY (benign)" + e=0 + try_syscall "ioctl TIOCNOTTY" || e="$?" + assert_streq "$e" "$EBADF" + ok "ioctl TIOCNOTTY not blocked" + + echo "# ioctl TIOCSTI (CVE-2017-5226)" + e=0 + try_syscall "ioctl TIOCSTI" || e="$?" + assert_streq "$e" "$EPERM" + ok "ioctl TIOCSTI blocked (CVE-2017-5226)" + + echo "# ioctl TIOCSTI (trying to repeat CVE-2019-10063)" + e=0 + try_syscall "ioctl TIOCSTI CVE-2019-10063" || e="$?" + if test "$e" = "$ENOENT"; then + echo "ok # SKIP Cannot replicate CVE-2019-10063 on 32-bit architecture" + else + assert_streq "$e" "$EPERM" + ok "ioctl TIOCSTI with high bits blocked (CVE-2019-10063)" + fi + + echo "# listen (benign)" + e=0 + try_syscall "listen" || e="$?" + assert_streq "$e" "$EBADF" + ok "listen not blocked" + + echo "# prctl (benign)" + e=0 + try_syscall "prctl" || e="$?" + assert_streq "$e" "$EFAULT" + ok "prctl not blocked" +done