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 13static int sys_ptrace(int request, pid_t pid, void *addr, void *data) 14{ 15 return syscall(SYS_ptrace, request, pid, addr, data); 16} 17 18TEST(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 72TEST_HARNESS_MAIN 73