232 lines
6.8 KiB
Diff
232 lines
6.8 KiB
Diff
|
|
From b83fb81d1a66fe4ea31fd9c36ca425705eaaca99 Mon Sep 17 00:00:00 2001
|
||
|
|
From: Simon McVittie <smcv@collabora.com>
|
||
|
|
Date: Thu, 21 Oct 2021 17:39:08 +0100
|
||
|
|
Subject: [PATCH] tests: Add try-syscall helper
|
||
|
|
|
||
|
|
This exercises various syscalls. It's heavily based on the one from
|
||
|
|
<https://github.com/containers/bubblewrap/pull/459>, but with the
|
||
|
|
addition of a mode to output the numeric values of various expected
|
||
|
|
errno codes, which are not otherwise available to shell scripts.
|
||
|
|
|
||
|
|
Signed-off-by: Simon McVittie <smcv@collabora.com>
|
||
|
|
(cherry picked from commit 4ce251882c488953ca6e3734f00c5dbe2e1e3e7a)
|
||
|
|
(cherry picked from commit f82e2a45777e6f370b9d3be787a84cddc3ed0575)
|
||
|
|
---
|
||
|
|
.gitignore | 1 +
|
||
|
|
tests/Makefile.am.inc | 14 +++-
|
||
|
|
tests/try-syscall.c | 173 ++++++++++++++++++++++++++++++++++++++++++
|
||
|
|
3 files changed, 187 insertions(+), 1 deletion(-)
|
||
|
|
create mode 100644 tests/try-syscall.c
|
||
|
|
|
||
|
|
diff --git a/tests/Makefile.am.inc b/tests/Makefile.am.inc
|
||
|
|
index 3632591a04..2548080254 100644
|
||
|
|
--- a/tests/Makefile.am.inc
|
||
|
|
+++ b/tests/Makefile.am.inc
|
||
|
|
@@ -99,6 +99,10 @@ tests_test_authenticator_CFLAGS = $(AM_CFLAGS) $(BASE_CFLAGS) \
|
||
|
|
tests_test_authenticator_LDADD = $(AM_LDADD) $(BASE_LIBS) libflatpak-common.la libflatpak-common-base.la libglnx.la
|
||
|
|
tests_test_authenticator_SOURCES = tests/test-authenticator.c
|
||
|
|
|
||
|
|
+tests_try_syscall_CFLAGS = $(AM_CFLAGS)
|
||
|
|
+tests_try_syscall_LDADD = $(AM_LDADD)
|
||
|
|
+tests_try_syscall_SOURCES = tests/try-syscall.c
|
||
|
|
+
|
||
|
|
tests_list_unused_CFLAGS = $(AM_CFLAGS) $(BASE_CFLAGS) $(OSTREE_CFLAGS) $(SOUP_CFLAGS) $(JSON_CFLAGS) $(APPSTREAM_GLIB_CFLAGS) \
|
||
|
|
-DFLATPAK_COMPILATION \
|
||
|
|
-DLOCALEDIR=\"$(localedir)\"
|
||
|
|
@@ -263,7 +267,15 @@ test_programs = \
|
||
|
|
testcommon \
|
||
|
|
testlibrary \
|
||
|
|
$(NULL)
|
||
|
|
-test_extra_programs = tests/httpcache tests/test-update-portal tests/test-portal-impl tests/test-authenticator tests/list-unused
|
||
|
|
+
|
||
|
|
+test_extra_programs = \
|
||
|
|
+ tests/httpcache \
|
||
|
|
+ tests/list-unused \
|
||
|
|
+ tests/test-authenticator \
|
||
|
|
+ tests/test-portal-impl \
|
||
|
|
+ tests/test-update-portal \
|
||
|
|
+ tests/try-syscall \
|
||
|
|
+ $(NULL)
|
||
|
|
|
||
|
|
@VALGRIND_CHECK_RULES@
|
||
|
|
VALGRIND_SUPPRESSIONS_FILES=tests/flatpak.supp tests/glib.supp
|
||
|
|
diff --git a/tests/try-syscall.c b/tests/try-syscall.c
|
||
|
|
new file mode 100644
|
||
|
|
index 0000000000..84a0ca6673
|
||
|
|
--- /dev/null
|
||
|
|
+++ b/tests/try-syscall.c
|
||
|
|
@@ -0,0 +1,173 @@
|
||
|
|
+/*
|
||
|
|
+ * Copyright 2021 Simon McVittie
|
||
|
|
+ * SPDX-License-Identifier: LGPL-2.0-or-later
|
||
|
|
+ *
|
||
|
|
+ * Try one or more system calls that might have been blocked by a
|
||
|
|
+ * seccomp filter. Return the last value of errno seen.
|
||
|
|
+ *
|
||
|
|
+ * In general, we pass a bad fd or pointer to each syscall that will
|
||
|
|
+ * accept one, so that it will fail with EBADF or EFAULT without side-effects.
|
||
|
|
+ */
|
||
|
|
+
|
||
|
|
+#include <errno.h>
|
||
|
|
+#include <stdio.h>
|
||
|
|
+#include <string.h>
|
||
|
|
+#include <unistd.h>
|
||
|
|
+#include <sys/ioctl.h>
|
||
|
|
+#include <sys/prctl.h>
|
||
|
|
+#include <sys/socket.h>
|
||
|
|
+#include <sys/syscall.h>
|
||
|
|
+#include <sys/stat.h>
|
||
|
|
+#include <sys/types.h>
|
||
|
|
+
|
||
|
|
+#if defined(_MIPS_SIM)
|
||
|
|
+# if _MIPS_SIM == _MIPS_SIM_ABI32
|
||
|
|
+# define MISSING_SYSCALL_BASE 4000
|
||
|
|
+# elif _MIPS_SIM == _MIPS_SIM_ABI64
|
||
|
|
+# define MISSING_SYSCALL_BASE 5000
|
||
|
|
+# elif _MIPS_SIM == _MIPS_SIM_NABI32
|
||
|
|
+# define MISSING_SYSCALL_BASE 6000
|
||
|
|
+# else
|
||
|
|
+# error "Unknown MIPS ABI"
|
||
|
|
+# endif
|
||
|
|
+#endif
|
||
|
|
+
|
||
|
|
+#if defined(__ia64__)
|
||
|
|
+# define MISSING_SYSCALL_BASE 1024
|
||
|
|
+#endif
|
||
|
|
+
|
||
|
|
+#if defined(__alpha__)
|
||
|
|
+# define MISSING_SYSCALL_BASE 110
|
||
|
|
+#endif
|
||
|
|
+
|
||
|
|
+#if defined(__x86_64__) && defined(__ILP32__)
|
||
|
|
+# define MISSING_SYSCALL_BASE 0x40000000
|
||
|
|
+#endif
|
||
|
|
+
|
||
|
|
+/*
|
||
|
|
+ * MISSING_SYSCALL_BASE:
|
||
|
|
+ *
|
||
|
|
+ * Number to add to the syscall numbers of recently-added syscalls
|
||
|
|
+ * to get the appropriate syscall for the current ABI.
|
||
|
|
+ */
|
||
|
|
+#ifndef MISSING_SYSCALL_BASE
|
||
|
|
+# define MISSING_SYSCALL_BASE 0
|
||
|
|
+#endif
|
||
|
|
+
|
||
|
|
+#ifndef __NR_clone3
|
||
|
|
+# define __NR_clone3 (MISSING_SYSCALL_BASE + 435)
|
||
|
|
+#endif
|
||
|
|
+
|
||
|
|
+/*
|
||
|
|
+ * The size of clone3's parameter (as of 2021)
|
||
|
|
+ */
|
||
|
|
+#define SIZEOF_STRUCT_CLONE_ARGS ((size_t) 88)
|
||
|
|
+
|
||
|
|
+/*
|
||
|
|
+ * An invalid pointer that will cause syscalls to fail with EFAULT
|
||
|
|
+ */
|
||
|
|
+#define WRONG_POINTER ((char *) 1)
|
||
|
|
+
|
||
|
|
+int
|
||
|
|
+main (int argc, char **argv)
|
||
|
|
+{
|
||
|
|
+ int errsv = 0;
|
||
|
|
+ int i;
|
||
|
|
+
|
||
|
|
+ for (i = 1; i < argc; i++)
|
||
|
|
+ {
|
||
|
|
+ const char *arg = argv[i];
|
||
|
|
+
|
||
|
|
+ if (strcmp (arg, "print-errno-values") == 0)
|
||
|
|
+ {
|
||
|
|
+ printf ("EBADF=%d\n", EBADF);
|
||
|
|
+ printf ("EFAULT=%d\n", EFAULT);
|
||
|
|
+ printf ("ENOENT=%d\n", ENOENT);
|
||
|
|
+ printf ("ENOSYS=%d\n", ENOSYS);
|
||
|
|
+ printf ("EPERM=%d\n", EPERM);
|
||
|
|
+ }
|
||
|
|
+ else if (strcmp (arg, "chmod") == 0)
|
||
|
|
+ {
|
||
|
|
+ /* If not blocked by seccomp, this will fail with EFAULT */
|
||
|
|
+ if (chmod (WRONG_POINTER, 0700) != 0)
|
||
|
|
+ {
|
||
|
|
+ errsv = errno;
|
||
|
|
+ perror (arg);
|
||
|
|
+ }
|
||
|
|
+ }
|
||
|
|
+ else if (strcmp (arg, "chroot") == 0)
|
||
|
|
+ {
|
||
|
|
+ /* If not blocked by seccomp, this will fail with EFAULT */
|
||
|
|
+ if (chroot (WRONG_POINTER) != 0)
|
||
|
|
+ {
|
||
|
|
+ errsv = errno;
|
||
|
|
+ perror (arg);
|
||
|
|
+ }
|
||
|
|
+ }
|
||
|
|
+ else if (strcmp (arg, "clone3") == 0)
|
||
|
|
+ {
|
||
|
|
+ /* If not blocked by seccomp, this will fail with EFAULT */
|
||
|
|
+ if (syscall (__NR_clone3, WRONG_POINTER, SIZEOF_STRUCT_CLONE_ARGS) != 0)
|
||
|
|
+ {
|
||
|
|
+ errsv = errno;
|
||
|
|
+ perror (arg);
|
||
|
|
+ }
|
||
|
|
+ }
|
||
|
|
+ else if (strcmp (arg, "ioctl TIOCNOTTY") == 0)
|
||
|
|
+ {
|
||
|
|
+ /* If not blocked by seccomp, this will fail with EBADF */
|
||
|
|
+ if (ioctl (-1, TIOCNOTTY) != 0)
|
||
|
|
+ {
|
||
|
|
+ errsv = errno;
|
||
|
|
+ perror (arg);
|
||
|
|
+ }
|
||
|
|
+ }
|
||
|
|
+ else if (strcmp (arg, "ioctl TIOCSTI") == 0)
|
||
|
|
+ {
|
||
|
|
+ /* If not blocked by seccomp, this will fail with EBADF */
|
||
|
|
+ if (ioctl (-1, TIOCSTI, WRONG_POINTER) != 0)
|
||
|
|
+ {
|
||
|
|
+ errsv = errno;
|
||
|
|
+ perror (arg);
|
||
|
|
+ }
|
||
|
|
+ }
|
||
|
|
+#ifdef __LP64__
|
||
|
|
+ else if (strcmp (arg, "ioctl TIOCSTI CVE-2019-10063") == 0)
|
||
|
|
+ {
|
||
|
|
+ unsigned long not_TIOCSTI = (0x123UL << 32) | (unsigned long) TIOCSTI;
|
||
|
|
+
|
||
|
|
+ /* If not blocked by seccomp, this will fail with EBADF */
|
||
|
|
+ if (syscall (__NR_ioctl, -1, not_TIOCSTI, WRONG_POINTER) != 0)
|
||
|
|
+ {
|
||
|
|
+ errsv = errno;
|
||
|
|
+ perror (arg);
|
||
|
|
+ }
|
||
|
|
+ }
|
||
|
|
+#endif
|
||
|
|
+ else if (strcmp (arg, "listen") == 0)
|
||
|
|
+ {
|
||
|
|
+ /* If not blocked by seccomp, this will fail with EBADF */
|
||
|
|
+ if (listen (-1, 42) != 0)
|
||
|
|
+ {
|
||
|
|
+ errsv = errno;
|
||
|
|
+ perror (arg);
|
||
|
|
+ }
|
||
|
|
+ }
|
||
|
|
+ else if (strcmp (arg, "prctl") == 0)
|
||
|
|
+ {
|
||
|
|
+ /* If not blocked by seccomp, this will fail with EFAULT */
|
||
|
|
+ if (prctl (PR_GET_CHILD_SUBREAPER, WRONG_POINTER, 0, 0, 0) != 0)
|
||
|
|
+ {
|
||
|
|
+ errsv = errno;
|
||
|
|
+ perror (arg);
|
||
|
|
+ }
|
||
|
|
+ }
|
||
|
|
+ else
|
||
|
|
+ {
|
||
|
|
+ fprintf (stderr, "Unsupported syscall \"%s\"\n", arg);
|
||
|
|
+ errsv = ENOENT;
|
||
|
|
+ }
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
+ return errsv;
|
||
|
|
+}
|