1 /* $NetBSD: t_ptrace_bytetransfer_wait.h,v 1.1 2020/05/04 22:05:28 kamil Exp $ */
2
3 /*-
4 * Copyright (c) 2016, 2017, 2018, 2019, 2020 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
17 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
18 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE.
27 */
28
29
30 enum bytes_transfer_type {
31 BYTES_TRANSFER_DATA,
32 BYTES_TRANSFER_DATAIO,
33 BYTES_TRANSFER_TEXT,
34 BYTES_TRANSFER_TEXTIO,
35 BYTES_TRANSFER_AUXV
36 };
37
38 static int __used
bytes_transfer_dummy(int a,int b,int c,int d)39 bytes_transfer_dummy(int a, int b, int c, int d)
40 {
41 int e, f, g, h;
42
43 a *= 4;
44 b += 3;
45 c -= 2;
46 d /= 1;
47
48 e = strtol("10", NULL, 10);
49 f = strtol("20", NULL, 10);
50 g = strtol("30", NULL, 10);
51 h = strtol("40", NULL, 10);
52
53 return (a + b * c - d) + (e * f - g / h);
54 }
55
56 static void
bytes_transfer(int operation,size_t size,enum bytes_transfer_type type)57 bytes_transfer(int operation, size_t size, enum bytes_transfer_type type)
58 {
59 const int exitval = 5;
60 const int sigval = SIGSTOP;
61 pid_t child, wpid;
62 bool skip = false;
63
64 int lookup_me = 0;
65 uint8_t lookup_me8 = 0;
66 uint16_t lookup_me16 = 0;
67 uint32_t lookup_me32 = 0;
68 uint64_t lookup_me64 = 0;
69
70 int magic = 0x13579246;
71 uint8_t magic8 = 0xab;
72 uint16_t magic16 = 0x1234;
73 uint32_t magic32 = 0x98765432;
74 uint64_t magic64 = 0xabcdef0123456789;
75
76 struct ptrace_io_desc io;
77 #if defined(TWAIT_HAVE_STATUS)
78 int status;
79 #endif
80 /* 513 is just enough, for the purposes of ATF it's good enough */
81 AuxInfo ai[513], *aip;
82
83 ATF_REQUIRE(size < sizeof(ai));
84
85 /* Prepare variables for .TEXT transfers */
86 switch (type) {
87 case BYTES_TRANSFER_TEXT:
88 memcpy(&magic, bytes_transfer_dummy, sizeof(magic));
89 break;
90 case BYTES_TRANSFER_TEXTIO:
91 switch (size) {
92 case 8:
93 memcpy(&magic8, bytes_transfer_dummy, sizeof(magic8));
94 break;
95 case 16:
96 memcpy(&magic16, bytes_transfer_dummy, sizeof(magic16));
97 break;
98 case 32:
99 memcpy(&magic32, bytes_transfer_dummy, sizeof(magic32));
100 break;
101 case 64:
102 memcpy(&magic64, bytes_transfer_dummy, sizeof(magic64));
103 break;
104 }
105 break;
106 default:
107 break;
108 }
109
110 /* Prepare variables for PIOD and AUXV transfers */
111 switch (type) {
112 case BYTES_TRANSFER_TEXTIO:
113 case BYTES_TRANSFER_DATAIO:
114 io.piod_op = operation;
115 switch (size) {
116 case 8:
117 io.piod_offs = (type == BYTES_TRANSFER_TEXTIO) ?
118 (void *)bytes_transfer_dummy :
119 &lookup_me8;
120 io.piod_addr = &lookup_me8;
121 io.piod_len = sizeof(lookup_me8);
122 break;
123 case 16:
124 io.piod_offs = (type == BYTES_TRANSFER_TEXTIO) ?
125 (void *)bytes_transfer_dummy :
126 &lookup_me16;
127 io.piod_addr = &lookup_me16;
128 io.piod_len = sizeof(lookup_me16);
129 break;
130 case 32:
131 io.piod_offs = (type == BYTES_TRANSFER_TEXTIO) ?
132 (void *)bytes_transfer_dummy :
133 &lookup_me32;
134 io.piod_addr = &lookup_me32;
135 io.piod_len = sizeof(lookup_me32);
136 break;
137 case 64:
138 io.piod_offs = (type == BYTES_TRANSFER_TEXTIO) ?
139 (void *)bytes_transfer_dummy :
140 &lookup_me64;
141 io.piod_addr = &lookup_me64;
142 io.piod_len = sizeof(lookup_me64);
143 break;
144 default:
145 break;
146 }
147 break;
148 case BYTES_TRANSFER_AUXV:
149 io.piod_op = operation;
150 io.piod_offs = 0;
151 io.piod_addr = ai;
152 io.piod_len = size;
153 break;
154 default:
155 break;
156 }
157
158 DPRINTF("Before forking process PID=%d\n", getpid());
159 SYSCALL_REQUIRE((child = fork()) != -1);
160 if (child == 0) {
161 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
162 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
163
164 switch (type) {
165 case BYTES_TRANSFER_DATA:
166 switch (operation) {
167 case PT_READ_D:
168 case PT_READ_I:
169 lookup_me = magic;
170 break;
171 default:
172 break;
173 }
174 break;
175 case BYTES_TRANSFER_DATAIO:
176 switch (operation) {
177 case PIOD_READ_D:
178 case PIOD_READ_I:
179 switch (size) {
180 case 8:
181 lookup_me8 = magic8;
182 break;
183 case 16:
184 lookup_me16 = magic16;
185 break;
186 case 32:
187 lookup_me32 = magic32;
188 break;
189 case 64:
190 lookup_me64 = magic64;
191 break;
192 default:
193 break;
194 }
195 break;
196 default:
197 break;
198 }
199 default:
200 break;
201 }
202
203 DPRINTF("Before raising %s from child\n", strsignal(sigval));
204 FORKEE_ASSERT(raise(sigval) == 0);
205
206 /* Handle PIOD and PT separately as operation values overlap */
207 switch (type) {
208 case BYTES_TRANSFER_DATA:
209 switch (operation) {
210 case PT_WRITE_D:
211 case PT_WRITE_I:
212 FORKEE_ASSERT_EQ(lookup_me, magic);
213 break;
214 default:
215 break;
216 }
217 break;
218 case BYTES_TRANSFER_DATAIO:
219 switch (operation) {
220 case PIOD_WRITE_D:
221 case PIOD_WRITE_I:
222 switch (size) {
223 case 8:
224 FORKEE_ASSERT_EQ(lookup_me8, magic8);
225 break;
226 case 16:
227 FORKEE_ASSERT_EQ(lookup_me16, magic16);
228 break;
229 case 32:
230 FORKEE_ASSERT_EQ(lookup_me32, magic32);
231 break;
232 case 64:
233 FORKEE_ASSERT_EQ(lookup_me64, magic64);
234 break;
235 default:
236 break;
237 }
238 break;
239 default:
240 break;
241 }
242 break;
243 case BYTES_TRANSFER_TEXT:
244 FORKEE_ASSERT(memcmp(&magic, bytes_transfer_dummy,
245 sizeof(magic)) == 0);
246 break;
247 case BYTES_TRANSFER_TEXTIO:
248 switch (size) {
249 case 8:
250 FORKEE_ASSERT(memcmp(&magic8,
251 bytes_transfer_dummy,
252 sizeof(magic8)) == 0);
253 break;
254 case 16:
255 FORKEE_ASSERT(memcmp(&magic16,
256 bytes_transfer_dummy,
257 sizeof(magic16)) == 0);
258 break;
259 case 32:
260 FORKEE_ASSERT(memcmp(&magic32,
261 bytes_transfer_dummy,
262 sizeof(magic32)) == 0);
263 break;
264 case 64:
265 FORKEE_ASSERT(memcmp(&magic64,
266 bytes_transfer_dummy,
267 sizeof(magic64)) == 0);
268 break;
269 }
270 break;
271 default:
272 break;
273 }
274
275 DPRINTF("Before exiting of the child process\n");
276 _exit(exitval);
277 }
278 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
279
280 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
281 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
282
283 validate_status_stopped(status, sigval);
284
285 /* Check PaX MPROTECT */
286 if (!can_we_write_to_text(child)) {
287 switch (type) {
288 case BYTES_TRANSFER_TEXTIO:
289 switch (operation) {
290 case PIOD_WRITE_D:
291 case PIOD_WRITE_I:
292 skip = true;
293 break;
294 default:
295 break;
296 }
297 break;
298 case BYTES_TRANSFER_TEXT:
299 switch (operation) {
300 case PT_WRITE_D:
301 case PT_WRITE_I:
302 skip = true;
303 break;
304 default:
305 break;
306 }
307 break;
308 default:
309 break;
310 }
311 }
312
313 /* Bailout cleanly killing the child process */
314 if (skip) {
315 SYSCALL_REQUIRE(ptrace(PT_KILL, child, (void *)1, 0) != -1);
316 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
317 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
318 child);
319
320 validate_status_signaled(status, SIGKILL, 0);
321
322 atf_tc_skip("PaX MPROTECT setup prevents writes to .text");
323 }
324
325 DPRINTF("Calling operation to transfer bytes between child=%d and "
326 "parent=%d\n", child, getpid());
327
328 switch (type) {
329 case BYTES_TRANSFER_TEXTIO:
330 case BYTES_TRANSFER_DATAIO:
331 case BYTES_TRANSFER_AUXV:
332 switch (operation) {
333 case PIOD_WRITE_D:
334 case PIOD_WRITE_I:
335 switch (size) {
336 case 8:
337 lookup_me8 = magic8;
338 break;
339 case 16:
340 lookup_me16 = magic16;
341 break;
342 case 32:
343 lookup_me32 = magic32;
344 break;
345 case 64:
346 lookup_me64 = magic64;
347 break;
348 default:
349 break;
350 }
351 break;
352 default:
353 break;
354 }
355 SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
356 switch (operation) {
357 case PIOD_READ_D:
358 case PIOD_READ_I:
359 switch (size) {
360 case 8:
361 ATF_REQUIRE_EQ(lookup_me8, magic8);
362 break;
363 case 16:
364 ATF_REQUIRE_EQ(lookup_me16, magic16);
365 break;
366 case 32:
367 ATF_REQUIRE_EQ(lookup_me32, magic32);
368 break;
369 case 64:
370 ATF_REQUIRE_EQ(lookup_me64, magic64);
371 break;
372 default:
373 break;
374 }
375 break;
376 case PIOD_READ_AUXV:
377 DPRINTF("Asserting that AUXV length (%zu) is > 0\n",
378 io.piod_len);
379 ATF_REQUIRE(io.piod_len > 0);
380 for (aip = ai; aip->a_type != AT_NULL; aip++)
381 DPRINTF("a_type=%#llx a_v=%#llx\n",
382 (long long int)aip->a_type,
383 (long long int)aip->a_v);
384 break;
385 default:
386 break;
387 }
388 break;
389 case BYTES_TRANSFER_TEXT:
390 switch (operation) {
391 case PT_READ_D:
392 case PT_READ_I:
393 errno = 0;
394 lookup_me = ptrace(operation, child,
395 bytes_transfer_dummy, 0);
396 ATF_REQUIRE_EQ(lookup_me, magic);
397 SYSCALL_REQUIRE_ERRNO(errno, 0);
398 break;
399 case PT_WRITE_D:
400 case PT_WRITE_I:
401 SYSCALL_REQUIRE(ptrace(operation, child,
402 bytes_transfer_dummy, magic)
403 != -1);
404 break;
405 default:
406 break;
407 }
408 break;
409 case BYTES_TRANSFER_DATA:
410 switch (operation) {
411 case PT_READ_D:
412 case PT_READ_I:
413 errno = 0;
414 lookup_me = ptrace(operation, child, &lookup_me, 0);
415 ATF_REQUIRE_EQ(lookup_me, magic);
416 SYSCALL_REQUIRE_ERRNO(errno, 0);
417 break;
418 case PT_WRITE_D:
419 case PT_WRITE_I:
420 lookup_me = magic;
421 SYSCALL_REQUIRE(ptrace(operation, child, &lookup_me,
422 magic) != -1);
423 break;
424 default:
425 break;
426 }
427 break;
428 default:
429 break;
430 }
431
432 DPRINTF("Before resuming the child process where it left off and "
433 "without signal to be sent\n");
434 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
435
436 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
437 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
438
439 validate_status_exited(status, exitval);
440
441 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
442 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
443 }
444
445 #define BYTES_TRANSFER(test, operation, size, type) \
446 ATF_TC(test); \
447 ATF_TC_HEAD(test, tc) \
448 { \
449 atf_tc_set_md_var(tc, "descr", \
450 "Verify bytes transfer operation" #operation " and size " #size \
451 " of type " #type); \
452 } \
453 \
454 ATF_TC_BODY(test, tc) \
455 { \
456 \
457 bytes_transfer(operation, size, BYTES_TRANSFER_##type); \
458 }
459
460 // DATA
461
462 BYTES_TRANSFER(bytes_transfer_piod_read_d_8, PIOD_READ_D, 8, DATAIO)
463 BYTES_TRANSFER(bytes_transfer_piod_read_d_16, PIOD_READ_D, 16, DATAIO)
464 BYTES_TRANSFER(bytes_transfer_piod_read_d_32, PIOD_READ_D, 32, DATAIO)
465 BYTES_TRANSFER(bytes_transfer_piod_read_d_64, PIOD_READ_D, 64, DATAIO)
466
467 BYTES_TRANSFER(bytes_transfer_piod_read_i_8, PIOD_READ_I, 8, DATAIO)
468 BYTES_TRANSFER(bytes_transfer_piod_read_i_16, PIOD_READ_I, 16, DATAIO)
469 BYTES_TRANSFER(bytes_transfer_piod_read_i_32, PIOD_READ_I, 32, DATAIO)
470 BYTES_TRANSFER(bytes_transfer_piod_read_i_64, PIOD_READ_I, 64, DATAIO)
471
472 BYTES_TRANSFER(bytes_transfer_piod_write_d_8, PIOD_WRITE_D, 8, DATAIO)
473 BYTES_TRANSFER(bytes_transfer_piod_write_d_16, PIOD_WRITE_D, 16, DATAIO)
474 BYTES_TRANSFER(bytes_transfer_piod_write_d_32, PIOD_WRITE_D, 32, DATAIO)
475 BYTES_TRANSFER(bytes_transfer_piod_write_d_64, PIOD_WRITE_D, 64, DATAIO)
476
477 BYTES_TRANSFER(bytes_transfer_piod_write_i_8, PIOD_WRITE_I, 8, DATAIO)
478 BYTES_TRANSFER(bytes_transfer_piod_write_i_16, PIOD_WRITE_I, 16, DATAIO)
479 BYTES_TRANSFER(bytes_transfer_piod_write_i_32, PIOD_WRITE_I, 32, DATAIO)
480 BYTES_TRANSFER(bytes_transfer_piod_write_i_64, PIOD_WRITE_I, 64, DATAIO)
481
482 BYTES_TRANSFER(bytes_transfer_read_d, PT_READ_D, 32, DATA)
483 BYTES_TRANSFER(bytes_transfer_read_i, PT_READ_I, 32, DATA)
484 BYTES_TRANSFER(bytes_transfer_write_d, PT_WRITE_D, 32, DATA)
485 BYTES_TRANSFER(bytes_transfer_write_i, PT_WRITE_I, 32, DATA)
486
487 // TEXT
488
489 BYTES_TRANSFER(bytes_transfer_piod_read_d_8_text, PIOD_READ_D, 8, TEXTIO)
490 BYTES_TRANSFER(bytes_transfer_piod_read_d_16_text, PIOD_READ_D, 16, TEXTIO)
491 BYTES_TRANSFER(bytes_transfer_piod_read_d_32_text, PIOD_READ_D, 32, TEXTIO)
492 BYTES_TRANSFER(bytes_transfer_piod_read_d_64_text, PIOD_READ_D, 64, TEXTIO)
493
494 BYTES_TRANSFER(bytes_transfer_piod_read_i_8_text, PIOD_READ_I, 8, TEXTIO)
495 BYTES_TRANSFER(bytes_transfer_piod_read_i_16_text, PIOD_READ_I, 16, TEXTIO)
496 BYTES_TRANSFER(bytes_transfer_piod_read_i_32_text, PIOD_READ_I, 32, TEXTIO)
497 BYTES_TRANSFER(bytes_transfer_piod_read_i_64_text, PIOD_READ_I, 64, TEXTIO)
498
499 BYTES_TRANSFER(bytes_transfer_piod_write_d_8_text, PIOD_WRITE_D, 8, TEXTIO)
500 BYTES_TRANSFER(bytes_transfer_piod_write_d_16_text, PIOD_WRITE_D, 16, TEXTIO)
501 BYTES_TRANSFER(bytes_transfer_piod_write_d_32_text, PIOD_WRITE_D, 32, TEXTIO)
502 BYTES_TRANSFER(bytes_transfer_piod_write_d_64_text, PIOD_WRITE_D, 64, TEXTIO)
503
504 BYTES_TRANSFER(bytes_transfer_piod_write_i_8_text, PIOD_WRITE_I, 8, TEXTIO)
505 BYTES_TRANSFER(bytes_transfer_piod_write_i_16_text, PIOD_WRITE_I, 16, TEXTIO)
506 BYTES_TRANSFER(bytes_transfer_piod_write_i_32_text, PIOD_WRITE_I, 32, TEXTIO)
507 BYTES_TRANSFER(bytes_transfer_piod_write_i_64_text, PIOD_WRITE_I, 64, TEXTIO)
508
509 BYTES_TRANSFER(bytes_transfer_read_d_text, PT_READ_D, 32, TEXT)
510 BYTES_TRANSFER(bytes_transfer_read_i_text, PT_READ_I, 32, TEXT)
511 BYTES_TRANSFER(bytes_transfer_write_d_text, PT_WRITE_D, 32, TEXT)
512 BYTES_TRANSFER(bytes_transfer_write_i_text, PT_WRITE_I, 32, TEXT)
513
514 // AUXV
515
516 BYTES_TRANSFER(bytes_transfer_piod_read_auxv, PIOD_READ_AUXV, 4096, AUXV)
517
518 /// ----------------------------------------------------------------------------
519
520 static void
bytes_transfer_alignment(const char * operation)521 bytes_transfer_alignment(const char *operation)
522 {
523 const int exitval = 5;
524 const int sigval = SIGSTOP;
525 pid_t child, wpid;
526 #if defined(TWAIT_HAVE_STATUS)
527 int status;
528 #endif
529 char *buffer;
530 int vector;
531 size_t len;
532 size_t i;
533 int op;
534
535 struct ptrace_io_desc io;
536 struct ptrace_siginfo info;
537
538 memset(&io, 0, sizeof(io));
539 memset(&info, 0, sizeof(info));
540
541 /* Testing misaligned byte transfer crossing page boundaries */
542 len = sysconf(_SC_PAGESIZE) * 2;
543 buffer = malloc(len);
544 ATF_REQUIRE(buffer != NULL);
545
546 /* Initialize the buffer with random data */
547 for (i = 0; i < len; i++)
548 buffer[i] = i & 0xff;
549
550 DPRINTF("Before forking process PID=%d\n", getpid());
551 SYSCALL_REQUIRE((child = fork()) != -1);
552 if (child == 0) {
553 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
554 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
555
556 DPRINTF("Before raising %s from child\n", strsignal(sigval));
557 FORKEE_ASSERT(raise(sigval) == 0);
558
559 DPRINTF("Before exiting of the child process\n");
560 _exit(exitval);
561 }
562 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
563
564 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
565 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
566
567 validate_status_stopped(status, sigval);
568
569 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
570 SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info))
571 != -1);
572
573 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
574 DPRINTF("Signal properties: si_signo=%#x si_code=%#x "
575 "si_errno=%#x\n",
576 info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
577 info.psi_siginfo.si_errno);
578
579 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
580 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
581
582 if (strcmp(operation, "PT_READ_I") == 0 ||
583 strcmp(operation, "PT_READ_D") == 0) {
584 if (strcmp(operation, "PT_READ_I"))
585 op = PT_READ_I;
586 else
587 op = PT_READ_D;
588
589 for (i = 0; i <= (len - sizeof(int)); i++) {
590 errno = 0;
591 vector = ptrace(op, child, buffer + i, 0);
592 ATF_REQUIRE_EQ(errno, 0);
593 ATF_REQUIRE(!memcmp(&vector, buffer + i, sizeof(int)));
594 }
595 } else if (strcmp(operation, "PT_WRITE_I") == 0 ||
596 strcmp(operation, "PT_WRITE_D") == 0) {
597 if (strcmp(operation, "PT_WRITE_I"))
598 op = PT_WRITE_I;
599 else
600 op = PT_WRITE_D;
601
602 for (i = 0; i <= (len - sizeof(int)); i++) {
603 memcpy(&vector, buffer + i, sizeof(int));
604 SYSCALL_REQUIRE(ptrace(op, child, buffer + 1, vector)
605 != -1);
606 }
607 } else if (strcmp(operation, "PIOD_READ_I") == 0 ||
608 strcmp(operation, "PIOD_READ_D") == 0) {
609 if (strcmp(operation, "PIOD_READ_I"))
610 op = PIOD_READ_I;
611 else
612 op = PIOD_READ_D;
613
614 io.piod_op = op;
615 io.piod_addr = &vector;
616 io.piod_len = sizeof(int);
617
618 for (i = 0; i <= (len - sizeof(int)); i++) {
619 io.piod_offs = buffer + i;
620
621 SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, sizeof(io))
622 != -1);
623 ATF_REQUIRE(!memcmp(&vector, buffer + i, sizeof(int)));
624 }
625 } else if (strcmp(operation, "PIOD_WRITE_I") == 0 ||
626 strcmp(operation, "PIOD_WRITE_D") == 0) {
627 if (strcmp(operation, "PIOD_WRITE_I"))
628 op = PIOD_WRITE_I;
629 else
630 op = PIOD_WRITE_D;
631
632 io.piod_op = op;
633 io.piod_addr = &vector;
634 io.piod_len = sizeof(int);
635
636 for (i = 0; i <= (len - sizeof(int)); i++) {
637 io.piod_offs = buffer + i;
638
639 SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, sizeof(io))
640 != -1);
641 }
642 } else if (strcmp(operation, "PIOD_READ_AUXV") == 0) {
643 io.piod_op = PIOD_READ_AUXV;
644 io.piod_addr = &vector;
645 io.piod_len = sizeof(int);
646
647 errno = 0;
648 i = 0;
649 /* Read the whole AUXV vector, it has no clear length */
650 while (io.piod_len > 0) {
651 io.piod_offs = (void *)(intptr_t)i;
652 SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, sizeof(io))
653 != -1 || (io.piod_len == 0 && i > 0));
654 ++i;
655 }
656 }
657
658 DPRINTF("Before resuming the child process where it left off "
659 "and without signal to be sent\n");
660 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
661
662 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
663 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
664 child);
665
666 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
667 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
668 }
669
670 #define BYTES_TRANSFER_ALIGNMENT(test, operation) \
671 ATF_TC(test); \
672 ATF_TC_HEAD(test, tc) \
673 { \
674 atf_tc_set_md_var(tc, "descr", \
675 "Verify bytes transfer for potentially misaligned " \
676 "operation " operation); \
677 } \
678 \
679 ATF_TC_BODY(test, tc) \
680 { \
681 \
682 bytes_transfer_alignment(operation); \
683 }
684
685 BYTES_TRANSFER_ALIGNMENT(bytes_transfer_alignment_pt_read_i, "PT_READ_I")
686 BYTES_TRANSFER_ALIGNMENT(bytes_transfer_alignment_pt_read_d, "PT_READ_D")
687 BYTES_TRANSFER_ALIGNMENT(bytes_transfer_alignment_pt_write_i, "PT_WRITE_I")
688 BYTES_TRANSFER_ALIGNMENT(bytes_transfer_alignment_pt_write_d, "PT_WRITE_D")
689
690 BYTES_TRANSFER_ALIGNMENT(bytes_transfer_alignment_piod_read_i, "PIOD_READ_I")
691 BYTES_TRANSFER_ALIGNMENT(bytes_transfer_alignment_piod_read_d, "PIOD_READ_D")
692 BYTES_TRANSFER_ALIGNMENT(bytes_transfer_alignment_piod_write_i, "PIOD_WRITE_I")
693 BYTES_TRANSFER_ALIGNMENT(bytes_transfer_alignment_piod_write_d, "PIOD_WRITE_D")
694
695 BYTES_TRANSFER_ALIGNMENT(bytes_transfer_alignment_piod_read_auxv, "PIOD_READ_AUXV")
696
697 /// ----------------------------------------------------------------------------
698
699 static void
bytes_transfer_eof(const char * operation)700 bytes_transfer_eof(const char *operation)
701 {
702 const int exitval = 5;
703 const int sigval = SIGSTOP;
704 pid_t child, wpid;
705 #if defined(TWAIT_HAVE_STATUS)
706 int status;
707 #endif
708 FILE *fp;
709 char *p;
710 int vector;
711 int op;
712
713 struct ptrace_io_desc io;
714 struct ptrace_siginfo info;
715
716 memset(&io, 0, sizeof(io));
717 memset(&info, 0, sizeof(info));
718
719 vector = 0;
720
721 fp = tmpfile();
722 ATF_REQUIRE(fp != NULL);
723
724 p = mmap(0, 1, PROT_READ|PROT_WRITE, MAP_PRIVATE, fileno(fp), 0);
725 ATF_REQUIRE(p != MAP_FAILED);
726
727 DPRINTF("Before forking process PID=%d\n", getpid());
728 SYSCALL_REQUIRE((child = fork()) != -1);
729 if (child == 0) {
730 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
731 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
732
733 DPRINTF("Before raising %s from child\n", strsignal(sigval));
734 FORKEE_ASSERT(raise(sigval) == 0);
735
736 DPRINTF("Before exiting of the child process\n");
737 _exit(exitval);
738 }
739 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
740
741 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
742 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
743
744 validate_status_stopped(status, sigval);
745
746 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
747 SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info))
748 != -1);
749
750 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
751 DPRINTF("Signal properties: si_signo=%#x si_code=%#x "
752 "si_errno=%#x\n",
753 info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
754 info.psi_siginfo.si_errno);
755
756 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
757 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
758
759 if (strcmp(operation, "PT_READ_I") == 0 ||
760 strcmp(operation, "PT_READ_D") == 0) {
761 if (strcmp(operation, "PT_READ_I"))
762 op = PT_READ_I;
763 else
764 op = PT_READ_D;
765
766 errno = 0;
767 SYSCALL_REQUIRE(ptrace(op, child, p, 0) == -1);
768 ATF_REQUIRE_EQ(errno, EINVAL);
769 } else if (strcmp(operation, "PT_WRITE_I") == 0 ||
770 strcmp(operation, "PT_WRITE_D") == 0) {
771 if (strcmp(operation, "PT_WRITE_I"))
772 op = PT_WRITE_I;
773 else
774 op = PT_WRITE_D;
775
776 errno = 0;
777 SYSCALL_REQUIRE(ptrace(op, child, p, vector) == -1);
778 ATF_REQUIRE_EQ(errno, EINVAL);
779 } else if (strcmp(operation, "PIOD_READ_I") == 0 ||
780 strcmp(operation, "PIOD_READ_D") == 0) {
781 if (strcmp(operation, "PIOD_READ_I"))
782 op = PIOD_READ_I;
783 else
784 op = PIOD_READ_D;
785
786 io.piod_op = op;
787 io.piod_addr = &vector;
788 io.piod_len = sizeof(int);
789 io.piod_offs = p;
790
791 errno = 0;
792 SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, sizeof(io)) == -1);
793 ATF_REQUIRE_EQ(errno, EINVAL);
794 } else if (strcmp(operation, "PIOD_WRITE_I") == 0 ||
795 strcmp(operation, "PIOD_WRITE_D") == 0) {
796 if (strcmp(operation, "PIOD_WRITE_I"))
797 op = PIOD_WRITE_I;
798 else
799 op = PIOD_WRITE_D;
800
801 io.piod_op = op;
802 io.piod_addr = &vector;
803 io.piod_len = sizeof(int);
804 io.piod_offs = p;
805
806 errno = 0;
807 SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, sizeof(io)) == -1);
808 ATF_REQUIRE_EQ(errno, EINVAL);
809 }
810
811 DPRINTF("Before resuming the child process where it left off "
812 "and without signal to be sent\n");
813 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
814
815 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
816 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
817 child);
818
819 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
820 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
821 }
822
823 #define BYTES_TRANSFER_EOF(test, operation) \
824 ATF_TC(test); \
825 ATF_TC_HEAD(test, tc) \
826 { \
827 atf_tc_set_md_var(tc, "descr", \
828 "Verify bytes EOF byte transfer for the " operation \
829 " operation"); \
830 } \
831 \
832 ATF_TC_BODY(test, tc) \
833 { \
834 \
835 bytes_transfer_eof(operation); \
836 }
837
838 BYTES_TRANSFER_EOF(bytes_transfer_eof_pt_read_i, "PT_READ_I")
839 BYTES_TRANSFER_EOF(bytes_transfer_eof_pt_read_d, "PT_READ_D")
840 BYTES_TRANSFER_EOF(bytes_transfer_eof_pt_write_i, "PT_WRITE_I")
841 BYTES_TRANSFER_EOF(bytes_transfer_eof_pt_write_d, "PT_WRITE_D")
842
843 BYTES_TRANSFER_EOF(bytes_transfer_eof_piod_read_i, "PIOD_READ_I")
844 BYTES_TRANSFER_EOF(bytes_transfer_eof_piod_read_d, "PIOD_READ_D")
845 BYTES_TRANSFER_EOF(bytes_transfer_eof_piod_write_i, "PIOD_WRITE_I")
846 BYTES_TRANSFER_EOF(bytes_transfer_eof_piod_write_d, "PIOD_WRITE_D")
847
848
849 #define ATF_TP_ADD_TCS_PTRACE_WAIT_BYTETRANSFER() \
850 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_8); \
851 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_16); \
852 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_32); \
853 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_64); \
854 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_8); \
855 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_16); \
856 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_32); \
857 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_64); \
858 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_8); \
859 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_16); \
860 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_32); \
861 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_64); \
862 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_8); \
863 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_16); \
864 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_32); \
865 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_64); \
866 ATF_TP_ADD_TC(tp, bytes_transfer_read_d); \
867 ATF_TP_ADD_TC(tp, bytes_transfer_read_i); \
868 ATF_TP_ADD_TC(tp, bytes_transfer_write_d); \
869 ATF_TP_ADD_TC(tp, bytes_transfer_write_i); \
870 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_8_text); \
871 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_16_text); \
872 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_32_text); \
873 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_64_text); \
874 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_8_text); \
875 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_16_text); \
876 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_32_text); \
877 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_64_text); \
878 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_8_text); \
879 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_16_text); \
880 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_32_text); \
881 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_64_text); \
882 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_8_text); \
883 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_16_text); \
884 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_32_text); \
885 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_64_text); \
886 ATF_TP_ADD_TC(tp, bytes_transfer_read_d_text); \
887 ATF_TP_ADD_TC(tp, bytes_transfer_read_i_text); \
888 ATF_TP_ADD_TC(tp, bytes_transfer_write_d_text); \
889 ATF_TP_ADD_TC(tp, bytes_transfer_write_i_text); \
890 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_auxv); \
891 ATF_TP_ADD_TC(tp, bytes_transfer_alignment_pt_read_i); \
892 ATF_TP_ADD_TC(tp, bytes_transfer_alignment_pt_read_d); \
893 ATF_TP_ADD_TC(tp, bytes_transfer_alignment_pt_write_i); \
894 ATF_TP_ADD_TC(tp, bytes_transfer_alignment_pt_write_d); \
895 ATF_TP_ADD_TC(tp, bytes_transfer_alignment_piod_read_i); \
896 ATF_TP_ADD_TC(tp, bytes_transfer_alignment_piod_read_d); \
897 ATF_TP_ADD_TC(tp, bytes_transfer_alignment_piod_write_i); \
898 ATF_TP_ADD_TC(tp, bytes_transfer_alignment_piod_write_d); \
899 ATF_TP_ADD_TC(tp, bytes_transfer_alignment_piod_read_auxv); \
900 ATF_TP_ADD_TC(tp, bytes_transfer_eof_pt_read_i); \
901 ATF_TP_ADD_TC(tp, bytes_transfer_eof_pt_read_d); \
902 ATF_TP_ADD_TC(tp, bytes_transfer_eof_pt_write_i); \
903 ATF_TP_ADD_TC(tp, bytes_transfer_eof_pt_write_d); \
904 ATF_TP_ADD_TC(tp, bytes_transfer_eof_piod_read_i); \
905 ATF_TP_ADD_TC(tp, bytes_transfer_eof_piod_read_d); \
906 ATF_TP_ADD_TC(tp, bytes_transfer_eof_piod_write_i); \
907 ATF_TP_ADD_TC(tp, bytes_transfer_eof_piod_write_d);
908