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 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 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 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 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