xref: /aosp_15_r20/external/ltp/testcases/kernel/syscalls/ptrace/ptrace06.c (revision 49cdfc7efb34551c7342be41a7384b9c40d7cab7)
1 /*
2  * check out-of-bound/unaligned addresses given to
3  *  - {PEEK,POKE}{DATA,TEXT,USER}
4  *  - {GET,SET}{,FG}REGS
5  *  - {GET,SET}SIGINFO
6  *
7  * Copyright (c) 2008 Analog Devices Inc.
8  *
9  * Licensed under the GPL-2 or later
10  */
11 
12 #define _GNU_SOURCE
13 
14 #include <errno.h>
15 #include <stdbool.h>
16 #include <stdio.h>
17 #include <stdlib.h>
18 #include <unistd.h>
19 #include <sys/ptrace.h>
20 
21 #include "test.h"
22 #include "spawn_ptrace_child.h"
23 
24 /* this should be sizeof(struct user), but that info is only found
25  * in the kernel asm/user.h which is not exported to userspace.
26  */
27 #if defined(__i386__)
28 #define SIZEOF_USER 284
29 #elif defined(__x86_64__)
30 #define SIZEOF_USER 928
31 #else
32 #define SIZEOF_USER 0x1000	/* just pick a big number */
33 #endif
34 
35 char *TCID = "ptrace06";
36 
37 struct test_case_t {
38 	int request;
39 	long addr;
40 	long data;
41 } test_cases[] = {
42 	{
43 	PTRACE_PEEKDATA,.addr = 0}, {
44 	PTRACE_PEEKDATA,.addr = 1}, {
45 	PTRACE_PEEKDATA,.addr = 2}, {
46 	PTRACE_PEEKDATA,.addr = 3}, {
47 	PTRACE_PEEKDATA,.addr = -1}, {
48 	PTRACE_PEEKDATA,.addr = -2}, {
49 	PTRACE_PEEKDATA,.addr = -3}, {
50 	PTRACE_PEEKDATA,.addr = -4}, {
51 	PTRACE_PEEKTEXT,.addr = 0}, {
52 	PTRACE_PEEKTEXT,.addr = 1}, {
53 	PTRACE_PEEKTEXT,.addr = 2}, {
54 	PTRACE_PEEKTEXT,.addr = 3}, {
55 	PTRACE_PEEKTEXT,.addr = -1}, {
56 	PTRACE_PEEKTEXT,.addr = -2}, {
57 	PTRACE_PEEKTEXT,.addr = -3}, {
58 	PTRACE_PEEKTEXT,.addr = -4}, {
59 	PTRACE_PEEKUSER,.addr = SIZEOF_USER + 1}, {
60 	PTRACE_PEEKUSER,.addr = SIZEOF_USER + 2}, {
61 	PTRACE_PEEKUSER,.addr = SIZEOF_USER + 3}, {
62 	PTRACE_PEEKUSER,.addr = SIZEOF_USER + 4}, {
63 	PTRACE_PEEKUSER,.addr = -1}, {
64 	PTRACE_PEEKUSER,.addr = -2}, {
65 	PTRACE_PEEKUSER,.addr = -3}, {
66 	PTRACE_PEEKUSER,.addr = -4}, {
67 	PTRACE_POKEDATA,.addr = 0}, {
68 	PTRACE_POKEDATA,.addr = 1}, {
69 	PTRACE_POKEDATA,.addr = 2}, {
70 	PTRACE_POKEDATA,.addr = 3}, {
71 	PTRACE_POKEDATA,.addr = -1}, {
72 	PTRACE_POKEDATA,.addr = -2}, {
73 	PTRACE_POKEDATA,.addr = -3}, {
74 	PTRACE_POKEDATA,.addr = -4}, {
75 	PTRACE_POKETEXT,.addr = 0}, {
76 	PTRACE_POKETEXT,.addr = 1}, {
77 	PTRACE_POKETEXT,.addr = 2}, {
78 	PTRACE_POKETEXT,.addr = 3}, {
79 	PTRACE_POKETEXT,.addr = -1}, {
80 	PTRACE_POKETEXT,.addr = -2}, {
81 	PTRACE_POKETEXT,.addr = -3}, {
82 	PTRACE_POKETEXT,.addr = -4}, {
83 	PTRACE_POKEUSER,.addr = SIZEOF_USER + 1}, {
84 	PTRACE_POKEUSER,.addr = SIZEOF_USER + 2}, {
85 	PTRACE_POKEUSER,.addr = SIZEOF_USER + 3}, {
86 	PTRACE_POKEUSER,.addr = SIZEOF_USER + 4}, {
87 	PTRACE_POKEUSER,.addr = -1}, {
88 	PTRACE_POKEUSER,.addr = -2}, {
89 	PTRACE_POKEUSER,.addr = -3}, {
90 	PTRACE_POKEUSER,.addr = -4},
91 #ifdef PTRACE_GETREGS
92 	{
93 	PTRACE_GETREGS,.data = 0}, {
94 	PTRACE_GETREGS,.data = 1}, {
95 	PTRACE_GETREGS,.data = 2}, {
96 	PTRACE_GETREGS,.data = 3}, {
97 	PTRACE_GETREGS,.data = -1}, {
98 	PTRACE_GETREGS,.data = -2}, {
99 	PTRACE_GETREGS,.data = -3}, {
100 	PTRACE_GETREGS,.data = -4},
101 #endif
102 #ifdef PTRACE_GETFGREGS
103 	{
104 	PTRACE_GETFGREGS,.data = 0}, {
105 	PTRACE_GETFGREGS,.data = 1}, {
106 	PTRACE_GETFGREGS,.data = 2}, {
107 	PTRACE_GETFGREGS,.data = 3}, {
108 	PTRACE_GETFGREGS,.data = -1}, {
109 	PTRACE_GETFGREGS,.data = -2}, {
110 	PTRACE_GETFGREGS,.data = -3}, {
111 	PTRACE_GETFGREGS,.data = -4},
112 #endif
113 #ifdef PTRACE_SETREGS
114 	{
115 	PTRACE_SETREGS,.data = 0}, {
116 	PTRACE_SETREGS,.data = 1}, {
117 	PTRACE_SETREGS,.data = 2}, {
118 	PTRACE_SETREGS,.data = 3}, {
119 	PTRACE_SETREGS,.data = -1}, {
120 	PTRACE_SETREGS,.data = -2}, {
121 	PTRACE_SETREGS,.data = -3}, {
122 	PTRACE_SETREGS,.data = -4},
123 #endif
124 #ifdef PTRACE_SETFGREGS
125 	{
126 	PTRACE_SETFGREGS,.data = 0}, {
127 	PTRACE_SETFGREGS,.data = 1}, {
128 	PTRACE_SETFGREGS,.data = 2}, {
129 	PTRACE_SETFGREGS,.data = 3}, {
130 	PTRACE_SETFGREGS,.data = -1}, {
131 	PTRACE_SETFGREGS,.data = -2}, {
132 	PTRACE_SETFGREGS,.data = -3}, {
133 	PTRACE_SETFGREGS,.data = -4},
134 #endif
135 #if HAVE_DECL_PTRACE_GETSIGINFO
136 	{
137 	PTRACE_GETSIGINFO,.data = 0}, {
138 	PTRACE_GETSIGINFO,.data = 1}, {
139 	PTRACE_GETSIGINFO,.data = 2}, {
140 	PTRACE_GETSIGINFO,.data = 3}, {
141 	PTRACE_GETSIGINFO,.data = -1}, {
142 	PTRACE_GETSIGINFO,.data = -2}, {
143 	PTRACE_GETSIGINFO,.data = -3}, {
144 	PTRACE_GETSIGINFO,.data = -4},
145 #endif
146 #if HAVE_DECL_PTRACE_SETSIGINFO
147 	{
148 	PTRACE_SETSIGINFO,.data = 0}, {
149 	PTRACE_SETSIGINFO,.data = 1}, {
150 	PTRACE_SETSIGINFO,.data = 2}, {
151 	PTRACE_SETSIGINFO,.data = 3}, {
152 	PTRACE_SETSIGINFO,.data = -1}, {
153 	PTRACE_SETSIGINFO,.data = -2}, {
154 	PTRACE_SETSIGINFO,.data = -3}, {
155 	PTRACE_SETSIGINFO,.data = -4},
156 #endif
157 };
158 
159 int TST_TOTAL = ARRAY_SIZE(test_cases);
160 
main(int argc,char * argv[])161 int main(int argc, char *argv[])
162 {
163 	size_t i;
164 	long ret;
165 	int saved_errno;
166 
167 	tst_parse_opts(argc, argv, NULL, NULL);
168 
169 	make_a_baby(argc, argv);
170 
171 	for (i = 0; i < ARRAY_SIZE(test_cases); ++i) {
172 		struct test_case_t *tc = &test_cases[i];
173 
174 		errno = 0;
175 		ret =
176 		    ptrace(tc->request, pid, (void *)tc->addr,
177 			   (void *)tc->data);
178 		saved_errno = errno;
179 		if (ret != -1)
180 			tst_resm(TFAIL,
181 				 "ptrace(%s, ..., %li, %li) returned %li instead of -1",
182 				 strptrace(tc->request), tc->addr, tc->data,
183 				 ret);
184 		else if (saved_errno != EIO && saved_errno != EFAULT)
185 			tst_resm(TFAIL,
186 				 "ptrace(%s, ..., %li, %li) expected errno EIO or EFAULT; actual: %i (%s)",
187 				 strptrace(tc->request), tc->addr, tc->data,
188 				 saved_errno, strerror(saved_errno));
189 		else
190 			tst_resm(TPASS,
191 				 "ptrace(%s, ..., %li, %li) failed as expected",
192 				 strptrace(tc->request), tc->addr, tc->data);
193 	}
194 
195 	/* hopefully this worked */
196 	ptrace(PTRACE_KILL, pid, NULL, NULL);
197 
198 	tst_exit();
199 }
200