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 73