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