/tests/param_test_mm_cid_benchmark_cxx
/tests/param_test_mm_cid_compare_twice
/tests/param_test_mm_cid_compare_twice_cxx
+/tests/no_syscall_test_cxx.tap
+/tests/no_syscall_test.tap
+/tests/unregistered_test_cxx.tap
+/tests/unregistered_test.tap
#automake
/include/config.h
])
AC_SUBST(DL_LIBS)
+PKG_CHECK_MODULES([SECCOMP], [libseccomp],
+ [
+ dnl PKG_CHECK_MODULES defines SECCOMP_LIBS
+ have_seccomp=yes
+ ],
+ [
+ have_seccomp=no
+ ])
+
## ##
## Optional features selection ##
AE_FEATURE([Werror], [Treat compiler warnings as errors.])
+## ##
+## Set automake variables for optional feature conditionnals in Makefile.am ##
+## ##
+
+AM_CONDITIONAL([ENABLE_SECCOMP], test "x${have_seccomp}" = "xyes")
+
+
## ##
## Substitute variables for use in Makefile.am ##
## ##
param_test_compare_twice \
param_test_compare_twice_cxx \
param_test_mm_cid_compare_twice \
- param_test_mm_cid_compare_twice_cxx
+ param_test_mm_cid_compare_twice_cxx \
+ no_syscall_test_cxx.tap \
+ no_syscall_test.tap \
+ unregistered_test_cxx.tap \
+ unregistered_test.tap
dist_noinst_SCRIPTS = \
+ run_no_syscall_test_cxx.tap \
+ run_no_syscall_test.tap \
+ run_param_test_cxx.tap \
run_param_test.tap \
- run_param_test_cxx.tap
+ run_unregistered_test_cxx.tap \
+ run_unregistered_test.tap
+
+if ENABLE_SECCOMP
+noinst_LTLIBRARIES = libdisable-rseq-syscall.la
+
+libdisable_rseq_syscall_la_SOURCES = disable-rseq-syscall.c
+libdisable_rseq_syscall_la_LDFLAGS = -module -shared -avoid-version -rpath $(abs_builddir)/.libs/
+libdisable_rseq_syscall_la_LIBADD = $(SECCOMP_LIBS)
+endif
basic_percpu_ops_test_tap_SOURCES = basic_percpu_ops_test.c
basic_percpu_ops_test_tap_LDADD = $(top_builddir)/src/librseq.la $(top_builddir)/tests/utils/libtap.la $(DL_LIBS)
basic_percpu_ops_mm_cid_test_cxx_tap_CPPFLAGS = $(AM_CPPFLAGS) -DBUILDOPT_RSEQ_PERCPU_MM_CID
basic_percpu_ops_mm_cid_test_cxx_tap_LDADD = $(top_builddir)/src/librseq.la $(top_builddir)/tests/utils/libtap.la $(DL_LIBS)
+unregistered_test_tap_SOURCES = unregistered_test.c
+unregistered_test_tap_LDADD = $(top_builddir)/src/librseq.la $(top_builddir)/tests/utils/libtap.la $(DL_LIBS)
+
+unregistered_test_cxx_tap_SOURCES = unregistered_test_cxx.cpp
+unregistered_test_cxx_tap_LDADD = $(top_builddir)/src/librseq.la $(top_builddir)/tests/utils/libtap.la $(DL_LIBS)
+
+no_syscall_test_tap_SOURCES = no_syscall_test.c
+no_syscall_test_tap_LDADD = $(top_builddir)/src/librseq.la $(top_builddir)/tests/utils/libtap.la $(DL_LIBS)
+
+no_syscall_test_cxx_tap_SOURCES = no_syscall_test_cxx.cpp
+no_syscall_test_cxx_tap_LDADD = $(top_builddir)/src/librseq.la $(top_builddir)/tests/utils/libtap.la $(DL_LIBS)
+
basic_test_tap_SOURCES = basic_test.c
basic_test_tap_LDADD = $(top_builddir)/src/librseq.la $(top_builddir)/tests/utils/libtap.la $(DL_LIBS)
param_test_mm_cid_compare_twice_cxx_CPPFLAGS = $(AM_CPPFLAGS) -DRSEQ_COMPARE_TWICE -DBUILDOPT_RSEQ_PERCPU_MM_CID
param_test_mm_cid_compare_twice_cxx_LDADD = $(top_builddir)/src/librseq.la $(DL_LIBS)
+# Run shorter tests first
TESTS = \
+ basic_test.tap \
+ basic_test_cxx.tap \
+ run_unregistered_test.tap \
+ run_unregistered_test_cxx.tap
+
+if ENABLE_SECCOMP
+TESTS += \
+ run_no_syscall_test.tap \
+ run_no_syscall_test_cxx.tap
+endif
+
+# Run longer tests last
+TESTS += \
basic_percpu_ops_test.tap \
basic_percpu_ops_test_cxx.tap \
basic_percpu_ops_mm_cid_test.tap \
basic_percpu_ops_mm_cid_test_cxx.tap \
- basic_test.tap \
- basic_test_cxx.tap \
run_param_test.tap \
run_param_test_cxx.tap
--- /dev/null
+// SPDX-License-Identifier: MIT
+// SPDX-FileCopyrightText: 2024 Michael Jeanson <mjeanson@efficios.com>
+
+#include <errno.h>
+#include <seccomp.h>
+
+/*
+ * Library constructor.
+ *
+ * Apply a seccomp policy that blocks access to the rseq syscall and returns
+ * ENOSYS.
+ */
+static __attribute__((constructor))
+void disable_rseq_syscall(void)
+{
+ scmp_filter_ctx ctx;
+
+ ctx = seccomp_init(SCMP_ACT_ALLOW);
+ seccomp_rule_add(ctx, SCMP_ACT_ERRNO(ENOSYS), SCMP_SYS(rseq), 0);
+ seccomp_load(ctx);
+}
--- /dev/null
+// SPDX-License-Identifier: MIT
+// SPDX-FileCopyrightText: 2024 Michael Jeanson <mjeanson@efficios.com>
+
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+#include <stdint.h>
+
+#include <rseq/rseq.h>
+
+#include "tap.h"
+
+#define NR_TESTS 5
+
+/*
+ * Check the state of the public symbols when the rseq syscall is unavailable.
+ *
+ * This test must be used with an LD_PRELOAD library to deny access to the
+ * syscall, or on a kernel that doesn't implement the syscall.
+ */
+
+int main(void)
+{
+ struct rseq_abi *rseq_abi;
+
+ plan_tests(NR_TESTS);
+
+ if (rseq_available(RSEQ_AVAILABLE_QUERY_KERNEL)) {
+ fail("The rseq syscall should be unavailable");
+ goto end;
+ }
+
+ /* The rseq syscall is disabled, no registration is possible. */
+
+ ok(rseq_flags == 0, "rseq_flags prior to registration is 0 (%d)", rseq_flags);
+ ok(rseq_size == 0, "rseq_size prior to registration is 0 (%d)", rseq_size);
+ ok(rseq_feature_size == 0, "rseq_feature_size prior to registration is 0 (%d)", rseq_feature_size);
+ ok(rseq_offset != 0, "rseq_offset prior to registration is not 0 (%td)", rseq_offset);
+
+ rseq_abi = rseq_get_abi();
+ ok((int32_t) rseq_abi->cpu_id == RSEQ_ABI_CPU_ID_UNINITIALIZED,
+ "rseq->cpu_id is set to RSEQ_ABI_CPU_ID_UNINITIALIZED (%d)",
+ (int32_t) rseq_abi->cpu_id);
+
+end:
+ exit(exit_status());
+}
--- /dev/null
+// SPDX-License-Identifier: MIT
+// SPDX-FileCopyrightText: 2024 EfficiOS Inc.
+
+#include "no_syscall_test.c"
--- /dev/null
+#!/bin/bash
+# SPDX-License-Identifier: MIT
+# SPDX-FileCopyrightText: 2024 Michael Jeanson <mjeanson@efficios.com>
+
+SH_TAP=0
+
+if [ "x${RSEQ_TESTS_SRCDIR:-}" != "x" ]; then
+ UTILSSH="$RSEQ_TESTS_SRCDIR/utils/utils.sh"
+else
+ UTILSSH="$(dirname "$0")/utils/utils.sh"
+fi
+
+# shellcheck source=./utils/utils.sh
+source "$UTILSSH"
+
+CURDIR="${RSEQ_TESTS_BUILDDIR}/"
+
+LIBDISABLE_RSEQ_SYSCALL_PATH="${CURDIR}/.libs"
+LIBDISABLE_RSEQ_SYSCALL="${LIBDISABLE_RSEQ_SYSCALL_PATH}/libdisable-rseq-syscall.so"
+
+LD_PRELOAD="${LIBDISABLE_RSEQ_SYSCALL}" "${CURDIR}/no_syscall_test.tap"
--- /dev/null
+#!/bin/bash
+# SPDX-License-Identifier: MIT
+# SPDX-FileCopyrightText: 2024 Michael Jeanson <mjeanson@efficios.com>
+
+SH_TAP=0
+
+if [ "x${RSEQ_TESTS_SRCDIR:-}" != "x" ]; then
+ UTILSSH="$RSEQ_TESTS_SRCDIR/utils/utils.sh"
+else
+ UTILSSH="$(dirname "$0")/utils/utils.sh"
+fi
+
+# shellcheck source=./utils/utils.sh
+source "$UTILSSH"
+
+CURDIR="${RSEQ_TESTS_BUILDDIR}/"
+
+LIBDISABLE_RSEQ_SYSCALL_PATH="${CURDIR}/.libs"
+LIBDISABLE_RSEQ_SYSCALL="${LIBDISABLE_RSEQ_SYSCALL_PATH}/libdisable-rseq-syscall.so"
+
+LD_PRELOAD="${LIBDISABLE_RSEQ_SYSCALL}" "${CURDIR}/no_syscall_test_cxx.tap"
--- /dev/null
+#!/bin/bash
+# SPDX-License-Identifier: MIT
+# SPDX-FileCopyrightText: 2024 Michael Jeanson <mjeanson@efficios.com>
+
+SH_TAP=0
+
+if [ "x${RSEQ_TESTS_SRCDIR:-}" != "x" ]; then
+ UTILSSH="$RSEQ_TESTS_SRCDIR/utils/utils.sh"
+else
+ UTILSSH="$(dirname "$0")/utils/utils.sh"
+fi
+
+# shellcheck source=./utils/utils.sh
+source "$UTILSSH"
+
+GLIBC_TUNABLES="${GLIBC_TUNABLES:-}:glibc.pthread.rseq=0" "${RSEQ_TESTS_BUILDDIR}/unregistered_test.tap"
--- /dev/null
+#!/bin/bash
+# SPDX-License-Identifier: MIT
+# SPDX-FileCopyrightText: 2024 Michael Jeanson <mjeanson@efficios.com>
+
+SH_TAP=0
+
+if [ "x${RSEQ_TESTS_SRCDIR:-}" != "x" ]; then
+ UTILSSH="$RSEQ_TESTS_SRCDIR/utils/utils.sh"
+else
+ UTILSSH="$(dirname "$0")/utils/utils.sh"
+fi
+
+# shellcheck source=./utils/utils.sh
+source "$UTILSSH"
+
+GLIBC_TUNABLES="${GLIBC_TUNABLES:-}:glibc.pthread.rseq=0" "${RSEQ_TESTS_BUILDDIR}/unregistered_test_cxx.tap"
--- /dev/null
+// SPDX-License-Identifier: MIT
+// SPDX-FileCopyrightText: 2024 Michael Jeanson <mjeanson@efficios.com>
+
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+#include <stdint.h>
+
+#include <rseq/rseq.h>
+
+#include "tap.h"
+
+#define NR_TESTS 5
+
+/*
+ * Check the state of the public symbols when the rseq syscall is available but
+ * no thread has registered.
+ */
+
+int main(void)
+{
+ struct rseq_abi *rseq_abi;
+
+ plan_tests(NR_TESTS);
+
+ if (!rseq_available(RSEQ_AVAILABLE_QUERY_KERNEL)) {
+ skip(NR_TESTS, "rseq syscall unavailable");
+ goto end;
+ }
+
+ /* The syscall is available but the current thread is not registered. */
+
+ ok(rseq_flags == 0, "rseq_flags prior to registration is 0 (%d)", rseq_flags);
+ ok(rseq_size >= 32, "rseq_size prior to registration is 32 or greater (%d)", rseq_size);
+ ok(rseq_feature_size >= 20, "rseq_feature_size prior to registration is 20 or greater (%d)", rseq_feature_size);
+ ok(rseq_offset != 0, "rseq_offset prior to registration is not 0 (%td)", rseq_offset);
+
+ rseq_abi = rseq_get_abi();
+ ok((int32_t) rseq_abi->cpu_id == RSEQ_ABI_CPU_ID_UNINITIALIZED,
+ "rseq->cpu_id is set to RSEQ_ABI_CPU_ID_UNINITIALIZED (%d)",
+ (int32_t) rseq_abi->cpu_id);
+
+end:
+ exit(exit_status());
+}
--- /dev/null
+// SPDX-License-Identifier: MIT
+// SPDX-FileCopyrightText: 2024 EfficiOS Inc.
+
+#include "unregistered_test.c"