1 /* $NetBSD: t_ptrace_wait.c,v 1.9 2017/01/13 21:30:41 christos Exp $ */ 2 3 /*- 4 * Copyright (c) 2016 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 #include <sys/cdefs.h> 30 __RCSID("$NetBSD: t_ptrace_wait.c,v 1.9 2017/01/13 21:30:41 christos Exp $"); 31 32 #include <sys/param.h> 33 #include <sys/types.h> 34 #include <sys/ptrace.h> 35 #include <sys/resource.h> 36 #include <sys/stat.h> 37 #include <sys/sysctl.h> 38 #include <sys/wait.h> 39 #include <machine/reg.h> 40 #include <x86/dbregs.h> 41 #include <err.h> 42 #include <errno.h> 43 #include <sched.h> 44 #include <signal.h> 45 #include <stdint.h> 46 #include <stdio.h> 47 #include <stdlib.h> 48 #include <strings.h> 49 #include <unistd.h> 50 51 #include <atf-c.h> 52 53 #include "h_macros.h" 54 55 #include "../../t_ptrace_wait.h" 56 57 58 #if defined(HAVE_GPREGS) 59 ATF_TC(regs1); 60 ATF_TC_HEAD(regs1, tc) 61 { 62 atf_tc_set_md_var(tc, "descr", 63 "Call PT_GETREGS and iterate over General Purpose registers"); 64 } 65 66 ATF_TC_BODY(regs1, tc) 67 { 68 const int exitval = 5; 69 const int sigval = SIGSTOP; 70 pid_t child, wpid; 71 #if defined(TWAIT_HAVE_STATUS) 72 int status; 73 #endif 74 struct reg r; 75 76 printf("Before forking process PID=%d\n", getpid()); 77 ATF_REQUIRE((child = fork()) != -1); 78 if (child == 0) { 79 printf("Before calling PT_TRACE_ME from child %d\n", getpid()); 80 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 81 82 printf("Before raising %s from child\n", strsignal(sigval)); 83 FORKEE_ASSERT(raise(sigval) == 0); 84 85 printf("Before exiting of the child process\n"); 86 _exit(exitval); 87 } 88 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); 89 90 printf("Before calling %s() for the child\n", TWAIT_FNAME); 91 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 92 93 validate_status_stopped(status, sigval); 94 95 printf("Call GETREGS for the child process\n"); 96 ATF_REQUIRE(ptrace(PT_GETREGS, child, &r, 0) != -1); 97 98 printf("RAX=%#" PRIxREGISTER "\n", r.regs[_REG_RAX]); 99 printf("RBX=%#" PRIxREGISTER "\n", r.regs[_REG_RBX]); 100 printf("RCX=%#" PRIxREGISTER "\n", r.regs[_REG_RCX]); 101 printf("RDX=%#" PRIxREGISTER "\n", r.regs[_REG_RDX]); 102 103 printf("RDI=%#" PRIxREGISTER "\n", r.regs[_REG_RDI]); 104 printf("RSI=%#" PRIxREGISTER "\n", r.regs[_REG_RSI]); 105 106 printf("GS=%#" PRIxREGISTER "\n", r.regs[_REG_GS]); 107 printf("FS=%#" PRIxREGISTER "\n", r.regs[_REG_FS]); 108 printf("ES=%#" PRIxREGISTER "\n", r.regs[_REG_ES]); 109 printf("DS=%#" PRIxREGISTER "\n", r.regs[_REG_DS]); 110 printf("CS=%#" PRIxREGISTER "\n", r.regs[_REG_CS]); 111 printf("SS=%#" PRIxREGISTER "\n", r.regs[_REG_SS]); 112 113 printf("RSP=%#" PRIxREGISTER "\n", r.regs[_REG_RSP]); 114 printf("RIP=%#" PRIxREGISTER "\n", r.regs[_REG_RIP]); 115 116 printf("RFLAGS=%#" PRIxREGISTER "\n", r.regs[_REG_RFLAGS]); 117 118 printf("R8=%#" PRIxREGISTER "\n", r.regs[_REG_R8]); 119 printf("R9=%#" PRIxREGISTER "\n", r.regs[_REG_R9]); 120 printf("R10=%#" PRIxREGISTER "\n", r.regs[_REG_R10]); 121 printf("R11=%#" PRIxREGISTER "\n", r.regs[_REG_R11]); 122 printf("R12=%#" PRIxREGISTER "\n", r.regs[_REG_R12]); 123 printf("R13=%#" PRIxREGISTER "\n", r.regs[_REG_R13]); 124 printf("R14=%#" PRIxREGISTER "\n", r.regs[_REG_R14]); 125 printf("R15=%#" PRIxREGISTER "\n", r.regs[_REG_R15]); 126 127 printf("Before resuming the child process where it left off and " 128 "without signal to be sent\n"); 129 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 130 131 printf("Before calling %s() for the child\n", TWAIT_FNAME); 132 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 133 134 validate_status_exited(status, exitval); 135 136 printf("Before calling %s() for the child\n", TWAIT_FNAME); 137 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 138 } 139 #endif 140 141 #if defined(__HAVE_PTRACE_WATCHPOINTS) 142 ATF_TC(watchpoint_count); 143 ATF_TC_HEAD(watchpoint_count, tc) 144 { 145 atf_tc_set_md_var(tc, "descr", 146 "Call PT_COUNT_WATCHPOINTS and assert four available watchpoints"); 147 } 148 149 ATF_TC_BODY(watchpoint_count, tc) 150 { 151 const int exitval = 5; 152 const int sigval = SIGSTOP; 153 pid_t child, wpid; 154 #if defined(TWAIT_HAVE_STATUS) 155 int status; 156 #endif 157 int N; 158 159 printf("Before forking process PID=%d\n", getpid()); 160 ATF_REQUIRE((child = fork()) != -1); 161 if (child == 0) { 162 printf("Before calling PT_TRACE_ME from child %d\n", getpid()); 163 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 164 165 printf("Before raising %s from child\n", strsignal(sigval)); 166 FORKEE_ASSERT(raise(sigval) == 0); 167 168 printf("Before exiting of the child process\n"); 169 _exit(exitval); 170 } 171 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); 172 173 printf("Before calling %s() for the child\n", TWAIT_FNAME); 174 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 175 176 validate_status_stopped(status, sigval); 177 178 printf("Call GETREGS for the child process\n"); 179 ATF_REQUIRE((N = ptrace(PT_COUNT_WATCHPOINTS, child, NULL, 0)) != -1); 180 printf("Reported %d watchpoints\n", N); 181 182 ATF_REQUIRE_EQ_MSG(N, 4, "Expected 4 hw watchpoints - got %d", N); 183 184 printf("Before resuming the child process where it left off and " 185 "without signal to be sent\n"); 186 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 187 188 printf("Before calling %s() for the child\n", TWAIT_FNAME); 189 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 190 191 validate_status_exited(status, exitval); 192 193 printf("Before calling %s() for the child\n", TWAIT_FNAME); 194 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 195 } 196 #endif 197 198 #if defined(__HAVE_PTRACE_WATCHPOINTS) 199 ATF_TC(watchpoint_read); 200 ATF_TC_HEAD(watchpoint_read, tc) 201 { 202 atf_tc_set_md_var(tc, "descr", 203 "Call PT_COUNT_WATCHPOINTS and assert four available watchpoints"); 204 } 205 206 ATF_TC_BODY(watchpoint_read, tc) 207 { 208 const int exitval = 5; 209 const int sigval = SIGSTOP; 210 pid_t child, wpid; 211 #if defined(TWAIT_HAVE_STATUS) 212 int status; 213 #endif 214 int i, N; 215 struct ptrace_watchpoint pw; 216 int len = sizeof(pw); 217 218 printf("Before forking process PID=%d\n", getpid()); 219 ATF_REQUIRE((child = fork()) != -1); 220 if (child == 0) { 221 printf("Before calling PT_TRACE_ME from child %d\n", getpid()); 222 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 223 224 printf("Before raising %s from child\n", strsignal(sigval)); 225 FORKEE_ASSERT(raise(sigval) == 0); 226 227 printf("Before exiting of the child process\n"); 228 _exit(exitval); 229 } 230 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); 231 232 printf("Before calling %s() for the child\n", TWAIT_FNAME); 233 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 234 235 validate_status_stopped(status, sigval); 236 237 printf("Call GETREGS for the child process\n"); 238 ATF_REQUIRE((N = ptrace(PT_COUNT_WATCHPOINTS, child, NULL, 0)) != -1); 239 240 ATF_REQUIRE_EQ_MSG(N, 4, "Expected 4 hw watchpoints - got %d", N); 241 242 for (i = 0; i < N; i++) { 243 printf("Before reading watchpoint %d\n", i); 244 pw.pw_index = i; 245 ATF_REQUIRE(ptrace(PT_READ_WATCHPOINT, child, &pw, len) != -1); 246 247 printf("struct ptrace {\n"); 248 printf("\t.pw_index=%d\n", pw.pw_index); 249 printf("\t.pw_lwpid=%d\n", pw.pw_lwpid); 250 printf("\t.pw_md.md_address=%p\n", pw.pw_md.md_address); 251 printf("\t.pw_md.md_condition=%#x\n", pw.pw_md.md_condition); 252 printf("\t.pw_md.md_length=%#x\n", pw.pw_md.md_length); 253 printf("}\n"); 254 } 255 256 printf("Before resuming the child process where it left off and " 257 "without signal to be sent\n"); 258 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 259 260 printf("Before calling %s() for the child\n", TWAIT_FNAME); 261 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 262 263 validate_status_exited(status, exitval); 264 265 printf("Before calling %s() for the child\n", TWAIT_FNAME); 266 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 267 } 268 #endif 269 270 #if defined(__HAVE_PTRACE_WATCHPOINTS) 271 ATF_TC(watchpoint_write_unmodified); 272 ATF_TC_HEAD(watchpoint_write_unmodified, tc) 273 { 274 atf_tc_set_md_var(tc, "descr", 275 "Call PT_COUNT_WATCHPOINTS and assert functional write of " 276 "unmodified data"); 277 } 278 279 ATF_TC_BODY(watchpoint_write_unmodified, tc) 280 { 281 const int exitval = 5; 282 const int sigval = SIGSTOP; 283 pid_t child, wpid; 284 #if defined(TWAIT_HAVE_STATUS) 285 int status; 286 #endif 287 int i, N; 288 struct ptrace_watchpoint pw; 289 int len = sizeof(pw); 290 291 printf("Before forking process PID=%d\n", getpid()); 292 ATF_REQUIRE((child = fork()) != -1); 293 if (child == 0) { 294 printf("Before calling PT_TRACE_ME from child %d\n", getpid()); 295 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 296 297 printf("Before raising %s from child\n", strsignal(sigval)); 298 FORKEE_ASSERT(raise(sigval) == 0); 299 300 printf("Before exiting of the child process\n"); 301 _exit(exitval); 302 } 303 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); 304 305 printf("Before calling %s() for the child\n", TWAIT_FNAME); 306 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 307 308 validate_status_stopped(status, sigval); 309 310 printf("Call GETREGS for the child process\n"); 311 ATF_REQUIRE((N = ptrace(PT_COUNT_WATCHPOINTS, child, NULL, 0)) != -1); 312 313 ATF_REQUIRE_EQ_MSG(N, 4, "Expected 4 hw watchpoints - got %d", N); 314 315 for (i = 0; i < N; i++) { 316 printf("Before reading watchpoint %d\n", i); 317 pw.pw_index = i; 318 ATF_REQUIRE(ptrace(PT_READ_WATCHPOINT, child, &pw, len) != -1); 319 320 printf("struct ptrace {\n"); 321 printf("\t.pw_index=%d\n", pw.pw_index); 322 printf("\t.pw_lwpid=%d\n", pw.pw_lwpid); 323 printf("\t.pw_md.md_address=%p\n", pw.pw_md.md_address); 324 printf("\t.pw_md.md_condition=%#x\n", pw.pw_md.md_condition); 325 printf("\t.pw_md.md_length=%#x\n", pw.pw_md.md_length); 326 printf("}\n"); 327 328 printf("Before writing watchpoint %d (unmodified)\n", i); 329 ATF_REQUIRE(ptrace(PT_WRITE_WATCHPOINT, child, &pw, len) 330 != -1); 331 } 332 333 printf("Before resuming the child process where it left off and " 334 "without signal to be sent\n"); 335 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 336 337 printf("Before calling %s() for the child\n", TWAIT_FNAME); 338 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 339 340 validate_status_exited(status, exitval); 341 342 printf("Before calling %s() for the child\n", TWAIT_FNAME); 343 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 344 } 345 #endif 346 347 #if defined(__HAVE_PTRACE_WATCHPOINTS) 348 ATF_TC(watchpoint_trap_code0); 349 ATF_TC_HEAD(watchpoint_trap_code0, tc) 350 { 351 atf_tc_set_md_var(tc, "descr", 352 "Call PT_COUNT_WATCHPOINTS and test code trap with watchpoint 0"); 353 } 354 355 ATF_TC_BODY(watchpoint_trap_code0, tc) 356 { 357 const int exitval = 5; 358 const int sigval = SIGSTOP; 359 pid_t child, wpid; 360 #if defined(TWAIT_HAVE_STATUS) 361 int status; 362 #endif 363 const int i = 0; 364 struct ptrace_watchpoint pw; 365 int len = sizeof(pw); 366 int watchme = 1234; 367 368 printf("Before forking process PID=%d\n", getpid()); 369 ATF_REQUIRE((child = fork()) != -1); 370 if (child == 0) { 371 printf("Before calling PT_TRACE_ME from child %d\n", getpid()); 372 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 373 374 printf("Before raising %s from child\n", strsignal(sigval)); 375 FORKEE_ASSERT(raise(sigval) == 0); 376 377 printf("check_happy(%d)=%d\n", watchme, check_happy(watchme)); 378 379 printf("Before exiting of the child process\n"); 380 _exit(exitval); 381 } 382 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); 383 384 printf("Before calling %s() for the child\n", TWAIT_FNAME); 385 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 386 387 validate_status_stopped(status, sigval); 388 389 printf("Preparing code watchpoint trap %d\n", i); 390 391 pw.pw_index = i; 392 pw.pw_lwpid = 0; 393 pw.pw_md.md_address = (void *)check_happy; 394 pw.pw_md.md_condition = X86_HW_WATCHPOINT_DR7_CONDITION_EXECUTION; 395 pw.pw_md.md_length = X86_HW_WATCHPOINT_DR7_LENGTH_BYTE; 396 397 printf("struct ptrace {\n"); 398 printf("\t.pw_index=%d\n", pw.pw_index); 399 printf("\t.pw_lwpid=%d\n", pw.pw_lwpid); 400 printf("\t.pw_md.md_address=%p\n", pw.pw_md.md_address); 401 printf("\t.pw_md.md_condition=%#x\n", pw.pw_md.md_condition); 402 printf("\t.pw_md.md_length=%#x\n", pw.pw_md.md_length); 403 printf("}\n"); 404 405 printf("Before writing watchpoint %d\n", i); 406 ATF_REQUIRE(ptrace(PT_WRITE_WATCHPOINT, child, &pw, len) != -1); 407 408 printf("Before resuming the child process where it left off " 409 "and without signal to be sent\n"); 410 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 411 412 printf("Before calling %s() for the child\n", TWAIT_FNAME); 413 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 414 415 validate_status_stopped(status, SIGTRAP); 416 417 pw.pw_md.md_address = NULL; 418 printf("Before writing watchpoint %d (disable it)\n", i); 419 ATF_REQUIRE(ptrace(PT_WRITE_WATCHPOINT, child, &pw, len) != -1); 420 421 printf("Before resuming the child process where it left off and " 422 "without signal to be sent\n"); 423 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 424 425 printf("Before calling %s() for the child\n", TWAIT_FNAME); 426 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 427 428 validate_status_exited(status, exitval); 429 430 printf("Before calling %s() for the child\n", TWAIT_FNAME); 431 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 432 } 433 #endif 434 435 #if defined(__HAVE_PTRACE_WATCHPOINTS) 436 ATF_TC(watchpoint_trap_code1); 437 ATF_TC_HEAD(watchpoint_trap_code1, tc) 438 { 439 atf_tc_set_md_var(tc, "descr", 440 "Call PT_COUNT_WATCHPOINTS and test code trap with watchpoint 1"); 441 } 442 443 ATF_TC_BODY(watchpoint_trap_code1, tc) 444 { 445 const int exitval = 5; 446 const int sigval = SIGSTOP; 447 pid_t child, wpid; 448 #if defined(TWAIT_HAVE_STATUS) 449 int status; 450 #endif 451 const int i = 1; 452 struct ptrace_watchpoint pw; 453 int len = sizeof(pw); 454 int watchme = 1234; 455 456 printf("Before forking process PID=%d\n", getpid()); 457 ATF_REQUIRE((child = fork()) != -1); 458 if (child == 0) { 459 printf("Before calling PT_TRACE_ME from child %d\n", getpid()); 460 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 461 462 printf("Before raising %s from child\n", strsignal(sigval)); 463 FORKEE_ASSERT(raise(sigval) == 0); 464 465 printf("check_happy(%d)=%d\n", watchme, check_happy(watchme)); 466 467 printf("Before exiting of the child process\n"); 468 _exit(exitval); 469 } 470 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); 471 472 printf("Before calling %s() for the child\n", TWAIT_FNAME); 473 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 474 475 validate_status_stopped(status, sigval); 476 477 printf("Preparing code watchpoint trap %d\n", i); 478 479 pw.pw_index = i; 480 pw.pw_lwpid = 0; 481 pw.pw_md.md_address = (void *)check_happy; 482 pw.pw_md.md_condition = X86_HW_WATCHPOINT_DR7_CONDITION_EXECUTION; 483 pw.pw_md.md_length = X86_HW_WATCHPOINT_DR7_LENGTH_BYTE; 484 485 printf("struct ptrace {\n"); 486 printf("\t.pw_index=%d\n", pw.pw_index); 487 printf("\t.pw_lwpid=%d\n", pw.pw_lwpid); 488 printf("\t.pw_md.md_address=%p\n", pw.pw_md.md_address); 489 printf("\t.pw_md.md_condition=%#x\n", pw.pw_md.md_condition); 490 printf("\t.pw_md.md_length=%#x\n", pw.pw_md.md_length); 491 printf("}\n"); 492 493 printf("Before writing watchpoint %d\n", i); 494 ATF_REQUIRE(ptrace(PT_WRITE_WATCHPOINT, child, &pw, len) != -1); 495 496 printf("Before resuming the child process where it left off " 497 "and without signal to be sent\n"); 498 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 499 500 printf("Before calling %s() for the child\n", TWAIT_FNAME); 501 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 502 503 validate_status_stopped(status, SIGTRAP); 504 505 pw.pw_md.md_address = NULL; 506 printf("Before writing watchpoint %d (disable it)\n", i); 507 ATF_REQUIRE(ptrace(PT_WRITE_WATCHPOINT, child, &pw, len) != -1); 508 509 printf("Before resuming the child process where it left off and " 510 "without signal to be sent\n"); 511 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 512 513 printf("Before calling %s() for the child\n", TWAIT_FNAME); 514 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 515 516 validate_status_exited(status, exitval); 517 518 printf("Before calling %s() for the child\n", TWAIT_FNAME); 519 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 520 } 521 #endif 522 523 #if defined(__HAVE_PTRACE_WATCHPOINTS) 524 ATF_TC(watchpoint_trap_code2); 525 ATF_TC_HEAD(watchpoint_trap_code2, tc) 526 { 527 atf_tc_set_md_var(tc, "descr", 528 "Call PT_COUNT_WATCHPOINTS and test code trap with watchpoint 2"); 529 } 530 531 ATF_TC_BODY(watchpoint_trap_code2, tc) 532 { 533 const int exitval = 5; 534 const int sigval = SIGSTOP; 535 pid_t child, wpid; 536 #if defined(TWAIT_HAVE_STATUS) 537 int status; 538 #endif 539 const int i = 2; 540 struct ptrace_watchpoint pw; 541 int len = sizeof(pw); 542 int watchme = 1234; 543 544 printf("Before forking process PID=%d\n", getpid()); 545 ATF_REQUIRE((child = fork()) != -1); 546 if (child == 0) { 547 printf("Before calling PT_TRACE_ME from child %d\n", getpid()); 548 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 549 550 printf("Before raising %s from child\n", strsignal(sigval)); 551 FORKEE_ASSERT(raise(sigval) == 0); 552 553 printf("check_happy(%d)=%d\n", watchme, check_happy(watchme)); 554 555 printf("Before exiting of the child process\n"); 556 _exit(exitval); 557 } 558 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); 559 560 printf("Before calling %s() for the child\n", TWAIT_FNAME); 561 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 562 563 validate_status_stopped(status, sigval); 564 565 printf("Preparing code watchpoint trap %d\n", i); 566 567 pw.pw_index = i; 568 pw.pw_lwpid = 0; 569 pw.pw_md.md_address = (void *)check_happy; 570 pw.pw_md.md_condition = X86_HW_WATCHPOINT_DR7_CONDITION_EXECUTION; 571 pw.pw_md.md_length = X86_HW_WATCHPOINT_DR7_LENGTH_BYTE; 572 573 printf("struct ptrace {\n"); 574 printf("\t.pw_index=%d\n", pw.pw_index); 575 printf("\t.pw_lwpid=%d\n", pw.pw_lwpid); 576 printf("\t.pw_md.md_address=%p\n", pw.pw_md.md_address); 577 printf("\t.pw_md.md_condition=%#x\n", pw.pw_md.md_condition); 578 printf("\t.pw_md.md_length=%#x\n", pw.pw_md.md_length); 579 printf("}\n"); 580 581 printf("Before writing watchpoint %d\n", i); 582 ATF_REQUIRE(ptrace(PT_WRITE_WATCHPOINT, child, &pw, len) != -1); 583 584 printf("Before resuming the child process where it left off " 585 "and without signal to be sent\n"); 586 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 587 588 printf("Before calling %s() for the child\n", TWAIT_FNAME); 589 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 590 591 validate_status_stopped(status, SIGTRAP); 592 593 pw.pw_md.md_address = NULL; 594 printf("Before writing watchpoint %d (disable it)\n", i); 595 ATF_REQUIRE(ptrace(PT_WRITE_WATCHPOINT, child, &pw, len) != -1); 596 597 printf("Before resuming the child process where it left off and " 598 "without signal to be sent\n"); 599 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 600 601 printf("Before calling %s() for the child\n", TWAIT_FNAME); 602 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 603 604 validate_status_exited(status, exitval); 605 606 printf("Before calling %s() for the child\n", TWAIT_FNAME); 607 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 608 } 609 #endif 610 611 #if defined(__HAVE_PTRACE_WATCHPOINTS) 612 ATF_TC(watchpoint_trap_code3); 613 ATF_TC_HEAD(watchpoint_trap_code3, tc) 614 { 615 atf_tc_set_md_var(tc, "descr", 616 "Call PT_COUNT_WATCHPOINTS and test code trap with watchpoint 3"); 617 } 618 619 ATF_TC_BODY(watchpoint_trap_code3, tc) 620 { 621 const int exitval = 5; 622 const int sigval = SIGSTOP; 623 pid_t child, wpid; 624 #if defined(TWAIT_HAVE_STATUS) 625 int status; 626 #endif 627 const int i = 3; 628 struct ptrace_watchpoint pw; 629 int len = sizeof(pw); 630 int watchme = 1234; 631 632 printf("Before forking process PID=%d\n", getpid()); 633 ATF_REQUIRE((child = fork()) != -1); 634 if (child == 0) { 635 printf("Before calling PT_TRACE_ME from child %d\n", getpid()); 636 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 637 638 printf("Before raising %s from child\n", strsignal(sigval)); 639 FORKEE_ASSERT(raise(sigval) == 0); 640 641 printf("check_happy(%d)=%d\n", watchme, check_happy(watchme)); 642 643 printf("Before exiting of the child process\n"); 644 _exit(exitval); 645 } 646 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); 647 648 printf("Before calling %s() for the child\n", TWAIT_FNAME); 649 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 650 651 validate_status_stopped(status, sigval); 652 653 printf("Preparing code watchpoint trap %d\n", i); 654 655 pw.pw_index = i; 656 pw.pw_lwpid = 0; 657 pw.pw_md.md_address = (void *)check_happy; 658 pw.pw_md.md_condition = X86_HW_WATCHPOINT_DR7_CONDITION_EXECUTION; 659 pw.pw_md.md_length = X86_HW_WATCHPOINT_DR7_LENGTH_BYTE; 660 661 printf("struct ptrace {\n"); 662 printf("\t.pw_index=%d\n", pw.pw_index); 663 printf("\t.pw_lwpid=%d\n", pw.pw_lwpid); 664 printf("\t.pw_md.md_address=%p\n", pw.pw_md.md_address); 665 printf("\t.pw_md.md_condition=%#x\n", pw.pw_md.md_condition); 666 printf("\t.pw_md.md_length=%#x\n", pw.pw_md.md_length); 667 printf("}\n"); 668 669 printf("Before writing watchpoint %d\n", i); 670 ATF_REQUIRE(ptrace(PT_WRITE_WATCHPOINT, child, &pw, len) != -1); 671 672 printf("Before resuming the child process where it left off " 673 "and without signal to be sent\n"); 674 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 675 676 printf("Before calling %s() for the child\n", TWAIT_FNAME); 677 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 678 679 validate_status_stopped(status, SIGTRAP); 680 681 pw.pw_md.md_address = NULL; 682 printf("Before writing watchpoint %d (disable it)\n", i); 683 ATF_REQUIRE(ptrace(PT_WRITE_WATCHPOINT, child, &pw, len) != -1); 684 685 printf("Before resuming the child process where it left off and " 686 "without signal to be sent\n"); 687 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 688 689 printf("Before calling %s() for the child\n", TWAIT_FNAME); 690 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 691 692 validate_status_exited(status, exitval); 693 694 printf("Before calling %s() for the child\n", TWAIT_FNAME); 695 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 696 } 697 #endif 698 699 #if defined(__HAVE_PTRACE_WATCHPOINTS) 700 ATF_TC(watchpoint_trap_data_write0); 701 ATF_TC_HEAD(watchpoint_trap_data_write0, tc) 702 { 703 atf_tc_set_md_var(tc, "descr", 704 "Call PT_COUNT_WATCHPOINTS and test write trap with watchpoint 0"); 705 } 706 707 ATF_TC_BODY(watchpoint_trap_data_write0, tc) 708 { 709 const int exitval = 5; 710 const int sigval = SIGSTOP; 711 pid_t child, wpid; 712 #if defined(TWAIT_HAVE_STATUS) 713 int status; 714 #endif 715 const int i = 0; 716 struct ptrace_watchpoint pw; 717 int len = sizeof(pw); 718 int watchme = 1234; 719 720 printf("Before forking process PID=%d\n", getpid()); 721 ATF_REQUIRE((child = fork()) != -1); 722 if (child == 0) { 723 printf("Before calling PT_TRACE_ME from child %d\n", getpid()); 724 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 725 726 printf("Before raising %s from child\n", strsignal(sigval)); 727 FORKEE_ASSERT(raise(sigval) == 0); 728 729 ++watchme; 730 731 printf("Before exiting of the child process\n"); 732 _exit(exitval); 733 } 734 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); 735 736 printf("Before calling %s() for the child\n", TWAIT_FNAME); 737 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 738 739 validate_status_stopped(status, sigval); 740 741 printf("Preparing code watchpoint trap %d\n", i); 742 743 pw.pw_index = 0; 744 pw.pw_md.md_address = &watchme; 745 pw.pw_md.md_condition = X86_HW_WATCHPOINT_DR7_CONDITION_DATA_WRITE; 746 pw.pw_md.md_length = X86_HW_WATCHPOINT_DR7_LENGTH_BYTE; 747 748 printf("struct ptrace {\n"); 749 printf("\t.pw_index=%d\n", pw.pw_index); 750 printf("\t.pw_lwpid=%d\n", pw.pw_lwpid); 751 printf("\t.pw_md.md_address=%p\n", pw.pw_md.md_address); 752 printf("\t.pw_md.md_condition=%#x\n", pw.pw_md.md_condition); 753 printf("\t.pw_md.md_length=%#x\n", pw.pw_md.md_length); 754 printf("}\n"); 755 756 printf("Before writing watchpoint %d\n", i); 757 ATF_REQUIRE(ptrace(PT_WRITE_WATCHPOINT, child, &pw, len) != -1); 758 759 printf("Before resuming the child process where it left off " 760 "and without signal to be sent\n"); 761 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 762 763 printf("Before calling %s() for the child\n", TWAIT_FNAME); 764 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 765 766 validate_status_stopped(status, SIGTRAP); 767 768 printf("Before resuming the child process where it left off and " 769 "without signal to be sent\n"); 770 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 771 772 printf("Before calling %s() for the child\n", TWAIT_FNAME); 773 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 774 775 validate_status_exited(status, exitval); 776 777 printf("Before calling %s() for the child\n", TWAIT_FNAME); 778 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 779 } 780 #endif 781 782 #if defined(__HAVE_PTRACE_WATCHPOINTS) 783 ATF_TC(watchpoint_trap_data_write1); 784 ATF_TC_HEAD(watchpoint_trap_data_write1, tc) 785 { 786 atf_tc_set_md_var(tc, "descr", 787 "Call PT_COUNT_WATCHPOINTS and test write trap with watchpoint 1"); 788 } 789 790 ATF_TC_BODY(watchpoint_trap_data_write1, tc) 791 { 792 const int exitval = 5; 793 const int sigval = SIGSTOP; 794 pid_t child, wpid; 795 #if defined(TWAIT_HAVE_STATUS) 796 int status; 797 #endif 798 const int i = 1; 799 struct ptrace_watchpoint pw; 800 int len = sizeof(pw); 801 int watchme = 1234; 802 803 printf("Before forking process PID=%d\n", getpid()); 804 ATF_REQUIRE((child = fork()) != -1); 805 if (child == 0) { 806 printf("Before calling PT_TRACE_ME from child %d\n", getpid()); 807 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 808 809 printf("Before raising %s from child\n", strsignal(sigval)); 810 FORKEE_ASSERT(raise(sigval) == 0); 811 812 ++watchme; 813 814 printf("Before exiting of the child process\n"); 815 _exit(exitval); 816 } 817 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); 818 819 printf("Before calling %s() for the child\n", TWAIT_FNAME); 820 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 821 822 validate_status_stopped(status, sigval); 823 824 printf("Preparing code watchpoint trap %d\n", i); 825 826 pw.pw_index = i; 827 pw.pw_md.md_address = &watchme; 828 pw.pw_md.md_condition = X86_HW_WATCHPOINT_DR7_CONDITION_DATA_WRITE; 829 pw.pw_md.md_length = X86_HW_WATCHPOINT_DR7_LENGTH_BYTE; 830 831 printf("struct ptrace {\n"); 832 printf("\t.pw_index=%d\n", pw.pw_index); 833 printf("\t.pw_lwpid=%d\n", pw.pw_lwpid); 834 printf("\t.pw_md.md_address=%p\n", pw.pw_md.md_address); 835 printf("\t.pw_md.md_condition=%#x\n", pw.pw_md.md_condition); 836 printf("\t.pw_md.md_length=%#x\n", pw.pw_md.md_length); 837 printf("}\n"); 838 839 printf("Before writing watchpoint %d\n", i); 840 ATF_REQUIRE(ptrace(PT_WRITE_WATCHPOINT, child, &pw, len) != -1); 841 842 printf("Before resuming the child process where it left off " 843 "and without signal to be sent\n"); 844 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 845 846 printf("Before calling %s() for the child\n", TWAIT_FNAME); 847 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 848 849 validate_status_stopped(status, SIGTRAP); 850 851 printf("Before resuming the child process where it left off and " 852 "without signal to be sent\n"); 853 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 854 855 printf("Before calling %s() for the child\n", TWAIT_FNAME); 856 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 857 858 validate_status_exited(status, exitval); 859 860 printf("Before calling %s() for the child\n", TWAIT_FNAME); 861 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 862 } 863 #endif 864 865 #if defined(__HAVE_PTRACE_WATCHPOINTS) 866 ATF_TC(watchpoint_trap_data_write2); 867 ATF_TC_HEAD(watchpoint_trap_data_write2, tc) 868 { 869 atf_tc_set_md_var(tc, "descr", 870 "Call PT_COUNT_WATCHPOINTS and test write trap with watchpoint 2"); 871 } 872 873 ATF_TC_BODY(watchpoint_trap_data_write2, tc) 874 { 875 const int exitval = 5; 876 const int sigval = SIGSTOP; 877 pid_t child, wpid; 878 #if defined(TWAIT_HAVE_STATUS) 879 int status; 880 #endif 881 const int i = 2; 882 struct ptrace_watchpoint pw; 883 int len = sizeof(pw); 884 int watchme = 1234; 885 886 printf("Before forking process PID=%d\n", getpid()); 887 ATF_REQUIRE((child = fork()) != -1); 888 if (child == 0) { 889 printf("Before calling PT_TRACE_ME from child %d\n", getpid()); 890 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 891 892 printf("Before raising %s from child\n", strsignal(sigval)); 893 FORKEE_ASSERT(raise(sigval) == 0); 894 895 ++watchme; 896 897 printf("Before exiting of the child process\n"); 898 _exit(exitval); 899 } 900 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); 901 902 printf("Before calling %s() for the child\n", TWAIT_FNAME); 903 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 904 905 validate_status_stopped(status, sigval); 906 907 printf("Preparing code watchpoint trap %d\n", i); 908 909 pw.pw_index = i; 910 pw.pw_md.md_address = &watchme; 911 pw.pw_md.md_condition = X86_HW_WATCHPOINT_DR7_CONDITION_DATA_WRITE; 912 pw.pw_md.md_length = X86_HW_WATCHPOINT_DR7_LENGTH_BYTE; 913 914 printf("struct ptrace {\n"); 915 printf("\t.pw_index=%d\n", pw.pw_index); 916 printf("\t.pw_lwpid=%d\n", pw.pw_lwpid); 917 printf("\t.pw_md.md_address=%p\n", pw.pw_md.md_address); 918 printf("\t.pw_md.md_condition=%#x\n", pw.pw_md.md_condition); 919 printf("\t.pw_md.md_length=%#x\n", pw.pw_md.md_length); 920 printf("}\n"); 921 922 printf("Before writing watchpoint %d\n", i); 923 ATF_REQUIRE(ptrace(PT_WRITE_WATCHPOINT, child, &pw, len) != -1); 924 925 printf("Before resuming the child process where it left off " 926 "and without signal to be sent\n"); 927 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 928 929 printf("Before calling %s() for the child\n", TWAIT_FNAME); 930 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 931 932 validate_status_stopped(status, SIGTRAP); 933 934 printf("Before resuming the child process where it left off and " 935 "without signal to be sent\n"); 936 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 937 938 printf("Before calling %s() for the child\n", TWAIT_FNAME); 939 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 940 941 validate_status_exited(status, exitval); 942 943 printf("Before calling %s() for the child\n", TWAIT_FNAME); 944 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 945 } 946 #endif 947 948 949 #if defined(__HAVE_PTRACE_WATCHPOINTS) 950 ATF_TC(watchpoint_trap_data_write3); 951 ATF_TC_HEAD(watchpoint_trap_data_write3, tc) 952 { 953 atf_tc_set_md_var(tc, "descr", 954 "Call PT_COUNT_WATCHPOINTS and test write trap with watchpoint 3"); 955 } 956 957 ATF_TC_BODY(watchpoint_trap_data_write3, tc) 958 { 959 const int exitval = 5; 960 const int sigval = SIGSTOP; 961 pid_t child, wpid; 962 #if defined(TWAIT_HAVE_STATUS) 963 int status; 964 #endif 965 const int i = 3; 966 struct ptrace_watchpoint pw; 967 int len = sizeof(pw); 968 int watchme = 1234; 969 970 printf("Before forking process PID=%d\n", getpid()); 971 ATF_REQUIRE((child = fork()) != -1); 972 if (child == 0) { 973 printf("Before calling PT_TRACE_ME from child %d\n", getpid()); 974 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 975 976 printf("Before raising %s from child\n", strsignal(sigval)); 977 FORKEE_ASSERT(raise(sigval) == 0); 978 979 ++watchme; 980 981 printf("Before exiting of the child process\n"); 982 _exit(exitval); 983 } 984 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); 985 986 printf("Before calling %s() for the child\n", TWAIT_FNAME); 987 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 988 989 validate_status_stopped(status, sigval); 990 991 printf("Preparing code watchpoint trap %d\n", i); 992 993 pw.pw_index = i; 994 pw.pw_md.md_address = &watchme; 995 pw.pw_md.md_condition = X86_HW_WATCHPOINT_DR7_CONDITION_DATA_WRITE; 996 pw.pw_md.md_length = X86_HW_WATCHPOINT_DR7_LENGTH_BYTE; 997 998 printf("struct ptrace {\n"); 999 printf("\t.pw_index=%d\n", pw.pw_index); 1000 printf("\t.pw_lwpid=%d\n", pw.pw_lwpid); 1001 printf("\t.pw_md.md_address=%p\n", pw.pw_md.md_address); 1002 printf("\t.pw_md.md_condition=%#x\n", pw.pw_md.md_condition); 1003 printf("\t.pw_md.md_length=%#x\n", pw.pw_md.md_length); 1004 printf("}\n"); 1005 1006 printf("Before writing watchpoint %d\n", i); 1007 ATF_REQUIRE(ptrace(PT_WRITE_WATCHPOINT, child, &pw, len) != -1); 1008 1009 printf("Before resuming the child process where it left off " 1010 "and without signal to be sent\n"); 1011 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 1012 1013 printf("Before calling %s() for the child\n", TWAIT_FNAME); 1014 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1015 1016 validate_status_stopped(status, SIGTRAP); 1017 1018 printf("Before resuming the child process where it left off and " 1019 "without signal to be sent\n"); 1020 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 1021 1022 printf("Before calling %s() for the child\n", TWAIT_FNAME); 1023 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1024 1025 validate_status_exited(status, exitval); 1026 1027 printf("Before calling %s() for the child\n", TWAIT_FNAME); 1028 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 1029 } 1030 #endif 1031 1032 #if defined(__HAVE_PTRACE_WATCHPOINTS) 1033 ATF_TC(watchpoint_trap_data_rw0); 1034 ATF_TC_HEAD(watchpoint_trap_data_rw0, tc) 1035 { 1036 atf_tc_set_md_var(tc, "descr", 1037 "Call PT_COUNT_WATCHPOINTS and test write trap with watchpoint 0"); 1038 } 1039 1040 ATF_TC_BODY(watchpoint_trap_data_rw0, tc) 1041 { 1042 const int exitval = 5; 1043 const int sigval = SIGSTOP; 1044 pid_t child, wpid; 1045 #if defined(TWAIT_HAVE_STATUS) 1046 int status; 1047 #endif 1048 const int i = 0; 1049 struct ptrace_watchpoint pw; 1050 int len = sizeof(pw); 1051 int watchme = 1234; 1052 1053 printf("Before forking process PID=%d\n", getpid()); 1054 ATF_REQUIRE((child = fork()) != -1); 1055 if (child == 0) { 1056 printf("Before calling PT_TRACE_ME from child %d\n", getpid()); 1057 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 1058 1059 printf("Before raising %s from child\n", strsignal(sigval)); 1060 FORKEE_ASSERT(raise(sigval) == 0); 1061 1062 printf("watchme=%d\n", watchme); 1063 1064 printf("Before exiting of the child process\n"); 1065 _exit(exitval); 1066 } 1067 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); 1068 1069 printf("Before calling %s() for the child\n", TWAIT_FNAME); 1070 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1071 1072 validate_status_stopped(status, sigval); 1073 1074 printf("Preparing code watchpoint trap %d\n", i); 1075 1076 pw.pw_index = i; 1077 pw.pw_md.md_address = &watchme; 1078 pw.pw_md.md_condition = X86_HW_WATCHPOINT_DR7_CONDITION_DATA_READWRITE; 1079 pw.pw_md.md_length = X86_HW_WATCHPOINT_DR7_LENGTH_BYTE; 1080 1081 printf("struct ptrace {\n"); 1082 printf("\t.pw_index=%d\n", pw.pw_index); 1083 printf("\t.pw_lwpid=%d\n", pw.pw_lwpid); 1084 printf("\t.pw_md.md_address=%p\n", pw.pw_md.md_address); 1085 printf("\t.pw_md.md_condition=%#x\n", pw.pw_md.md_condition); 1086 printf("\t.pw_md.md_length=%#x\n", pw.pw_md.md_length); 1087 printf("}\n"); 1088 1089 printf("Before writing watchpoint %d\n", i); 1090 ATF_REQUIRE(ptrace(PT_WRITE_WATCHPOINT, child, &pw, len) != -1); 1091 1092 printf("Before resuming the child process where it left off " 1093 "and without signal to be sent\n"); 1094 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 1095 1096 printf("Before calling %s() for the child\n", TWAIT_FNAME); 1097 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1098 1099 validate_status_stopped(status, SIGTRAP); 1100 1101 printf("Before resuming the child process where it left off and " 1102 "without signal to be sent\n"); 1103 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 1104 1105 printf("Before calling %s() for the child\n", TWAIT_FNAME); 1106 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1107 1108 validate_status_exited(status, exitval); 1109 1110 printf("Before calling %s() for the child\n", TWAIT_FNAME); 1111 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 1112 } 1113 #endif 1114 1115 #if defined(__HAVE_PTRACE_WATCHPOINTS) 1116 ATF_TC(watchpoint_trap_data_rw1); 1117 ATF_TC_HEAD(watchpoint_trap_data_rw1, tc) 1118 { 1119 atf_tc_set_md_var(tc, "descr", 1120 "Call PT_COUNT_WATCHPOINTS and test write trap with watchpoint 1"); 1121 } 1122 1123 ATF_TC_BODY(watchpoint_trap_data_rw1, tc) 1124 { 1125 const int exitval = 5; 1126 const int sigval = SIGSTOP; 1127 pid_t child, wpid; 1128 #if defined(TWAIT_HAVE_STATUS) 1129 int status; 1130 #endif 1131 const int i = 1; 1132 struct ptrace_watchpoint pw; 1133 int len = sizeof(pw); 1134 int watchme = 1234; 1135 1136 printf("Before forking process PID=%d\n", getpid()); 1137 ATF_REQUIRE((child = fork()) != -1); 1138 if (child == 0) { 1139 printf("Before calling PT_TRACE_ME from child %d\n", getpid()); 1140 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 1141 1142 printf("Before raising %s from child\n", strsignal(sigval)); 1143 FORKEE_ASSERT(raise(sigval) == 0); 1144 1145 printf("watchme=%d\n", watchme); 1146 1147 printf("Before exiting of the child process\n"); 1148 _exit(exitval); 1149 } 1150 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); 1151 1152 printf("Before calling %s() for the child\n", TWAIT_FNAME); 1153 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1154 1155 validate_status_stopped(status, sigval); 1156 1157 printf("Preparing code watchpoint trap %d\n", i); 1158 1159 pw.pw_index = i; 1160 pw.pw_md.md_address = &watchme; 1161 pw.pw_md.md_condition = X86_HW_WATCHPOINT_DR7_CONDITION_DATA_READWRITE; 1162 pw.pw_md.md_length = X86_HW_WATCHPOINT_DR7_LENGTH_BYTE; 1163 1164 printf("struct ptrace {\n"); 1165 printf("\t.pw_index=%d\n", pw.pw_index); 1166 printf("\t.pw_lwpid=%d\n", pw.pw_lwpid); 1167 printf("\t.pw_md.md_address=%p\n", pw.pw_md.md_address); 1168 printf("\t.pw_md.md_condition=%#x\n", pw.pw_md.md_condition); 1169 printf("\t.pw_md.md_length=%#x\n", pw.pw_md.md_length); 1170 printf("}\n"); 1171 1172 printf("Before writing watchpoint %d\n", i); 1173 ATF_REQUIRE(ptrace(PT_WRITE_WATCHPOINT, child, &pw, len) != -1); 1174 1175 printf("Before resuming the child process where it left off " 1176 "and without signal to be sent\n"); 1177 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 1178 1179 printf("Before calling %s() for the child\n", TWAIT_FNAME); 1180 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1181 1182 validate_status_stopped(status, SIGTRAP); 1183 1184 printf("Before resuming the child process where it left off and " 1185 "without signal to be sent\n"); 1186 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 1187 1188 printf("Before calling %s() for the child\n", TWAIT_FNAME); 1189 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1190 1191 validate_status_exited(status, exitval); 1192 1193 printf("Before calling %s() for the child\n", TWAIT_FNAME); 1194 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 1195 } 1196 #endif 1197 1198 #if defined(__HAVE_PTRACE_WATCHPOINTS) 1199 ATF_TC(watchpoint_trap_data_rw2); 1200 ATF_TC_HEAD(watchpoint_trap_data_rw2, tc) 1201 { 1202 atf_tc_set_md_var(tc, "descr", 1203 "Call PT_COUNT_WATCHPOINTS and test write trap with watchpoint 2"); 1204 } 1205 1206 ATF_TC_BODY(watchpoint_trap_data_rw2, tc) 1207 { 1208 const int exitval = 5; 1209 const int sigval = SIGSTOP; 1210 pid_t child, wpid; 1211 #if defined(TWAIT_HAVE_STATUS) 1212 int status; 1213 #endif 1214 const int i = 2; 1215 struct ptrace_watchpoint pw; 1216 int len = sizeof(pw); 1217 int watchme = 1234; 1218 1219 printf("Before forking process PID=%d\n", getpid()); 1220 ATF_REQUIRE((child = fork()) != -1); 1221 if (child == 0) { 1222 printf("Before calling PT_TRACE_ME from child %d\n", getpid()); 1223 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 1224 1225 printf("Before raising %s from child\n", strsignal(sigval)); 1226 FORKEE_ASSERT(raise(sigval) == 0); 1227 1228 printf("watchme=%d\n", watchme); 1229 1230 printf("Before exiting of the child process\n"); 1231 _exit(exitval); 1232 } 1233 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); 1234 1235 printf("Before calling %s() for the child\n", TWAIT_FNAME); 1236 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1237 1238 validate_status_stopped(status, sigval); 1239 1240 printf("Preparing code watchpoint trap %d\n", i); 1241 1242 pw.pw_index = i; 1243 pw.pw_md.md_address = &watchme; 1244 pw.pw_md.md_condition = X86_HW_WATCHPOINT_DR7_CONDITION_DATA_READWRITE; 1245 pw.pw_md.md_length = X86_HW_WATCHPOINT_DR7_LENGTH_BYTE; 1246 1247 printf("struct ptrace {\n"); 1248 printf("\t.pw_index=%d\n", pw.pw_index); 1249 printf("\t.pw_lwpid=%d\n", pw.pw_lwpid); 1250 printf("\t.pw_md.md_address=%p\n", pw.pw_md.md_address); 1251 printf("\t.pw_md.md_condition=%#x\n", pw.pw_md.md_condition); 1252 printf("\t.pw_md.md_length=%#x\n", pw.pw_md.md_length); 1253 printf("}\n"); 1254 1255 printf("Before writing watchpoint %d\n", i); 1256 ATF_REQUIRE(ptrace(PT_WRITE_WATCHPOINT, child, &pw, len) != -1); 1257 1258 printf("Before resuming the child process where it left off " 1259 "and without signal to be sent\n"); 1260 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 1261 1262 printf("Before calling %s() for the child\n", TWAIT_FNAME); 1263 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1264 1265 validate_status_stopped(status, SIGTRAP); 1266 1267 printf("Before resuming the child process where it left off and " 1268 "without signal to be sent\n"); 1269 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 1270 1271 printf("Before calling %s() for the child\n", TWAIT_FNAME); 1272 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1273 1274 validate_status_exited(status, exitval); 1275 1276 printf("Before calling %s() for the child\n", TWAIT_FNAME); 1277 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 1278 } 1279 #endif 1280 1281 #if defined(__HAVE_PTRACE_WATCHPOINTS) 1282 ATF_TC(watchpoint_trap_data_rw3); 1283 ATF_TC_HEAD(watchpoint_trap_data_rw3, tc) 1284 { 1285 atf_tc_set_md_var(tc, "descr", 1286 "Call PT_COUNT_WATCHPOINTS and test write trap with watchpoint 3"); 1287 } 1288 1289 ATF_TC_BODY(watchpoint_trap_data_rw3, tc) 1290 { 1291 const int exitval = 5; 1292 const int sigval = SIGSTOP; 1293 pid_t child, wpid; 1294 #if defined(TWAIT_HAVE_STATUS) 1295 int status; 1296 #endif 1297 const int i = 3; 1298 struct ptrace_watchpoint pw; 1299 int len = sizeof(pw); 1300 int watchme = 1234; 1301 1302 printf("Before forking process PID=%d\n", getpid()); 1303 ATF_REQUIRE((child = fork()) != -1); 1304 if (child == 0) { 1305 printf("Before calling PT_TRACE_ME from child %d\n", getpid()); 1306 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 1307 1308 printf("Before raising %s from child\n", strsignal(sigval)); 1309 FORKEE_ASSERT(raise(sigval) == 0); 1310 1311 printf("watchme=%d\n", watchme); 1312 1313 printf("Before exiting of the child process\n"); 1314 _exit(exitval); 1315 } 1316 printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); 1317 1318 printf("Before calling %s() for the child\n", TWAIT_FNAME); 1319 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1320 1321 validate_status_stopped(status, sigval); 1322 1323 printf("Preparing code watchpoint trap %d\n", i); 1324 1325 pw.pw_index = i; 1326 pw.pw_md.md_address = &watchme; 1327 pw.pw_md.md_condition = X86_HW_WATCHPOINT_DR7_CONDITION_DATA_READWRITE; 1328 pw.pw_md.md_length = X86_HW_WATCHPOINT_DR7_LENGTH_BYTE; 1329 1330 printf("struct ptrace {\n"); 1331 printf("\t.pw_index=%d\n", pw.pw_index); 1332 printf("\t.pw_lwpid=%d\n", pw.pw_lwpid); 1333 printf("\t.pw_md.md_address=%p\n", pw.pw_md.md_address); 1334 printf("\t.pw_md.md_condition=%#x\n", pw.pw_md.md_condition); 1335 printf("\t.pw_md.md_length=%#x\n", pw.pw_md.md_length); 1336 printf("}\n"); 1337 1338 printf("Before writing watchpoint %d\n", i); 1339 ATF_REQUIRE(ptrace(PT_WRITE_WATCHPOINT, child, &pw, len) != -1); 1340 1341 printf("Before resuming the child process where it left off " 1342 "and without signal to be sent\n"); 1343 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 1344 1345 printf("Before calling %s() for the child\n", TWAIT_FNAME); 1346 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1347 1348 validate_status_stopped(status, SIGTRAP); 1349 1350 printf("Before resuming the child process where it left off and " 1351 "without signal to be sent\n"); 1352 ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 1353 1354 printf("Before calling %s() for the child\n", TWAIT_FNAME); 1355 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1356 1357 validate_status_exited(status, exitval); 1358 1359 printf("Before calling %s() for the child\n", TWAIT_FNAME); 1360 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 1361 } 1362 #endif 1363 1364 ATF_TP_ADD_TCS(tp) 1365 { 1366 setvbuf(stdout, NULL, _IONBF, 0); 1367 setvbuf(stderr, NULL, _IONBF, 0); 1368 1369 ATF_TP_ADD_TC_HAVE_GPREGS(tp, regs1); 1370 1371 ATF_TP_ADD_TC_HAVE_PTRACE_WATCHPOINTS(tp, watchpoint_count); 1372 ATF_TP_ADD_TC_HAVE_PTRACE_WATCHPOINTS(tp, watchpoint_read); 1373 ATF_TP_ADD_TC_HAVE_PTRACE_WATCHPOINTS(tp, watchpoint_write_unmodified); 1374 ATF_TP_ADD_TC_HAVE_PTRACE_WATCHPOINTS(tp, watchpoint_trap_code0); 1375 ATF_TP_ADD_TC_HAVE_PTRACE_WATCHPOINTS(tp, watchpoint_trap_code1); 1376 ATF_TP_ADD_TC_HAVE_PTRACE_WATCHPOINTS(tp, watchpoint_trap_code2); 1377 ATF_TP_ADD_TC_HAVE_PTRACE_WATCHPOINTS(tp, watchpoint_trap_code3); 1378 ATF_TP_ADD_TC_HAVE_PTRACE_WATCHPOINTS(tp, watchpoint_trap_data_write0); 1379 ATF_TP_ADD_TC_HAVE_PTRACE_WATCHPOINTS(tp, watchpoint_trap_data_write1); 1380 ATF_TP_ADD_TC_HAVE_PTRACE_WATCHPOINTS(tp, watchpoint_trap_data_write2); 1381 ATF_TP_ADD_TC_HAVE_PTRACE_WATCHPOINTS(tp, watchpoint_trap_data_write3); 1382 ATF_TP_ADD_TC_HAVE_PTRACE_WATCHPOINTS(tp, watchpoint_trap_data_rw0); 1383 ATF_TP_ADD_TC_HAVE_PTRACE_WATCHPOINTS(tp, watchpoint_trap_data_rw1); 1384 ATF_TP_ADD_TC_HAVE_PTRACE_WATCHPOINTS(tp, watchpoint_trap_data_rw2); 1385 ATF_TP_ADD_TC_HAVE_PTRACE_WATCHPOINTS(tp, watchpoint_trap_data_rw3); 1386 1387 return atf_no_error(); 1388 } 1389