diff --git a/tests/sys/kern/Makefile b/tests/sys/kern/Makefile --- a/tests/sys/kern/Makefile +++ b/tests/sys/kern/Makefile @@ -27,6 +27,9 @@ ATF_TESTS_C+= reaper ATF_TESTS_C+= sched_affinity ATF_TESTS_C+= sigaltstack +ATF_TESTS_C+= sigsys +TEST_METADATA.sigsys+= is_exclusive="true" +TEST_METADATA.sigsys+= required_user="root" ATF_TESTS_C+= sigwait ATF_TESTS_C+= socket_accf ATF_TESTS_C+= socket_msg_trunc diff --git a/tests/sys/kern/sigsys.c b/tests/sys/kern/sigsys.c new file mode 100644 --- /dev/null +++ b/tests/sys/kern/sigsys.c @@ -0,0 +1,122 @@ +/*- + * Copyright (c) 2023 Dmitry Chagin + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include + +#include +#include +#include + +static volatile sig_atomic_t signals = 0; +static volatile sig_atomic_t signo = 0; + +static void +handler(int sig) +{ + + signo = sig; + signals++; +} + +static void +sysctlset(const char *name, int32_t val) +{ + + ATF_REQUIRE(sysctlbyname(name, NULL, NULL, &val, sizeof(val)) == 0); +} + +static void +test_sigsys(bool sigsys) +{ + int error; + + ATF_REQUIRE(signal(SIGSYS, handler) != SIG_ERR); + + /* 11 - obsolete execv */ + signals = signo = 0; + error = syscall(11, 0, 1); + ATF_REQUIRE(error == -1); + ATF_REQUIRE(errno == ENOSYS); + if (sigsys) { + ATF_REQUIRE(signals == 1); + ATF_REQUIRE(signo == SIGSYS); + } else + ATF_REQUIRE(signals == 0); + /* loadable syscall */ + signals = signo = 0; + error = syscall(SYS_nfssvc, 0, 1); + ATF_REQUIRE(error == -1); + ATF_REQUIRE(errno == ENOSYS || errno == EINVAL); + if (sigsys) { + ATF_REQUIRE(signals == 0 || signals == 1); + ATF_REQUIRE(signo == SIGSYS || signo == 0); + } else + ATF_REQUIRE(signals == 0); + /* non-existent syscall */ + signals = signo = 0; + error = syscall(SYS_MAXSYSCALL + 1, 0, 1); + ATF_REQUIRE(error == -1); + ATF_REQUIRE(errno == ENOSYS); + if (sigsys) { + ATF_REQUIRE(signals == 1); + ATF_REQUIRE(signo == SIGSYS); + } else + ATF_REQUIRE(signals == 0); +} + +/* Test SIGSYS with knob kern.signosys=1 */ +ATF_TC_WITH_CLEANUP(test_sigsys_on); +ATF_TC_HEAD(test_sigsys_on, tc) +{ + + atf_tc_set_md_var(tc, "require.user", "root"); + atf_tc_set_md_var(tc, "descr", "Test SIGSYS with kern.signosys on"); +} + +ATF_TC_BODY(test_sigsys_on, tc) +{ + + sysctlset("kern.signosys", 1); + test_sigsys(true); +} + +ATF_TC_CLEANUP(test_sigsys_on, tc) +{ + + sysctlset("kern.signosys", 1); +} + +/* Test SIGSYS with knob kern.signosys=0 */ +ATF_TC_WITH_CLEANUP(test_sigsys_off); +ATF_TC_HEAD(test_sigsys_off, tc) +{ + + atf_tc_set_md_var(tc, "require.user", "root"); + atf_tc_set_md_var(tc, "descr", "Test SIGSYS with kern.signosys off"); +} + +ATF_TC_BODY(test_sigsys_off, tc) +{ + + sysctlset("kern.signosys", 0); + test_sigsys(false); +} + +ATF_TC_CLEANUP(test_sigsys_off, tc) +{ + + sysctlset("kern.signosys", 1); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, test_sigsys_on); + ATF_TP_ADD_TC(tp, test_sigsys_off); + + return (atf_no_error()); +}