#ifdef __NR_syscalls # define MAGIC_SYSCALL_1 (__NR_syscalls + 1) /* Bad Linux syscall number */ #else # define MAGIC_SYSCALL_1 (0xff00) /* Bad Linux syscall number */ #endif
/* Test Summary: * * - dispatch_trigger_sigsys: Verify if PR_SET_SYSCALL_USER_DISPATCH is * able to trigger SIGSYS on a syscall. * * - bad_selector: Test that a bad selector value triggers SIGSYS with * si_errno EINVAL. * * - bad_prctl_param: Test that the API correctly rejects invalid * parameters on prctl * * - dispatch_and_return: Test that a syscall is selectively dispatched * to userspace depending on the value of selector. * * - disable_dispatch: Test that the PR_SYS_DISPATCH_OFF correctly * disables the dispatcher * * - direct_dispatch_range: Test that a syscall within the allowed range * can bypass the dispatcher.
*/
TEST_SIGNAL(dispatch_trigger_sigsys, SIGSYS)
{ char sel = SYSCALL_DISPATCH_FILTER_ALLOW; struct sysinfo info; int ret;
ret = sysinfo(&info);
ASSERT_EQ(0, ret);
ret = prctl(PR_SET_SYSCALL_USER_DISPATCH, PR_SYS_DISPATCH_EXCLUSIVE_ON, 0, 0, &sel);
ASSERT_EQ(0, ret) {
TH_LOG("Kernel does not support CONFIG_SYSCALL_USER_DISPATCH");
}
/* * Use global selector for handle_sigsys tests, to avoid passing * selector to signal handler
*/ char glob_sel; int nr_syscalls_emulated; int si_code; int si_errno; unsignedlong syscall_addr;
if (info->si_syscall == MAGIC_SYSCALL_1)
nr_syscalls_emulated++;
/* In preparation for sigreturn. */
SYSCALL_DISPATCH_OFF(glob_sel);
/* * The tests for argument handling assume that `syscall(x) == x`. This * is a NOP on x86 because the syscall number is passed in %rax, which * happens to also be the function ABI return register. Other * architectures may need to swizzle the arguments around.
*/ #ifdefined(__riscv) /* REG_A7 is not defined in libc headers */ # define REG_A7 (REG_A0 + 7)
/* Make sure selector is good prior to prctl. */
SYSCALL_DISPATCH_OFF(glob_sel);
ret = prctl(PR_SET_SYSCALL_USER_DISPATCH, PR_SYS_DISPATCH_EXCLUSIVE_ON, 0, 0, &glob_sel);
ASSERT_EQ(0, ret) {
TH_LOG("Kernel does not support CONFIG_SYSCALL_USER_DISPATCH");
}
ret = sigaction(SIGSYS, &act, NULL);
ASSERT_EQ(0, ret);
/* Make sure selector is good prior to prctl. */
SYSCALL_DISPATCH_OFF(glob_sel);
ret = prctl(PR_SET_SYSCALL_USER_DISPATCH, PR_SYS_DISPATCH_EXCLUSIVE_ON, 0, 0, &glob_sel);
ASSERT_EQ(0, ret) {
TH_LOG("Kernel does not support CONFIG_SYSCALL_USER_DISPATCH");
}
glob_sel = -1;
sysinfo(&info);
/* Even though it is ready to catch SIGSYS, the signal is * supposed to be uncatchable.
*/
EXPECT_FALSE(true) {
TH_LOG("Unreachable!");
}
}
TEST(disable_dispatch)
{ int ret; struct sysinfo info; char sel = 0;
ret = prctl(PR_SET_SYSCALL_USER_DISPATCH, PR_SYS_DISPATCH_EXCLUSIVE_ON, 0, 0, &sel);
ASSERT_EQ(0, ret) {
TH_LOG("Kernel does not support CONFIG_SYSCALL_USER_DISPATCH");
}
TEST(direct_dispatch_range)
{ int ret = 0; struct sysinfo info; char sel = SYSCALL_DISPATCH_FILTER_ALLOW;
/* * Instead of calculating libc addresses; allow the entire * memory map and lock the selector.
*/
ret = prctl(PR_SET_SYSCALL_USER_DISPATCH, PR_SYS_DISPATCH_EXCLUSIVE_ON, 0, -1L, &sel);
ASSERT_EQ(0, ret) {
TH_LOG("Kernel does not support CONFIG_SYSCALL_USER_DISPATCH");
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.