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