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