Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

selftest, ptrace: Add selftest for syscall user dispatch config api

Validate that the following new ptrace requests work as expected

* PTRACE_GET_SYSCALL_USER_DISPATCH_CONFIG
returns the contents of task->syscall_dispatch

* PTRACE_SET_SYSCALL_USER_DISPATCH_CONFIG
sets the contents of task->syscall_dispatch

Signed-off-by: Gregory Price <gregory.price@memverge.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Link: https://lore.kernel.org/r/20230407171834.3558-5-gregory.price@memverge.com

authored by

Gregory Price and committed by
Thomas Gleixner
8c8fa605 3f67987c

+74 -1
+1
tools/testing/selftests/ptrace/.gitignore
··· 1 1 # SPDX-License-Identifier: GPL-2.0-only 2 2 get_syscall_info 3 + get_set_sud 3 4 peeksiginfo 4 5 vmaccess
+1 -1
tools/testing/selftests/ptrace/Makefile
··· 1 1 # SPDX-License-Identifier: GPL-2.0-only 2 2 CFLAGS += -std=c99 -pthread -Wall $(KHDR_INCLUDES) 3 3 4 - TEST_GEN_PROGS := get_syscall_info peeksiginfo vmaccess 4 + TEST_GEN_PROGS := get_syscall_info peeksiginfo vmaccess get_set_sud 5 5 6 6 include ../lib.mk
+72
tools/testing/selftests/ptrace/get_set_sud.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + #define _GNU_SOURCE 3 + #include "../kselftest_harness.h" 4 + #include <stdio.h> 5 + #include <string.h> 6 + #include <errno.h> 7 + #include <sys/wait.h> 8 + #include <sys/syscall.h> 9 + #include <sys/prctl.h> 10 + 11 + #include "linux/ptrace.h" 12 + 13 + static int sys_ptrace(int request, pid_t pid, void *addr, void *data) 14 + { 15 + return syscall(SYS_ptrace, request, pid, addr, data); 16 + } 17 + 18 + TEST(get_set_sud) 19 + { 20 + struct ptrace_sud_config config; 21 + pid_t child; 22 + int ret = 0; 23 + int status; 24 + 25 + child = fork(); 26 + ASSERT_GE(child, 0); 27 + if (child == 0) { 28 + ASSERT_EQ(0, sys_ptrace(PTRACE_TRACEME, 0, 0, 0)) { 29 + TH_LOG("PTRACE_TRACEME: %m"); 30 + } 31 + kill(getpid(), SIGSTOP); 32 + _exit(1); 33 + } 34 + 35 + waitpid(child, &status, 0); 36 + 37 + memset(&config, 0xff, sizeof(config)); 38 + config.mode = PR_SYS_DISPATCH_ON; 39 + 40 + ret = sys_ptrace(PTRACE_GET_SYSCALL_USER_DISPATCH_CONFIG, child, 41 + (void *)sizeof(config), &config); 42 + 43 + ASSERT_EQ(ret, 0); 44 + ASSERT_EQ(config.mode, PR_SYS_DISPATCH_OFF); 45 + ASSERT_EQ(config.selector, 0); 46 + ASSERT_EQ(config.offset, 0); 47 + ASSERT_EQ(config.len, 0); 48 + 49 + config.mode = PR_SYS_DISPATCH_ON; 50 + config.selector = 0; 51 + config.offset = 0x400000; 52 + config.len = 0x1000; 53 + 54 + ret = sys_ptrace(PTRACE_SET_SYSCALL_USER_DISPATCH_CONFIG, child, 55 + (void *)sizeof(config), &config); 56 + 57 + ASSERT_EQ(ret, 0); 58 + 59 + memset(&config, 1, sizeof(config)); 60 + ret = sys_ptrace(PTRACE_GET_SYSCALL_USER_DISPATCH_CONFIG, child, 61 + (void *)sizeof(config), &config); 62 + 63 + ASSERT_EQ(ret, 0); 64 + ASSERT_EQ(config.mode, PR_SYS_DISPATCH_ON); 65 + ASSERT_EQ(config.selector, 0); 66 + ASSERT_EQ(config.offset, 0x400000); 67 + ASSERT_EQ(config.len, 0x1000); 68 + 69 + kill(child, SIGKILL); 70 + } 71 + 72 + TEST_HARNESS_MAIN