1 /* $NetBSD: t_ptrace_x86_wait.h,v 1.7 2018/05/26 20:27:48 kamil 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 #if defined(__i386__) || defined(__x86_64__) 30 union u { 31 unsigned long raw; 32 struct { 33 unsigned long local_dr0_breakpoint : 1; /* 0 */ 34 unsigned long global_dr0_breakpoint : 1; /* 1 */ 35 unsigned long local_dr1_breakpoint : 1; /* 2 */ 36 unsigned long global_dr1_breakpoint : 1; /* 3 */ 37 unsigned long local_dr2_breakpoint : 1; /* 4 */ 38 unsigned long global_dr2_breakpoint : 1; /* 5 */ 39 unsigned long local_dr3_breakpoint : 1; /* 6 */ 40 unsigned long global_dr3_breakpoint : 1; /* 7 */ 41 unsigned long local_exact_breakpt : 1; /* 8 */ 42 unsigned long global_exact_breakpt : 1; /* 9 */ 43 unsigned long reserved_10 : 1; /* 10 */ 44 unsigned long rest_trans_memory : 1; /* 11 */ 45 unsigned long reserved_12 : 1; /* 12 */ 46 unsigned long general_detect_enable : 1; /* 13 */ 47 unsigned long reserved_14 : 1; /* 14 */ 48 unsigned long reserved_15 : 1; /* 15 */ 49 unsigned long condition_dr0 : 2; /* 16-17 */ 50 unsigned long len_dr0 : 2; /* 18-19 */ 51 unsigned long condition_dr1 : 2; /* 20-21 */ 52 unsigned long len_dr1 : 2; /* 22-23 */ 53 unsigned long condition_dr2 : 2; /* 24-25 */ 54 unsigned long len_dr2 : 2; /* 26-27 */ 55 unsigned long condition_dr3 : 2; /* 28-29 */ 56 unsigned long len_dr3 : 2; /* 30-31 */ 57 } bits; 58 }; 59 60 ATF_TC(dbregs_print); 61 ATF_TC_HEAD(dbregs_print, tc) 62 { 63 atf_tc_set_md_var(tc, "descr", 64 "Verify plain PT_GETDBREGS with printing Debug Registers"); 65 } 66 67 ATF_TC_BODY(dbregs_print, tc) 68 { 69 const int exitval = 5; 70 const int sigval = SIGSTOP; 71 pid_t child, wpid; 72 #if defined(TWAIT_HAVE_STATUS) 73 int status; 74 #endif 75 struct dbreg r; 76 size_t i; 77 78 DPRINTF("Before forking process PID=%d\n", getpid()); 79 SYSCALL_REQUIRE((child = fork()) != -1); 80 if (child == 0) { 81 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 82 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 83 84 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 85 FORKEE_ASSERT(raise(sigval) == 0); 86 87 DPRINTF("Before exiting of the child process\n"); 88 _exit(exitval); 89 } 90 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 91 92 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 93 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 94 95 validate_status_stopped(status, sigval); 96 97 DPRINTF("Call GETDBREGS for the child process\n"); 98 SYSCALL_REQUIRE(ptrace(PT_GETDBREGS, child, &r, 0) != -1); 99 100 DPRINTF("State of the debug registers:\n"); 101 for (i = 0; i < __arraycount(r.dr); i++) 102 DPRINTF("r[%zu]=%" PRIxREGISTER "\n", i, r.dr[i]); 103 104 DPRINTF("Before resuming the child process where it left off and " 105 "without signal to be sent\n"); 106 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 107 108 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 109 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 110 111 validate_status_exited(status, exitval); 112 113 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 114 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 115 } 116 117 118 enum dbreg_preserve_mode { 119 dbreg_preserve_mode_none, 120 dbreg_preserve_mode_yield, 121 dbreg_preserve_mode_continued 122 }; 123 124 static void 125 dbreg_preserve(int reg, enum dbreg_preserve_mode mode) 126 { 127 const int exitval = 5; 128 const int sigval = SIGSTOP; 129 pid_t child, wpid; 130 #if defined(TWAIT_HAVE_STATUS) 131 int status; 132 #endif 133 struct dbreg r1; 134 struct dbreg r2; 135 size_t i; 136 int watchme; 137 138 if (!can_we_set_dbregs()) { 139 atf_tc_skip("Either run this test as root or set sysctl(3) " 140 "security.models.extensions.user_set_dbregs to 1"); 141 } 142 143 DPRINTF("Before forking process PID=%d\n", getpid()); 144 SYSCALL_REQUIRE((child = fork()) != -1); 145 if (child == 0) { 146 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 147 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 148 149 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 150 FORKEE_ASSERT(raise(sigval) == 0); 151 152 if (mode == dbreg_preserve_mode_continued) { 153 DPRINTF("Before raising %s from child\n", 154 strsignal(sigval)); 155 FORKEE_ASSERT(raise(sigval) == 0); 156 } 157 158 DPRINTF("Before exiting of the child process\n"); 159 _exit(exitval); 160 } 161 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 162 163 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 164 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 165 166 validate_status_stopped(status, sigval); 167 168 DPRINTF("Call GETDBREGS for the child process (r1)\n"); 169 SYSCALL_REQUIRE(ptrace(PT_GETDBREGS, child, &r1, 0) != -1); 170 171 DPRINTF("State of the debug registers (r1):\n"); 172 for (i = 0; i < __arraycount(r1.dr); i++) 173 DPRINTF("r1[%zu]=%" PRIxREGISTER "\n", i, r1.dr[i]); 174 175 r1.dr[reg] = (long)(intptr_t)&watchme; 176 DPRINTF("Set DR0 (r1.dr[%d]) to new value %" PRIxREGISTER "\n", 177 reg, r1.dr[reg]); 178 179 DPRINTF("New state of the debug registers (r1):\n"); 180 for (i = 0; i < __arraycount(r1.dr); i++) 181 DPRINTF("r1[%zu]=%" PRIxREGISTER "\n", i, r1.dr[i]); 182 183 DPRINTF("Call SETDBREGS for the child process (r1)\n"); 184 SYSCALL_REQUIRE(ptrace(PT_SETDBREGS, child, &r1, 0) != -1); 185 186 switch (mode) { 187 case dbreg_preserve_mode_none: 188 break; 189 case dbreg_preserve_mode_yield: 190 DPRINTF("Yields a processor voluntarily and gives other " 191 "threads a chance to run without waiting for an " 192 "involuntary preemptive switch\n"); 193 sched_yield(); 194 break; 195 case dbreg_preserve_mode_continued: 196 DPRINTF("Call CONTINUE for the child process\n"); 197 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 198 199 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 200 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 201 202 validate_status_stopped(status, sigval); 203 break; 204 } 205 206 DPRINTF("Call GETDBREGS for the child process (r2)\n"); 207 SYSCALL_REQUIRE(ptrace(PT_GETDBREGS, child, &r2, 0) != -1); 208 209 DPRINTF("Assert that (r1) and (r2) are the same\n"); 210 SYSCALL_REQUIRE(memcmp(&r1, &r2, sizeof(r1)) == 0); 211 212 DPRINTF("Before resuming the child process where it left off and " 213 "without signal to be sent\n"); 214 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 215 216 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 217 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 218 219 validate_status_exited(status, exitval); 220 221 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 222 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 223 } 224 225 226 ATF_TC(dbregs_preserve_dr0); 227 ATF_TC_HEAD(dbregs_preserve_dr0, tc) 228 { 229 atf_tc_set_md_var(tc, "descr", 230 "Verify that setting DR0 is preserved across ptrace(2) calls"); 231 } 232 233 ATF_TC_BODY(dbregs_preserve_dr0, tc) 234 { 235 dbreg_preserve(0, dbreg_preserve_mode_none); 236 } 237 238 ATF_TC(dbregs_preserve_dr1); 239 ATF_TC_HEAD(dbregs_preserve_dr1, tc) 240 { 241 atf_tc_set_md_var(tc, "descr", 242 "Verify that setting DR1 is preserved across ptrace(2) calls"); 243 } 244 245 ATF_TC_BODY(dbregs_preserve_dr1, tc) 246 { 247 dbreg_preserve(1, dbreg_preserve_mode_none); 248 } 249 250 ATF_TC(dbregs_preserve_dr2); 251 ATF_TC_HEAD(dbregs_preserve_dr2, tc) 252 { 253 atf_tc_set_md_var(tc, "descr", 254 "Verify that setting DR2 is preserved across ptrace(2) calls"); 255 } 256 257 ATF_TC_BODY(dbregs_preserve_dr2, tc) 258 { 259 dbreg_preserve(2, dbreg_preserve_mode_none); 260 } 261 262 ATF_TC(dbregs_preserve_dr3); 263 ATF_TC_HEAD(dbregs_preserve_dr3, tc) 264 { 265 atf_tc_set_md_var(tc, "descr", 266 "Verify that setting DR3 is preserved across ptrace(2) calls"); 267 } 268 269 ATF_TC_BODY(dbregs_preserve_dr3, tc) 270 { 271 dbreg_preserve(3, dbreg_preserve_mode_none); 272 } 273 274 ATF_TC(dbregs_preserve_dr0_yield); 275 ATF_TC_HEAD(dbregs_preserve_dr0_yield, tc) 276 { 277 atf_tc_set_md_var(tc, "descr", 278 "Verify that setting DR0 is preserved across ptrace(2) calls with " 279 "scheduler yield"); 280 } 281 282 ATF_TC_BODY(dbregs_preserve_dr0_yield, tc) 283 { 284 dbreg_preserve(0, dbreg_preserve_mode_yield); 285 } 286 287 ATF_TC(dbregs_preserve_dr1_yield); 288 ATF_TC_HEAD(dbregs_preserve_dr1_yield, tc) 289 { 290 atf_tc_set_md_var(tc, "descr", 291 "Verify that setting DR1 is preserved across ptrace(2) calls with " 292 "scheduler yield"); 293 } 294 295 ATF_TC_BODY(dbregs_preserve_dr1_yield, tc) 296 { 297 dbreg_preserve(0, dbreg_preserve_mode_yield); 298 } 299 300 ATF_TC(dbregs_preserve_dr2_yield); 301 ATF_TC_HEAD(dbregs_preserve_dr2_yield, tc) 302 { 303 atf_tc_set_md_var(tc, "descr", 304 "Verify that setting DR2 is preserved across ptrace(2) calls with " 305 "scheduler yield"); 306 } 307 308 ATF_TC_BODY(dbregs_preserve_dr2_yield, tc) 309 { 310 dbreg_preserve(0, dbreg_preserve_mode_yield); 311 } 312 313 314 ATF_TC(dbregs_preserve_dr3_yield); 315 ATF_TC_HEAD(dbregs_preserve_dr3_yield, tc) 316 { 317 atf_tc_set_md_var(tc, "descr", 318 "Verify that setting DR3 is preserved across ptrace(2) calls with " 319 "scheduler yield"); 320 } 321 322 ATF_TC_BODY(dbregs_preserve_dr3_yield, tc) 323 { 324 dbreg_preserve(3, dbreg_preserve_mode_yield); 325 } 326 327 ATF_TC(dbregs_preserve_dr0_continued); 328 ATF_TC_HEAD(dbregs_preserve_dr0_continued, tc) 329 { 330 atf_tc_set_md_var(tc, "descr", 331 "Verify that setting DR0 is preserved across ptrace(2) calls and " 332 "with continued child"); 333 } 334 335 ATF_TC_BODY(dbregs_preserve_dr0_continued, tc) 336 { 337 dbreg_preserve(0, dbreg_preserve_mode_continued); 338 } 339 340 ATF_TC(dbregs_preserve_dr1_continued); 341 ATF_TC_HEAD(dbregs_preserve_dr1_continued, tc) 342 { 343 atf_tc_set_md_var(tc, "descr", 344 "Verify that setting DR1 is preserved across ptrace(2) calls and " 345 "with continued child"); 346 } 347 348 ATF_TC_BODY(dbregs_preserve_dr1_continued, tc) 349 { 350 dbreg_preserve(1, dbreg_preserve_mode_continued); 351 } 352 353 ATF_TC(dbregs_preserve_dr2_continued); 354 ATF_TC_HEAD(dbregs_preserve_dr2_continued, tc) 355 { 356 atf_tc_set_md_var(tc, "descr", 357 "Verify that setting DR2 is preserved across ptrace(2) calls and " 358 "with continued child"); 359 } 360 361 ATF_TC_BODY(dbregs_preserve_dr2_continued, tc) 362 { 363 dbreg_preserve(2, dbreg_preserve_mode_continued); 364 } 365 366 ATF_TC(dbregs_preserve_dr3_continued); 367 ATF_TC_HEAD(dbregs_preserve_dr3_continued, tc) 368 { 369 atf_tc_set_md_var(tc, "descr", 370 "Verify that setting DR3 is preserved across ptrace(2) calls and " 371 "with continued child"); 372 } 373 374 ATF_TC_BODY(dbregs_preserve_dr3_continued, tc) 375 { 376 dbreg_preserve(3, dbreg_preserve_mode_continued); 377 } 378 379 380 static void 381 dbregs_trap_variable(int reg, int cond, int len, bool write) 382 { 383 const int exitval = 5; 384 const int sigval = SIGSTOP; 385 pid_t child, wpid; 386 #if defined(TWAIT_HAVE_STATUS) 387 int status; 388 #endif 389 struct dbreg r1; 390 size_t i; 391 volatile int watchme = 0; 392 union u dr7; 393 394 struct ptrace_siginfo info; 395 memset(&info, 0, sizeof(info)); 396 397 if (!can_we_set_dbregs()) { 398 atf_tc_skip("Either run this test as root or set sysctl(3) " 399 "security.models.extensions.user_set_dbregs to 1"); 400 } 401 402 dr7.raw = 0; 403 switch (reg) { 404 case 0: 405 dr7.bits.global_dr0_breakpoint = 1; 406 dr7.bits.condition_dr0 = cond; 407 dr7.bits.len_dr0 = len; 408 case 1: 409 dr7.bits.global_dr1_breakpoint = 1; 410 dr7.bits.condition_dr1 = cond; 411 dr7.bits.len_dr1 = len; 412 case 2: 413 dr7.bits.global_dr2_breakpoint = 1; 414 dr7.bits.condition_dr2 = cond; 415 dr7.bits.len_dr2 = len; 416 case 3: 417 dr7.bits.global_dr3_breakpoint = 1; 418 dr7.bits.condition_dr3 = cond; 419 dr7.bits.len_dr3 = len; 420 break; 421 } 422 423 DPRINTF("Before forking process PID=%d\n", getpid()); 424 SYSCALL_REQUIRE((child = fork()) != -1); 425 if (child == 0) { 426 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 427 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 428 429 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 430 FORKEE_ASSERT(raise(sigval) == 0); 431 432 if (write) 433 watchme = 1; 434 else 435 printf("watchme=%d\n", watchme); 436 437 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 438 FORKEE_ASSERT(raise(sigval) == 0); 439 440 DPRINTF("Before exiting of the child process\n"); 441 _exit(exitval); 442 } 443 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 444 445 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 446 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 447 448 validate_status_stopped(status, sigval); 449 450 DPRINTF("Call GETDBREGS for the child process (r1)\n"); 451 SYSCALL_REQUIRE(ptrace(PT_GETDBREGS, child, &r1, 0) != -1); 452 453 DPRINTF("State of the debug registers (r1):\n"); 454 for (i = 0; i < __arraycount(r1.dr); i++) 455 DPRINTF("r1[%zu]=%" PRIxREGISTER "\n", i, r1.dr[i]); 456 457 r1.dr[reg] = (long)(intptr_t)&watchme; 458 DPRINTF("Set DR%d (r1.dr[%d]) to new value %" PRIxREGISTER "\n", 459 reg, reg, r1.dr[reg]); 460 461 r1.dr[7] = dr7.raw; 462 DPRINTF("Set DR7 (r1.dr[7]) to new value %" PRIxREGISTER "\n", 463 r1.dr[7]); 464 465 DPRINTF("New state of the debug registers (r1):\n"); 466 for (i = 0; i < __arraycount(r1.dr); i++) 467 DPRINTF("r1[%zu]=%" PRIxREGISTER "\n", i, r1.dr[i]); 468 469 DPRINTF("Call SETDBREGS for the child process (r1)\n"); 470 SYSCALL_REQUIRE(ptrace(PT_SETDBREGS, child, &r1, 0) != -1); 471 472 DPRINTF("Call CONTINUE for the child process\n"); 473 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 474 475 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 476 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 477 478 validate_status_stopped(status, SIGTRAP); 479 480 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 481 SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 482 483 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 484 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 485 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 486 info.psi_siginfo.si_errno); 487 488 DPRINTF("Before checking siginfo_t\n"); 489 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); 490 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_DBREG); 491 492 DPRINTF("Call CONTINUE for the child process\n"); 493 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 494 495 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 496 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 497 498 validate_status_stopped(status, sigval); 499 500 DPRINTF("Before resuming the child process where it left off and " 501 "without signal to be sent\n"); 502 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 503 504 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 505 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 506 507 validate_status_exited(status, exitval); 508 509 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 510 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 511 } 512 513 ATF_TC(dbregs_dr0_trap_variable_writeonly_byte); 514 ATF_TC_HEAD(dbregs_dr0_trap_variable_writeonly_byte, tc) 515 { 516 atf_tc_set_md_var(tc, "descr", 517 "Verify that setting trap with DR0 triggers SIGTRAP " 518 "(break on data writes only and 1 byte mode)"); 519 } 520 521 ATF_TC_BODY(dbregs_dr0_trap_variable_writeonly_byte, tc) 522 { 523 /* 0b01 -- break on data write only */ 524 /* 0b00 -- 1 byte */ 525 526 dbregs_trap_variable(0, 1, 0, true); 527 } 528 529 ATF_TC(dbregs_dr1_trap_variable_writeonly_byte); 530 ATF_TC_HEAD(dbregs_dr1_trap_variable_writeonly_byte, tc) 531 { 532 atf_tc_set_md_var(tc, "descr", 533 "Verify that setting trap with DR1 triggers SIGTRAP " 534 "(break on data writes only and 1 byte mode)"); 535 } 536 537 ATF_TC_BODY(dbregs_dr1_trap_variable_writeonly_byte, tc) 538 { 539 /* 0b01 -- break on data write only */ 540 /* 0b00 -- 1 byte */ 541 542 dbregs_trap_variable(1, 1, 0, true); 543 } 544 545 ATF_TC(dbregs_dr2_trap_variable_writeonly_byte); 546 ATF_TC_HEAD(dbregs_dr2_trap_variable_writeonly_byte, tc) 547 { 548 atf_tc_set_md_var(tc, "descr", 549 "Verify that setting trap with DR2 triggers SIGTRAP " 550 "(break on data writes only and 1 byte mode)"); 551 } 552 553 ATF_TC_BODY(dbregs_dr2_trap_variable_writeonly_byte, tc) 554 { 555 /* 0b01 -- break on data write only */ 556 /* 0b00 -- 1 byte */ 557 558 dbregs_trap_variable(2, 1, 0, true); 559 } 560 561 ATF_TC(dbregs_dr3_trap_variable_writeonly_byte); 562 ATF_TC_HEAD(dbregs_dr3_trap_variable_writeonly_byte, tc) 563 { 564 atf_tc_set_md_var(tc, "descr", 565 "Verify that setting trap with DR3 triggers SIGTRAP " 566 "(break on data writes only and 1 byte mode)"); 567 } 568 569 ATF_TC_BODY(dbregs_dr3_trap_variable_writeonly_byte, tc) 570 { 571 /* 0b01 -- break on data write only */ 572 /* 0b00 -- 1 byte */ 573 574 dbregs_trap_variable(3, 1, 0, true); 575 } 576 577 ATF_TC(dbregs_dr0_trap_variable_writeonly_2bytes); 578 ATF_TC_HEAD(dbregs_dr0_trap_variable_writeonly_2bytes, tc) 579 { 580 atf_tc_set_md_var(tc, "descr", 581 "Verify that setting trap with DR0 triggers SIGTRAP " 582 "(break on data writes only and 2 bytes mode)"); 583 } 584 585 ATF_TC_BODY(dbregs_dr0_trap_variable_writeonly_2bytes, tc) 586 { 587 /* 0b01 -- break on data write only */ 588 /* 0b01 -- 2 bytes */ 589 590 dbregs_trap_variable(0, 1, 1, true); 591 } 592 593 ATF_TC(dbregs_dr1_trap_variable_writeonly_2bytes); 594 ATF_TC_HEAD(dbregs_dr1_trap_variable_writeonly_2bytes, tc) 595 { 596 atf_tc_set_md_var(tc, "descr", 597 "Verify that setting trap with DR1 triggers SIGTRAP " 598 "(break on data writes only and 2 bytes mode)"); 599 } 600 601 ATF_TC_BODY(dbregs_dr1_trap_variable_writeonly_2bytes, tc) 602 { 603 /* 0b01 -- break on data write only */ 604 /* 0b01 -- 2 bytes */ 605 606 dbregs_trap_variable(1, 1, 1, true); 607 } 608 609 ATF_TC(dbregs_dr2_trap_variable_writeonly_2bytes); 610 ATF_TC_HEAD(dbregs_dr2_trap_variable_writeonly_2bytes, tc) 611 { 612 atf_tc_set_md_var(tc, "descr", 613 "Verify that setting trap with DR2 triggers SIGTRAP " 614 "(break on data writes only and 2 bytes mode)"); 615 } 616 617 ATF_TC_BODY(dbregs_dr2_trap_variable_writeonly_2bytes, tc) 618 { 619 /* 0b01 -- break on data write only */ 620 /* 0b01 -- 2 bytes */ 621 622 dbregs_trap_variable(2, 1, 1, true); 623 } 624 625 ATF_TC(dbregs_dr3_trap_variable_writeonly_2bytes); 626 ATF_TC_HEAD(dbregs_dr3_trap_variable_writeonly_2bytes, tc) 627 { 628 atf_tc_set_md_var(tc, "descr", 629 "Verify that setting trap with DR3 triggers SIGTRAP " 630 "(break on data writes only and 2 bytes mode)"); 631 } 632 633 ATF_TC_BODY(dbregs_dr3_trap_variable_writeonly_2bytes, tc) 634 { 635 /* 0b01 -- break on data write only */ 636 /* 0b01 -- 2 bytes */ 637 638 dbregs_trap_variable(3, 1, 1, true); 639 } 640 641 ATF_TC(dbregs_dr0_trap_variable_writeonly_4bytes); 642 ATF_TC_HEAD(dbregs_dr0_trap_variable_writeonly_4bytes, tc) 643 { 644 atf_tc_set_md_var(tc, "descr", 645 "Verify that setting trap with DR0 triggers SIGTRAP " 646 "(break on data writes only and 4 bytes mode)"); 647 } 648 649 ATF_TC_BODY(dbregs_dr0_trap_variable_writeonly_4bytes, tc) 650 { 651 /* 0b01 -- break on data write only */ 652 /* 0b11 -- 4 bytes */ 653 654 dbregs_trap_variable(0, 1, 3, true); 655 } 656 657 ATF_TC(dbregs_dr1_trap_variable_writeonly_4bytes); 658 ATF_TC_HEAD(dbregs_dr1_trap_variable_writeonly_4bytes, tc) 659 { 660 atf_tc_set_md_var(tc, "descr", 661 "Verify that setting trap with DR1 triggers SIGTRAP " 662 "(break on data writes only and 4 bytes mode)"); 663 } 664 665 ATF_TC_BODY(dbregs_dr1_trap_variable_writeonly_4bytes, tc) 666 { 667 /* 0b01 -- break on data write only */ 668 /* 0b11 -- 4 bytes */ 669 670 dbregs_trap_variable(1, 1, 3, true); 671 } 672 673 ATF_TC(dbregs_dr2_trap_variable_writeonly_4bytes); 674 ATF_TC_HEAD(dbregs_dr2_trap_variable_writeonly_4bytes, tc) 675 { 676 atf_tc_set_md_var(tc, "descr", 677 "Verify that setting trap with DR2 triggers SIGTRAP " 678 "(break on data writes only and 4 bytes mode)"); 679 } 680 681 ATF_TC_BODY(dbregs_dr2_trap_variable_writeonly_4bytes, tc) 682 { 683 /* 0b01 -- break on data write only */ 684 /* 0b11 -- 4 bytes */ 685 686 dbregs_trap_variable(2, 1, 3, true); 687 } 688 689 ATF_TC(dbregs_dr3_trap_variable_writeonly_4bytes); 690 ATF_TC_HEAD(dbregs_dr3_trap_variable_writeonly_4bytes, tc) 691 { 692 atf_tc_set_md_var(tc, "descr", 693 "Verify that setting trap with DR3 triggers SIGTRAP " 694 "(break on data writes only and 4 bytes mode)"); 695 } 696 697 ATF_TC_BODY(dbregs_dr3_trap_variable_writeonly_4bytes, tc) 698 { 699 /* 0b01 -- break on data write only */ 700 /* 0b11 -- 4 bytes */ 701 702 dbregs_trap_variable(3, 1, 3, true); 703 } 704 705 ATF_TC(dbregs_dr0_trap_variable_readwrite_write_byte); 706 ATF_TC_HEAD(dbregs_dr0_trap_variable_readwrite_write_byte, tc) 707 { 708 atf_tc_set_md_var(tc, "descr", 709 "Verify that setting trap with DR0 triggers SIGTRAP " 710 "(break on data read/write trap in read 1 byte mode)"); 711 } 712 713 ATF_TC_BODY(dbregs_dr0_trap_variable_readwrite_write_byte, tc) 714 { 715 /* 0b11 -- break on data write&read */ 716 /* 0b00 -- 1 byte */ 717 718 dbregs_trap_variable(0, 3, 0, true); 719 } 720 721 ATF_TC(dbregs_dr1_trap_variable_readwrite_write_byte); 722 ATF_TC_HEAD(dbregs_dr1_trap_variable_readwrite_write_byte, tc) 723 { 724 atf_tc_set_md_var(tc, "descr", 725 "Verify that setting trap with DR1 triggers SIGTRAP " 726 "(break on data read/write trap in read 1 byte mode)"); 727 } 728 729 ATF_TC_BODY(dbregs_dr1_trap_variable_readwrite_write_byte, tc) 730 { 731 /* 0b11 -- break on data write&read */ 732 /* 0b00 -- 1 byte */ 733 734 dbregs_trap_variable(1, 3, 0, true); 735 } 736 737 ATF_TC(dbregs_dr2_trap_variable_readwrite_write_byte); 738 ATF_TC_HEAD(dbregs_dr2_trap_variable_readwrite_write_byte, tc) 739 { 740 atf_tc_set_md_var(tc, "descr", 741 "Verify that setting trap with DR2 triggers SIGTRAP " 742 "(break on data read/write trap in read 1 byte mode)"); 743 } 744 745 ATF_TC_BODY(dbregs_dr2_trap_variable_readwrite_write_byte, tc) 746 { 747 /* 0b11 -- break on data write&read */ 748 /* 0b00 -- 1 byte */ 749 750 dbregs_trap_variable(2, 3, 0, true); 751 } 752 753 ATF_TC(dbregs_dr3_trap_variable_readwrite_write_byte); 754 ATF_TC_HEAD(dbregs_dr3_trap_variable_readwrite_write_byte, tc) 755 { 756 atf_tc_set_md_var(tc, "descr", 757 "Verify that setting trap with DR3 triggers SIGTRAP " 758 "(break on data read/write trap in read 1 byte mode)"); 759 } 760 761 ATF_TC_BODY(dbregs_dr3_trap_variable_readwrite_write_byte, tc) 762 { 763 /* 0b11 -- break on data write&read */ 764 /* 0b00 -- 1 byte */ 765 766 dbregs_trap_variable(3, 3, 0, true); 767 } 768 769 ATF_TC(dbregs_dr0_trap_variable_readwrite_write_2bytes); 770 ATF_TC_HEAD(dbregs_dr0_trap_variable_readwrite_write_2bytes, tc) 771 { 772 atf_tc_set_md_var(tc, "descr", 773 "Verify that setting trap with DR0 triggers SIGTRAP " 774 "(break on data read/write trap in read 2 bytes mode)"); 775 } 776 777 ATF_TC_BODY(dbregs_dr0_trap_variable_readwrite_write_2bytes, tc) 778 { 779 /* 0b11 -- break on data write&read */ 780 /* 0b01 -- 2 bytes */ 781 782 dbregs_trap_variable(0, 3, 1, true); 783 } 784 785 ATF_TC(dbregs_dr1_trap_variable_readwrite_write_2bytes); 786 ATF_TC_HEAD(dbregs_dr1_trap_variable_readwrite_write_2bytes, tc) 787 { 788 atf_tc_set_md_var(tc, "descr", 789 "Verify that setting trap with DR1 triggers SIGTRAP " 790 "(break on data read/write trap in read 2 bytes mode)"); 791 } 792 793 ATF_TC_BODY(dbregs_dr1_trap_variable_readwrite_write_2bytes, tc) 794 { 795 /* 0b11 -- break on data write&read */ 796 /* 0b01 -- 2 bytes */ 797 798 dbregs_trap_variable(1, 3, 1, true); 799 } 800 801 ATF_TC(dbregs_dr2_trap_variable_readwrite_write_2bytes); 802 ATF_TC_HEAD(dbregs_dr2_trap_variable_readwrite_write_2bytes, tc) 803 { 804 atf_tc_set_md_var(tc, "descr", 805 "Verify that setting trap with DR2 triggers SIGTRAP " 806 "(break on data read/write trap in read 2 bytes mode)"); 807 } 808 809 ATF_TC_BODY(dbregs_dr2_trap_variable_readwrite_write_2bytes, tc) 810 { 811 /* 0b11 -- break on data write&read */ 812 /* 0b01 -- 2 bytes */ 813 814 dbregs_trap_variable(2, 3, 1, true); 815 } 816 817 ATF_TC(dbregs_dr3_trap_variable_readwrite_write_2bytes); 818 ATF_TC_HEAD(dbregs_dr3_trap_variable_readwrite_write_2bytes, tc) 819 { 820 atf_tc_set_md_var(tc, "descr", 821 "Verify that setting trap with DR3 triggers SIGTRAP " 822 "(break on data read/write trap in read 2 bytes mode)"); 823 } 824 825 ATF_TC_BODY(dbregs_dr3_trap_variable_readwrite_write_2bytes, tc) 826 { 827 /* 0b11 -- break on data write&read */ 828 /* 0b01 -- 2 bytes */ 829 830 dbregs_trap_variable(3, 3, 1, true); 831 } 832 833 ATF_TC(dbregs_dr0_trap_variable_readwrite_write_4bytes); 834 ATF_TC_HEAD(dbregs_dr0_trap_variable_readwrite_write_4bytes, tc) 835 { 836 atf_tc_set_md_var(tc, "descr", 837 "Verify that setting trap with DR0 triggers SIGTRAP " 838 "(break on data read/write trap in read 4 bytes mode)"); 839 } 840 841 ATF_TC_BODY(dbregs_dr0_trap_variable_readwrite_write_4bytes, tc) 842 { 843 /* 0b11 -- break on data write&read */ 844 /* 0b11 -- 4 bytes */ 845 846 dbregs_trap_variable(0, 3, 3, true); 847 } 848 849 ATF_TC(dbregs_dr1_trap_variable_readwrite_write_4bytes); 850 ATF_TC_HEAD(dbregs_dr1_trap_variable_readwrite_write_4bytes, tc) 851 { 852 atf_tc_set_md_var(tc, "descr", 853 "Verify that setting trap with DR1 triggers SIGTRAP " 854 "(break on data read/write trap in read 4 bytes mode)"); 855 } 856 857 ATF_TC_BODY(dbregs_dr1_trap_variable_readwrite_write_4bytes, tc) 858 { 859 /* 0b11 -- break on data write&read */ 860 /* 0b11 -- 4 bytes */ 861 862 dbregs_trap_variable(1, 3, 3, true); 863 } 864 865 ATF_TC(dbregs_dr2_trap_variable_readwrite_write_4bytes); 866 ATF_TC_HEAD(dbregs_dr2_trap_variable_readwrite_write_4bytes, tc) 867 { 868 atf_tc_set_md_var(tc, "descr", 869 "Verify that setting trap with DR2 triggers SIGTRAP " 870 "(break on data read/write trap in read 4 bytes mode)"); 871 } 872 873 ATF_TC_BODY(dbregs_dr2_trap_variable_readwrite_write_4bytes, tc) 874 { 875 /* 0b11 -- break on data write&read */ 876 /* 0b11 -- 4 bytes */ 877 878 dbregs_trap_variable(2, 3, 3, true); 879 } 880 881 ATF_TC(dbregs_dr3_trap_variable_readwrite_write_4bytes); 882 ATF_TC_HEAD(dbregs_dr3_trap_variable_readwrite_write_4bytes, tc) 883 { 884 atf_tc_set_md_var(tc, "descr", 885 "Verify that setting trap with DR3 triggers SIGTRAP " 886 "(break on data read/write trap in read 4 bytes mode)"); 887 } 888 889 ATF_TC_BODY(dbregs_dr3_trap_variable_readwrite_write_4bytes, tc) 890 { 891 /* 0b11 -- break on data write&read */ 892 /* 0b11 -- 4 bytes */ 893 894 dbregs_trap_variable(3, 3, 3, true); 895 } 896 897 ATF_TC(dbregs_dr0_trap_variable_readwrite_read_byte); 898 ATF_TC_HEAD(dbregs_dr0_trap_variable_readwrite_read_byte, tc) 899 { 900 atf_tc_set_md_var(tc, "descr", 901 "Verify that setting trap with DR0 triggers SIGTRAP " 902 "(break on data read/write trap in write 1 byte mode)"); 903 } 904 905 ATF_TC_BODY(dbregs_dr0_trap_variable_readwrite_read_byte, tc) 906 { 907 /* 0b11 -- break on data write&read */ 908 /* 0b00 -- 1 byte */ 909 910 dbregs_trap_variable(0, 3, 0, false); 911 } 912 913 ATF_TC(dbregs_dr1_trap_variable_readwrite_read_byte); 914 ATF_TC_HEAD(dbregs_dr1_trap_variable_readwrite_read_byte, tc) 915 { 916 atf_tc_set_md_var(tc, "descr", 917 "Verify that setting trap with DR1 triggers SIGTRAP " 918 "(break on data read/write trap in write 1 byte mode)"); 919 } 920 921 ATF_TC_BODY(dbregs_dr1_trap_variable_readwrite_read_byte, tc) 922 { 923 /* 0b11 -- break on data write&read */ 924 /* 0b00 -- 1 byte */ 925 926 dbregs_trap_variable(1, 3, 0, false); 927 } 928 929 ATF_TC(dbregs_dr2_trap_variable_readwrite_read_byte); 930 ATF_TC_HEAD(dbregs_dr2_trap_variable_readwrite_read_byte, tc) 931 { 932 atf_tc_set_md_var(tc, "descr", 933 "Verify that setting trap with DR2 triggers SIGTRAP " 934 "(break on data read/write trap in write 1 byte mode)"); 935 } 936 937 ATF_TC_BODY(dbregs_dr2_trap_variable_readwrite_read_byte, tc) 938 { 939 /* 0b11 -- break on data write&read */ 940 /* 0b00 -- 1 byte */ 941 942 dbregs_trap_variable(2, 3, 0, false); 943 } 944 945 ATF_TC(dbregs_dr3_trap_variable_readwrite_read_byte); 946 ATF_TC_HEAD(dbregs_dr3_trap_variable_readwrite_read_byte, tc) 947 { 948 atf_tc_set_md_var(tc, "descr", 949 "Verify that setting trap with DR3 triggers SIGTRAP " 950 "(break on data read/write trap in write 1 byte mode)"); 951 } 952 953 ATF_TC_BODY(dbregs_dr3_trap_variable_readwrite_read_byte, tc) 954 { 955 /* 0b11 -- break on data write&read */ 956 /* 0b00 -- 1 byte */ 957 958 dbregs_trap_variable(3, 3, 0, false); 959 } 960 961 ATF_TC(dbregs_dr0_trap_variable_readwrite_read_2bytes); 962 ATF_TC_HEAD(dbregs_dr0_trap_variable_readwrite_read_2bytes, tc) 963 { 964 atf_tc_set_md_var(tc, "descr", 965 "Verify that setting trap with DR0 triggers SIGTRAP " 966 "(break on data read/write trap in write 2 bytes mode)"); 967 } 968 969 ATF_TC_BODY(dbregs_dr0_trap_variable_readwrite_read_2bytes, tc) 970 { 971 /* 0b11 -- break on data write&read */ 972 /* 0b01 -- 2 bytes */ 973 974 dbregs_trap_variable(0, 3, 1, false); 975 } 976 977 ATF_TC(dbregs_dr1_trap_variable_readwrite_read_2bytes); 978 ATF_TC_HEAD(dbregs_dr1_trap_variable_readwrite_read_2bytes, tc) 979 { 980 atf_tc_set_md_var(tc, "descr", 981 "Verify that setting trap with DR1 triggers SIGTRAP " 982 "(break on data read/write trap in write 2 bytes mode)"); 983 } 984 985 ATF_TC_BODY(dbregs_dr1_trap_variable_readwrite_read_2bytes, tc) 986 { 987 /* 0b11 -- break on data write&read */ 988 /* 0b01 -- 2 bytes */ 989 990 dbregs_trap_variable(1, 3, 1, false); 991 } 992 993 ATF_TC(dbregs_dr2_trap_variable_readwrite_read_2bytes); 994 ATF_TC_HEAD(dbregs_dr2_trap_variable_readwrite_read_2bytes, tc) 995 { 996 atf_tc_set_md_var(tc, "descr", 997 "Verify that setting trap with DR2 triggers SIGTRAP " 998 "(break on data read/write trap in write 2 bytes mode)"); 999 } 1000 1001 ATF_TC_BODY(dbregs_dr2_trap_variable_readwrite_read_2bytes, tc) 1002 { 1003 /* 0b11 -- break on data write&read */ 1004 /* 0b01 -- 2 bytes */ 1005 1006 dbregs_trap_variable(2, 3, 1, false); 1007 } 1008 1009 ATF_TC(dbregs_dr3_trap_variable_readwrite_read_2bytes); 1010 ATF_TC_HEAD(dbregs_dr3_trap_variable_readwrite_read_2bytes, tc) 1011 { 1012 atf_tc_set_md_var(tc, "descr", 1013 "Verify that setting trap with DR3 triggers SIGTRAP " 1014 "(break on data read/write trap in write 2 bytes mode)"); 1015 } 1016 1017 ATF_TC_BODY(dbregs_dr3_trap_variable_readwrite_read_2bytes, tc) 1018 { 1019 /* 0b11 -- break on data write&read */ 1020 /* 0b01 -- 2 bytes */ 1021 1022 dbregs_trap_variable(3, 3, 1, false); 1023 } 1024 1025 ATF_TC(dbregs_dr0_trap_variable_readwrite_read_4bytes); 1026 ATF_TC_HEAD(dbregs_dr0_trap_variable_readwrite_read_4bytes, tc) 1027 { 1028 atf_tc_set_md_var(tc, "descr", 1029 "Verify that setting trap with DR0 triggers SIGTRAP " 1030 "(break on data read/write trap in write 4 bytes mode)"); 1031 } 1032 1033 ATF_TC_BODY(dbregs_dr0_trap_variable_readwrite_read_4bytes, tc) 1034 { 1035 /* 0b11 -- break on data write&read */ 1036 /* 0b11 -- 4 bytes */ 1037 1038 dbregs_trap_variable(0, 3, 3, false); 1039 } 1040 1041 ATF_TC(dbregs_dr1_trap_variable_readwrite_read_4bytes); 1042 ATF_TC_HEAD(dbregs_dr1_trap_variable_readwrite_read_4bytes, tc) 1043 { 1044 atf_tc_set_md_var(tc, "descr", 1045 "Verify that setting trap with DR1 triggers SIGTRAP " 1046 "(break on data read/write trap in write 4 bytes mode)"); 1047 } 1048 1049 ATF_TC_BODY(dbregs_dr1_trap_variable_readwrite_read_4bytes, tc) 1050 { 1051 /* 0b11 -- break on data write&read */ 1052 /* 0b11 -- 4 bytes */ 1053 1054 dbregs_trap_variable(1, 3, 3, false); 1055 } 1056 1057 ATF_TC(dbregs_dr2_trap_variable_readwrite_read_4bytes); 1058 ATF_TC_HEAD(dbregs_dr2_trap_variable_readwrite_read_4bytes, tc) 1059 { 1060 atf_tc_set_md_var(tc, "descr", 1061 "Verify that setting trap with DR2 triggers SIGTRAP " 1062 "(break on data read/write trap in write 4 bytes mode)"); 1063 } 1064 1065 ATF_TC_BODY(dbregs_dr2_trap_variable_readwrite_read_4bytes, tc) 1066 { 1067 /* 0b11 -- break on data write&read */ 1068 /* 0b11 -- 4 bytes */ 1069 1070 dbregs_trap_variable(2, 3, 3, false); 1071 } 1072 1073 ATF_TC(dbregs_dr3_trap_variable_readwrite_read_4bytes); 1074 ATF_TC_HEAD(dbregs_dr3_trap_variable_readwrite_read_4bytes, tc) 1075 { 1076 atf_tc_set_md_var(tc, "descr", 1077 "Verify that setting trap with DR3 triggers SIGTRAP " 1078 "(break on data read/write trap in write 4 bytes mode)"); 1079 } 1080 1081 ATF_TC_BODY(dbregs_dr3_trap_variable_readwrite_read_4bytes, tc) 1082 { 1083 /* 0b11 -- break on data write&read */ 1084 /* 0b11 -- 4 bytes */ 1085 1086 dbregs_trap_variable(3, 3, 3, false); 1087 } 1088 1089 #if defined(HAVE_DBREGS) 1090 ATF_TC(dbregs_dr0_trap_code); 1091 ATF_TC_HEAD(dbregs_dr0_trap_code, tc) 1092 { 1093 atf_tc_set_md_var(tc, "descr", 1094 "Verify that setting trap with DR0 triggers SIGTRAP " 1095 "(break on code execution trap)"); 1096 } 1097 1098 ATF_TC_BODY(dbregs_dr0_trap_code, tc) 1099 { 1100 const int exitval = 5; 1101 const int sigval = SIGSTOP; 1102 pid_t child, wpid; 1103 #if defined(TWAIT_HAVE_STATUS) 1104 int status; 1105 #endif 1106 struct dbreg r1; 1107 size_t i; 1108 volatile int watchme = 1; 1109 union u dr7; 1110 1111 struct ptrace_siginfo info; 1112 memset(&info, 0, sizeof(info)); 1113 1114 if (!can_we_set_dbregs()) { 1115 atf_tc_skip("Either run this test as root or set sysctl(3) " 1116 "security.models.extensions.user_set_dbregs to 1"); 1117 } 1118 1119 dr7.raw = 0; 1120 dr7.bits.global_dr0_breakpoint = 1; 1121 dr7.bits.condition_dr0 = 0; /* 0b00 -- break on code execution */ 1122 dr7.bits.len_dr0 = 0; /* 0b00 -- 1 byte */ 1123 1124 DPRINTF("Before forking process PID=%d\n", getpid()); 1125 SYSCALL_REQUIRE((child = fork()) != -1); 1126 if (child == 0) { 1127 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 1128 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 1129 1130 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 1131 FORKEE_ASSERT(raise(sigval) == 0); 1132 1133 printf("check_happy(%d)=%d\n", watchme, check_happy(watchme)); 1134 1135 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 1136 FORKEE_ASSERT(raise(sigval) == 0); 1137 1138 DPRINTF("Before exiting of the child process\n"); 1139 _exit(exitval); 1140 } 1141 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 1142 1143 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1144 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1145 1146 validate_status_stopped(status, sigval); 1147 1148 DPRINTF("Call GETDBREGS for the child process (r1)\n"); 1149 SYSCALL_REQUIRE(ptrace(PT_GETDBREGS, child, &r1, 0) != -1); 1150 1151 DPRINTF("State of the debug registers (r1):\n"); 1152 for (i = 0; i < __arraycount(r1.dr); i++) 1153 DPRINTF("r1[%zu]=%" PRIxREGISTER "\n", i, r1.dr[i]); 1154 1155 r1.dr[0] = (long)(intptr_t)check_happy; 1156 DPRINTF("Set DR0 (r1.dr[0]) to new value %" PRIxREGISTER "\n", 1157 r1.dr[0]); 1158 1159 r1.dr[7] = dr7.raw; 1160 DPRINTF("Set DR7 (r1.dr[7]) to new value %" PRIxREGISTER "\n", 1161 r1.dr[7]); 1162 1163 DPRINTF("New state of the debug registers (r1):\n"); 1164 for (i = 0; i < __arraycount(r1.dr); i++) 1165 DPRINTF("r1[%zu]=%" PRIxREGISTER "\n", i, r1.dr[i]); 1166 1167 DPRINTF("Call SETDBREGS for the child process (r1)\n"); 1168 SYSCALL_REQUIRE(ptrace(PT_SETDBREGS, child, &r1, 0) != -1); 1169 1170 DPRINTF("Call CONTINUE for the child process\n"); 1171 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 1172 1173 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1174 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1175 1176 validate_status_stopped(status, SIGTRAP); 1177 1178 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 1179 SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 1180 1181 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 1182 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 1183 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 1184 info.psi_siginfo.si_errno); 1185 1186 DPRINTF("Before checking siginfo_t\n"); 1187 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); 1188 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_DBREG); 1189 1190 DPRINTF("Remove code trap from check_happy=%p\n", check_happy); 1191 dr7.bits.global_dr0_breakpoint = 0; 1192 r1.dr[7] = dr7.raw; 1193 DPRINTF("Set DR7 (r1.dr[7]) to new value %" PRIxREGISTER "\n", 1194 r1.dr[7]); 1195 1196 DPRINTF("Call SETDBREGS for the child process (r1)\n"); 1197 SYSCALL_REQUIRE(ptrace(PT_SETDBREGS, child, &r1, 0) != -1); 1198 1199 DPRINTF("Call CONTINUE for the child process\n"); 1200 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 1201 1202 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1203 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1204 1205 validate_status_stopped(status, sigval); 1206 1207 DPRINTF("Before resuming the child process where it left off and " 1208 "without signal to be sent\n"); 1209 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 1210 1211 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1212 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1213 1214 validate_status_exited(status, exitval); 1215 1216 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1217 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 1218 } 1219 #endif 1220 1221 #if defined(HAVE_DBREGS) 1222 ATF_TC(dbregs_dr1_trap_code); 1223 ATF_TC_HEAD(dbregs_dr1_trap_code, tc) 1224 { 1225 atf_tc_set_md_var(tc, "descr", 1226 "Verify that setting trap with DR1 triggers SIGTRAP " 1227 "(break on code execution trap)"); 1228 } 1229 1230 ATF_TC_BODY(dbregs_dr1_trap_code, tc) 1231 { 1232 const int exitval = 5; 1233 const int sigval = SIGSTOP; 1234 pid_t child, wpid; 1235 #if defined(TWAIT_HAVE_STATUS) 1236 int status; 1237 #endif 1238 struct dbreg r1; 1239 size_t i; 1240 volatile int watchme = 1; 1241 union u dr7; 1242 1243 struct ptrace_siginfo info; 1244 memset(&info, 0, sizeof(info)); 1245 1246 if (!can_we_set_dbregs()) { 1247 atf_tc_skip("Either run this test as root or set sysctl(3) " 1248 "security.models.extensions.user_set_dbregs to 1"); 1249 } 1250 1251 dr7.raw = 0; 1252 dr7.bits.global_dr1_breakpoint = 1; 1253 dr7.bits.condition_dr1 = 0; /* 0b00 -- break on code execution */ 1254 dr7.bits.len_dr1 = 0; /* 0b00 -- 1 byte */ 1255 1256 DPRINTF("Before forking process PID=%d\n", getpid()); 1257 SYSCALL_REQUIRE((child = fork()) != -1); 1258 if (child == 0) { 1259 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 1260 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 1261 1262 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 1263 FORKEE_ASSERT(raise(sigval) == 0); 1264 1265 printf("check_happy(%d)=%d\n", watchme, check_happy(watchme)); 1266 1267 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 1268 FORKEE_ASSERT(raise(sigval) == 0); 1269 1270 DPRINTF("Before exiting of the child process\n"); 1271 _exit(exitval); 1272 } 1273 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 1274 1275 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1276 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1277 1278 validate_status_stopped(status, sigval); 1279 1280 DPRINTF("Call GETDBREGS for the child process (r1)\n"); 1281 SYSCALL_REQUIRE(ptrace(PT_GETDBREGS, child, &r1, 0) != -1); 1282 1283 DPRINTF("State of the debug registers (r1):\n"); 1284 for (i = 0; i < __arraycount(r1.dr); i++) 1285 DPRINTF("r1[%zu]=%" PRIxREGISTER "\n", i, r1.dr[i]); 1286 1287 r1.dr[1] = (long)(intptr_t)check_happy; 1288 DPRINTF("Set DR1 (r1.dr[1]) to new value %" PRIxREGISTER "\n", 1289 r1.dr[1]); 1290 1291 r1.dr[7] = dr7.raw; 1292 DPRINTF("Set DR7 (r1.dr[7]) to new value %" PRIxREGISTER "\n", 1293 r1.dr[7]); 1294 1295 DPRINTF("New state of the debug registers (r1):\n"); 1296 for (i = 0; i < __arraycount(r1.dr); i++) 1297 DPRINTF("r1[%zu]=%" PRIxREGISTER "\n", i, r1.dr[i]); 1298 1299 DPRINTF("Call SETDBREGS for the child process (r1)\n"); 1300 SYSCALL_REQUIRE(ptrace(PT_SETDBREGS, child, &r1, 0) != -1); 1301 1302 DPRINTF("Call CONTINUE for the child process\n"); 1303 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 1304 1305 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1306 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1307 1308 validate_status_stopped(status, SIGTRAP); 1309 1310 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 1311 SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 1312 1313 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 1314 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 1315 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 1316 info.psi_siginfo.si_errno); 1317 1318 DPRINTF("Before checking siginfo_t\n"); 1319 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); 1320 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_DBREG); 1321 1322 DPRINTF("Remove code trap from check_happy=%p\n", check_happy); 1323 dr7.bits.global_dr1_breakpoint = 0; 1324 r1.dr[7] = dr7.raw; 1325 DPRINTF("Set DR7 (r1.dr[7]) to new value %" PRIxREGISTER "\n", 1326 r1.dr[7]); 1327 1328 DPRINTF("Call SETDBREGS for the child process (r1)\n"); 1329 SYSCALL_REQUIRE(ptrace(PT_SETDBREGS, child, &r1, 0) != -1); 1330 1331 DPRINTF("Call CONTINUE for the child process\n"); 1332 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 1333 1334 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1335 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1336 1337 validate_status_stopped(status, sigval); 1338 1339 DPRINTF("Before resuming the child process where it left off and " 1340 "without signal to be sent\n"); 1341 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 1342 1343 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1344 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1345 1346 validate_status_exited(status, exitval); 1347 1348 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1349 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 1350 } 1351 #endif 1352 1353 #if defined(HAVE_DBREGS) 1354 ATF_TC(dbregs_dr2_trap_code); 1355 ATF_TC_HEAD(dbregs_dr2_trap_code, tc) 1356 { 1357 atf_tc_set_md_var(tc, "descr", 1358 "Verify that setting trap with DR2 triggers SIGTRAP " 1359 "(break on code execution trap)"); 1360 } 1361 1362 ATF_TC_BODY(dbregs_dr2_trap_code, tc) 1363 { 1364 const int exitval = 5; 1365 const int sigval = SIGSTOP; 1366 pid_t child, wpid; 1367 #if defined(TWAIT_HAVE_STATUS) 1368 int status; 1369 #endif 1370 struct dbreg r1; 1371 size_t i; 1372 volatile int watchme = 1; 1373 union u dr7; 1374 1375 struct ptrace_siginfo info; 1376 memset(&info, 0, sizeof(info)); 1377 1378 if (!can_we_set_dbregs()) { 1379 atf_tc_skip("Either run this test as root or set sysctl(3) " 1380 "security.models.extensions.user_set_dbregs to 1"); 1381 } 1382 1383 dr7.raw = 0; 1384 dr7.bits.global_dr2_breakpoint = 1; 1385 dr7.bits.condition_dr2 = 0; /* 0b00 -- break on code execution */ 1386 dr7.bits.len_dr2 = 0; /* 0b00 -- 1 byte */ 1387 1388 DPRINTF("Before forking process PID=%d\n", getpid()); 1389 SYSCALL_REQUIRE((child = fork()) != -1); 1390 if (child == 0) { 1391 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 1392 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 1393 1394 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 1395 FORKEE_ASSERT(raise(sigval) == 0); 1396 1397 printf("check_happy(%d)=%d\n", watchme, check_happy(watchme)); 1398 1399 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 1400 FORKEE_ASSERT(raise(sigval) == 0); 1401 1402 DPRINTF("Before exiting of the child process\n"); 1403 _exit(exitval); 1404 } 1405 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 1406 1407 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1408 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1409 1410 validate_status_stopped(status, sigval); 1411 1412 DPRINTF("Call GETDBREGS for the child process (r1)\n"); 1413 SYSCALL_REQUIRE(ptrace(PT_GETDBREGS, child, &r1, 0) != -1); 1414 1415 DPRINTF("State of the debug registers (r1):\n"); 1416 for (i = 0; i < __arraycount(r1.dr); i++) 1417 DPRINTF("r1[%zu]=%" PRIxREGISTER "\n", i, r1.dr[i]); 1418 1419 r1.dr[2] = (long)(intptr_t)check_happy; 1420 DPRINTF("Set DR2 (r1.dr[2]) to new value %" PRIxREGISTER "\n", 1421 r1.dr[2]); 1422 1423 r1.dr[7] = dr7.raw; 1424 DPRINTF("Set DR7 (r1.dr[7]) to new value %" PRIxREGISTER "\n", 1425 r1.dr[7]); 1426 1427 DPRINTF("New state of the debug registers (r1):\n"); 1428 for (i = 0; i < __arraycount(r1.dr); i++) 1429 DPRINTF("r1[%zu]=%" PRIxREGISTER "\n", i, r1.dr[i]); 1430 1431 DPRINTF("Call SETDBREGS for the child process (r1)\n"); 1432 SYSCALL_REQUIRE(ptrace(PT_SETDBREGS, child, &r1, 0) != -1); 1433 1434 DPRINTF("Call CONTINUE for the child process\n"); 1435 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 1436 1437 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1438 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1439 1440 validate_status_stopped(status, SIGTRAP); 1441 1442 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 1443 SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 1444 1445 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 1446 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 1447 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 1448 info.psi_siginfo.si_errno); 1449 1450 DPRINTF("Before checking siginfo_t\n"); 1451 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); 1452 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_DBREG); 1453 1454 DPRINTF("Remove code trap from check_happy=%p\n", check_happy); 1455 dr7.bits.global_dr2_breakpoint = 0; 1456 r1.dr[7] = dr7.raw; 1457 DPRINTF("Set DR7 (r1.dr[7]) to new value %" PRIxREGISTER "\n", 1458 r1.dr[7]); 1459 1460 DPRINTF("Call SETDBREGS for the child process (r1)\n"); 1461 SYSCALL_REQUIRE(ptrace(PT_SETDBREGS, child, &r1, 0) != -1); 1462 1463 DPRINTF("Call CONTINUE for the child process\n"); 1464 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 1465 1466 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1467 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1468 1469 validate_status_stopped(status, sigval); 1470 1471 DPRINTF("Before resuming the child process where it left off and " 1472 "without signal to be sent\n"); 1473 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 1474 1475 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1476 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1477 1478 validate_status_exited(status, exitval); 1479 1480 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1481 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 1482 } 1483 #endif 1484 1485 #if defined(HAVE_DBREGS) 1486 ATF_TC(dbregs_dr3_trap_code); 1487 ATF_TC_HEAD(dbregs_dr3_trap_code, tc) 1488 { 1489 atf_tc_set_md_var(tc, "descr", 1490 "Verify that setting trap with DR3 triggers SIGTRAP " 1491 "(break on code execution trap)"); 1492 } 1493 1494 ATF_TC_BODY(dbregs_dr3_trap_code, tc) 1495 { 1496 const int exitval = 5; 1497 const int sigval = SIGSTOP; 1498 pid_t child, wpid; 1499 #if defined(TWAIT_HAVE_STATUS) 1500 int status; 1501 #endif 1502 struct dbreg r1; 1503 size_t i; 1504 volatile int watchme = 1; 1505 union u dr7; 1506 1507 struct ptrace_siginfo info; 1508 memset(&info, 0, sizeof(info)); 1509 1510 if (!can_we_set_dbregs()) { 1511 atf_tc_skip("Either run this test as root or set sysctl(3) " 1512 "security.models.extensions.user_set_dbregs to 1"); 1513 } 1514 1515 dr7.raw = 0; 1516 dr7.bits.global_dr3_breakpoint = 1; 1517 dr7.bits.condition_dr3 = 0; /* 0b00 -- break on code execution */ 1518 dr7.bits.len_dr3 = 0; /* 0b00 -- 1 byte */ 1519 1520 DPRINTF("Before forking process PID=%d\n", getpid()); 1521 SYSCALL_REQUIRE((child = fork()) != -1); 1522 if (child == 0) { 1523 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 1524 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 1525 1526 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 1527 FORKEE_ASSERT(raise(sigval) == 0); 1528 1529 printf("check_happy(%d)=%d\n", watchme, check_happy(watchme)); 1530 1531 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 1532 FORKEE_ASSERT(raise(sigval) == 0); 1533 1534 DPRINTF("Before exiting of the child process\n"); 1535 _exit(exitval); 1536 } 1537 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 1538 1539 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1540 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1541 1542 validate_status_stopped(status, sigval); 1543 1544 DPRINTF("Call GETDBREGS for the child process (r1)\n"); 1545 SYSCALL_REQUIRE(ptrace(PT_GETDBREGS, child, &r1, 0) != -1); 1546 1547 DPRINTF("State of the debug registers (r1):\n"); 1548 for (i = 0; i < __arraycount(r1.dr); i++) 1549 DPRINTF("r1[%zu]=%" PRIxREGISTER "\n", i, r1.dr[i]); 1550 1551 r1.dr[3] = (long)(intptr_t)check_happy; 1552 DPRINTF("Set DR3 (r1.dr[3]) to new value %" PRIxREGISTER "\n", 1553 r1.dr[3]); 1554 1555 r1.dr[7] = dr7.raw; 1556 DPRINTF("Set DR7 (r1.dr[7]) to new value %" PRIxREGISTER "\n", 1557 r1.dr[7]); 1558 1559 DPRINTF("New state of the debug registers (r1):\n"); 1560 for (i = 0; i < __arraycount(r1.dr); i++) 1561 DPRINTF("r1[%zu]=%" PRIxREGISTER "\n", i, r1.dr[i]); 1562 1563 DPRINTF("Call SETDBREGS for the child process (r1)\n"); 1564 SYSCALL_REQUIRE(ptrace(PT_SETDBREGS, child, &r1, 0) != -1); 1565 1566 DPRINTF("Call CONTINUE for the child process\n"); 1567 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 1568 1569 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1570 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1571 1572 validate_status_stopped(status, SIGTRAP); 1573 1574 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 1575 SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 1576 1577 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 1578 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 1579 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 1580 info.psi_siginfo.si_errno); 1581 1582 DPRINTF("Before checking siginfo_t\n"); 1583 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); 1584 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_DBREG); 1585 1586 DPRINTF("Remove code trap from check_happy=%p\n", check_happy); 1587 dr7.bits.global_dr3_breakpoint = 0; 1588 r1.dr[7] = dr7.raw; 1589 DPRINTF("Set DR7 (r1.dr[7]) to new value %" PRIxREGISTER "\n", 1590 r1.dr[7]); 1591 1592 DPRINTF("Call SETDBREGS for the child process (r1)\n"); 1593 SYSCALL_REQUIRE(ptrace(PT_SETDBREGS, child, &r1, 0) != -1); 1594 1595 DPRINTF("Call CONTINUE for the child process\n"); 1596 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 1597 1598 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1599 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1600 1601 validate_status_stopped(status, sigval); 1602 1603 DPRINTF("Before resuming the child process where it left off and " 1604 "without signal to be sent\n"); 1605 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 1606 1607 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1608 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1609 1610 validate_status_exited(status, exitval); 1611 1612 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1613 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 1614 } 1615 #endif 1616 1617 volatile lwpid_t x86_the_lwp_id = 0; 1618 1619 static void __used 1620 x86_lwp_main_func(void *arg) 1621 { 1622 x86_the_lwp_id = _lwp_self(); 1623 _lwp_exit(); 1624 } 1625 1626 static void 1627 dbregs_dont_inherit_lwp(int reg) 1628 { 1629 const int exitval = 5; 1630 const int sigval = SIGSTOP; 1631 pid_t child, wpid; 1632 #if defined(TWAIT_HAVE_STATUS) 1633 int status; 1634 #endif 1635 ptrace_state_t state; 1636 const int slen = sizeof(state); 1637 ptrace_event_t event; 1638 const int elen = sizeof(event); 1639 ucontext_t uc; 1640 lwpid_t lid; 1641 static const size_t ssize = 16*1024; 1642 void *stack; 1643 size_t i; 1644 struct dbreg r1; 1645 struct dbreg r2; 1646 1647 if (!can_we_set_dbregs()) { 1648 atf_tc_skip("Either run this test as root or set sysctl(3) " 1649 "security.models.extensions.user_set_dbregs to 1"); 1650 } 1651 1652 DPRINTF("Before forking process PID=%d\n", getpid()); 1653 SYSCALL_REQUIRE((child = fork()) != -1); 1654 if (child == 0) { 1655 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 1656 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 1657 1658 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 1659 FORKEE_ASSERT(raise(sigval) == 0); 1660 1661 DPRINTF("Before allocating memory for stack in child\n"); 1662 FORKEE_ASSERT((stack = malloc(ssize)) != NULL); 1663 1664 DPRINTF("Before making context for new lwp in child\n"); 1665 _lwp_makecontext(&uc, x86_lwp_main_func, NULL, NULL, stack, 1666 ssize); 1667 1668 DPRINTF("Before creating new in child\n"); 1669 FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0); 1670 1671 DPRINTF("Before waiting for lwp %d to exit\n", lid); 1672 FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0); 1673 1674 DPRINTF("Before verifying that reported %d and running lid %d " 1675 "are the same\n", lid, x86_the_lwp_id); 1676 FORKEE_ASSERT_EQ(lid, x86_the_lwp_id); 1677 1678 DPRINTF("Before exiting of the child process\n"); 1679 _exit(exitval); 1680 } 1681 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 1682 1683 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1684 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1685 1686 validate_status_stopped(status, sigval); 1687 1688 DPRINTF("Set empty EVENT_MASK for the child %d\n", child); 1689 event.pe_set_event = PTRACE_LWP_CREATE; 1690 SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); 1691 1692 DPRINTF("Call GETDBREGS for the child process (r1)\n"); 1693 SYSCALL_REQUIRE(ptrace(PT_GETDBREGS, child, &r1, 0) != -1); 1694 1695 DPRINTF("State of the debug registers (r1):\n"); 1696 for (i = 0; i < __arraycount(r1.dr); i++) 1697 DPRINTF("r1[%zu]=%" PRIxREGISTER "\n", i, r1.dr[i]); 1698 1699 r1.dr[reg] = (long)(intptr_t)check_happy; 1700 DPRINTF("Set DR%d (r1.dr[%d]) to new value %" PRIxREGISTER "\n", 1701 reg, reg, r1.dr[0]); 1702 1703 DPRINTF("New state of the debug registers (r1):\n"); 1704 for (i = 0; i < __arraycount(r1.dr); i++) 1705 DPRINTF("r1[%zu]=%" PRIxREGISTER "\n", i, r1.dr[i]); 1706 1707 DPRINTF("Call SETDBREGS for the child process (r1)\n"); 1708 SYSCALL_REQUIRE(ptrace(PT_SETDBREGS, child, &r1, 0) != -1); 1709 1710 DPRINTF("Before resuming the child process where it left off and " 1711 "without signal to be sent\n"); 1712 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 1713 1714 DPRINTF("Before calling %s() for the child - expected stopped " 1715 "SIGTRAP\n", TWAIT_FNAME); 1716 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1717 1718 validate_status_stopped(status, SIGTRAP); 1719 1720 SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 1721 1722 ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_LWP_CREATE); 1723 1724 lid = state.pe_lwp; 1725 DPRINTF("Reported PTRACE_LWP_CREATE event with lid %d\n", lid); 1726 1727 DPRINTF("Call GETDBREGS for the child process new lwp (r2)\n"); 1728 SYSCALL_REQUIRE(ptrace(PT_GETDBREGS, child, &r2, lid) != -1); 1729 1730 DPRINTF("State of the debug registers (r2):\n"); 1731 for (i = 0; i < __arraycount(r2.dr); i++) 1732 DPRINTF("r2[%zu]=%" PRIxREGISTER "\n", i, r2.dr[i]); 1733 1734 DPRINTF("Assert that (r1) and (r2) are not the same\n"); 1735 ATF_REQUIRE(memcmp(&r1, &r2, sizeof(r1)) != 0); 1736 1737 DPRINTF("Before resuming the child process where it left off and " 1738 "without signal to be sent\n"); 1739 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 1740 1741 DPRINTF("Before calling %s() for the child - expected exited\n", 1742 TWAIT_FNAME); 1743 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1744 1745 validate_status_exited(status, exitval); 1746 1747 DPRINTF("Before calling %s() for the child - expected no process\n", 1748 TWAIT_FNAME); 1749 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 1750 } 1751 1752 ATF_TC(dbregs_dr0_dont_inherit_lwp); 1753 ATF_TC_HEAD(dbregs_dr0_dont_inherit_lwp, tc) 1754 { 1755 atf_tc_set_md_var(tc, "descr", 1756 "Verify that 1 LWP creation is intercepted by ptrace(2) with " 1757 "EVENT_MASK set to PTRACE_LWP_CREATE and Debug Register 0 from " 1758 "the forker thread is not inherited"); 1759 } 1760 1761 ATF_TC_BODY(dbregs_dr0_dont_inherit_lwp, tc) 1762 { 1763 dbregs_dont_inherit_lwp(0); 1764 } 1765 1766 ATF_TC(dbregs_dr1_dont_inherit_lwp); 1767 ATF_TC_HEAD(dbregs_dr1_dont_inherit_lwp, tc) 1768 { 1769 atf_tc_set_md_var(tc, "descr", 1770 "Verify that 1 LWP creation is intercepted by ptrace(2) with " 1771 "EVENT_MASK set to PTRACE_LWP_CREATE and Debug Register 1 from " 1772 "the forker thread is not inherited"); 1773 } 1774 1775 ATF_TC_BODY(dbregs_dr1_dont_inherit_lwp, tc) 1776 { 1777 dbregs_dont_inherit_lwp(1); 1778 } 1779 1780 ATF_TC(dbregs_dr2_dont_inherit_lwp); 1781 ATF_TC_HEAD(dbregs_dr2_dont_inherit_lwp, tc) 1782 { 1783 atf_tc_set_md_var(tc, "descr", 1784 "Verify that 1 LWP creation is intercepted by ptrace(2) with " 1785 "EVENT_MASK set to PTRACE_LWP_CREATE and Debug Register 2 from " 1786 "the forker thread is not inherited"); 1787 } 1788 1789 ATF_TC_BODY(dbregs_dr2_dont_inherit_lwp, tc) 1790 { 1791 dbregs_dont_inherit_lwp(2); 1792 } 1793 1794 ATF_TC(dbregs_dr3_dont_inherit_lwp); 1795 ATF_TC_HEAD(dbregs_dr3_dont_inherit_lwp, tc) 1796 { 1797 atf_tc_set_md_var(tc, "descr", 1798 "Verify that 1 LWP creation is intercepted by ptrace(2) with " 1799 "EVENT_MASK set to PTRACE_LWP_CREATE and Debug Register 3 from " 1800 "the forker thread is not inherited"); 1801 } 1802 1803 ATF_TC_BODY(dbregs_dr3_dont_inherit_lwp, tc) 1804 { 1805 dbregs_dont_inherit_lwp(3); 1806 } 1807 1808 static void 1809 dbregs_dont_inherit_execve(int reg) 1810 { 1811 const int sigval = SIGTRAP; 1812 pid_t child, wpid; 1813 #if defined(TWAIT_HAVE_STATUS) 1814 int status; 1815 #endif 1816 size_t i; 1817 struct dbreg r1; 1818 struct dbreg r2; 1819 1820 struct ptrace_siginfo info; 1821 memset(&info, 0, sizeof(info)); 1822 1823 if (!can_we_set_dbregs()) { 1824 atf_tc_skip("Either run this test as root or set sysctl(3) " 1825 "security.models.extensions.user_set_dbregs to 1"); 1826 } 1827 1828 DPRINTF("Before forking process PID=%d\n", getpid()); 1829 SYSCALL_REQUIRE((child = fork()) != -1); 1830 if (child == 0) { 1831 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 1832 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 1833 1834 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 1835 FORKEE_ASSERT(raise(sigval) == 0); 1836 1837 DPRINTF("Before calling execve(2) from child\n"); 1838 execlp("/bin/echo", "/bin/echo", NULL); 1839 1840 FORKEE_ASSERT(0 && "Not reached"); 1841 } 1842 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 1843 1844 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1845 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1846 1847 validate_status_stopped(status, sigval); 1848 1849 DPRINTF("Call GETDBREGS for the child process (r1)\n"); 1850 SYSCALL_REQUIRE(ptrace(PT_GETDBREGS, child, &r1, 0) != -1); 1851 1852 DPRINTF("State of the debug registers (r1):\n"); 1853 for (i = 0; i < __arraycount(r1.dr); i++) 1854 DPRINTF("r1[%zu]=%" PRIxREGISTER "\n", i, r1.dr[i]); 1855 1856 r1.dr[reg] = (long)(intptr_t)check_happy; 1857 DPRINTF("Set DR%d (r1.dr[%d]) to new value %" PRIxREGISTER "\n", 1858 reg, reg, r1.dr[reg]); 1859 1860 DPRINTF("New state of the debug registers (r1):\n"); 1861 for (i = 0; i < __arraycount(r1.dr); i++) 1862 DPRINTF("r1[%zu]=%" PRIxREGISTER "\n", i, r1.dr[i]); 1863 1864 DPRINTF("Call SETDBREGS for the child process (r1)\n"); 1865 SYSCALL_REQUIRE(ptrace(PT_SETDBREGS, child, &r1, 0) != -1); 1866 1867 DPRINTF("Before resuming the child process where it left off and " 1868 "without signal to be sent\n"); 1869 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 1870 1871 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1872 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1873 1874 validate_status_stopped(status, sigval); 1875 1876 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 1877 SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 1878 1879 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 1880 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 1881 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 1882 info.psi_siginfo.si_errno); 1883 1884 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 1885 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_EXEC); 1886 1887 DPRINTF("Call GETDBREGS for the child process after execve(2)\n"); 1888 SYSCALL_REQUIRE(ptrace(PT_GETDBREGS, child, &r2, 0) != -1); 1889 1890 DPRINTF("State of the debug registers (r2):\n"); 1891 for (i = 0; i < __arraycount(r2.dr); i++) 1892 DPRINTF("r2[%zu]=%" PRIxREGISTER "\n", i, r2.dr[i]); 1893 1894 DPRINTF("Assert that (r1) and (r2) are not the same\n"); 1895 ATF_REQUIRE(memcmp(&r1, &r2, sizeof(r1)) != 0); 1896 1897 DPRINTF("Before resuming the child process where it left off and " 1898 "without signal to be sent\n"); 1899 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 1900 1901 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1902 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1903 1904 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1905 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 1906 } 1907 1908 ATF_TC(dbregs_dr0_dont_inherit_execve); 1909 ATF_TC_HEAD(dbregs_dr0_dont_inherit_execve, tc) 1910 { 1911 atf_tc_set_md_var(tc, "descr", 1912 "Verify that execve(2) is intercepted by tracer and Debug " 1913 "Register 0 is reset"); 1914 } 1915 1916 ATF_TC_BODY(dbregs_dr0_dont_inherit_execve, tc) 1917 { 1918 dbregs_dont_inherit_execve(0); 1919 } 1920 1921 ATF_TC(dbregs_dr1_dont_inherit_execve); 1922 ATF_TC_HEAD(dbregs_dr1_dont_inherit_execve, tc) 1923 { 1924 atf_tc_set_md_var(tc, "descr", 1925 "Verify that execve(2) is intercepted by tracer and Debug " 1926 "Register 1 is reset"); 1927 } 1928 1929 ATF_TC_BODY(dbregs_dr1_dont_inherit_execve, tc) 1930 { 1931 dbregs_dont_inherit_execve(1); 1932 } 1933 1934 ATF_TC(dbregs_dr2_dont_inherit_execve); 1935 ATF_TC_HEAD(dbregs_dr2_dont_inherit_execve, tc) 1936 { 1937 atf_tc_set_md_var(tc, "descr", 1938 "Verify that execve(2) is intercepted by tracer and Debug " 1939 "Register 2 is reset"); 1940 } 1941 1942 ATF_TC_BODY(dbregs_dr2_dont_inherit_execve, tc) 1943 { 1944 dbregs_dont_inherit_execve(2); 1945 } 1946 1947 ATF_TC(dbregs_dr3_dont_inherit_execve); 1948 ATF_TC_HEAD(dbregs_dr3_dont_inherit_execve, tc) 1949 { 1950 atf_tc_set_md_var(tc, "descr", 1951 "Verify that execve(2) is intercepted by tracer and Debug " 1952 "Register 3 is reset"); 1953 } 1954 1955 ATF_TC_BODY(dbregs_dr3_dont_inherit_execve, tc) 1956 { 1957 dbregs_dont_inherit_execve(3); 1958 } 1959 1960 /// ---------------------------------------------------------------------------- 1961 1962 ATF_TC(x86_cve_2018_8897); 1963 ATF_TC_HEAD(x86_cve_2018_8897, tc) 1964 { 1965 atf_tc_set_md_var(tc, "descr", 1966 "Verify mitigation for CVE-2018-8897 (POP SS debug exception)"); 1967 } 1968 1969 #define X86_CVE_2018_8897_PAGE 0x5000 /* page addressable by 32-bit registers */ 1970 1971 static void 1972 x86_cve_2018_8897_trigger(void) 1973 { 1974 /* 1975 * A function to trigger the POP SS (CVE-2018-8897) vulnerability 1976 * 1977 * ifdef __x86_64__ 1978 * 1979 * We need to switch to 32-bit mode execution on 64-bit kernel. 1980 * This is achieved with far jump instruction and GDT descriptor 1981 * set to 32-bit CS selector. The 32-bit CS selector is kernel 1982 * specific, in the NetBSD case registered as GUCODE32_SEL 1983 * that is equal to (14 (decimal) << 3) with GDT and user 1984 * privilege level (this makes it 0x73). 1985 * 1986 * In UNIX as(1) assembly x86_64 far jump is coded as ljmp. 1987 * amd64 ljmp requires an indirect address with cs:RIP. 1988 * 1989 * When we are running in 32-bit mode, it's similar to the 1990 * mode as if the binary had been launched in netbsd32. 1991 * 1992 * There are two versions of this exploit, one with RIP 1993 * relative code and the other with static addresses. 1994 * The first one is PIE code aware, the other no-PIE one. 1995 * 1996 * 1997 * After switching to the 32-bit mode we can move on to the remaining 1998 * part of the exploit. 1999 * 2000 * endif // __x86_64__ 2001 * 2002 * Set the stack pointer to the page we allocated earlier. Remember 2003 * that we put an SS selector exactly at this address, so we can pop. 2004 * 2005 * movl $0x5000,%esp 2006 * 2007 * Pop the SS selector off the stack. This reloads the SS selector, 2008 * which is fine. Remember that we set DR0 at address 0x5000, which 2009 * we are now reading. Therefore, on this instruction, the CPU will 2010 * raise a #DB exception. 2011 * 2012 * But the "pop %ss" instruction is special: it blocks exceptions 2013 * until the next instruction is executed. So the #DB that we just 2014 * raised is actually blocked. 2015 * 2016 * pop %ss 2017 * 2018 * We are still here, and didn't receive the #DB. After we execute 2019 * this instruction, the effect of "pop %ss" will disappear, and 2020 * we will receive the #DB for real. 2021 * 2022 * int $4 2023 * 2024 * Here the bug happens. We executed "int $4", so we entered the 2025 * kernel, with interrupts disabled. The #DB that was pending is 2026 * received. But, it is received immediately in kernel mode, and is 2027 * _NOT_ received when interrupts are enabled again. 2028 * 2029 * It means that, in the first instruction of the $4 handler, we 2030 * think we are safe with interrupts disabled. But we aren't, and 2031 * just got interrupted. 2032 * 2033 * The new interrupt handler doesn't handle this particular context: 2034 * we are entered in kernel mode, the previous context was kernel 2035 * mode too but it still had the user context loaded. 2036 * 2037 * We find ourselves not doing a 'swapgs'. At the end of the day, it 2038 * means that we call trap() with a curcpu() that is fully 2039 * controllable by userland. From then on, it is easy to escalate 2040 * privileges. 2041 * 2042 * With SVS it also means we don't switch CR3, so this results in a 2043 * triple fault, which this time cannot be turned to a privilege 2044 * escalation. 2045 */ 2046 2047 #if __x86_64__ 2048 #if __PIE__ 2049 void *csRIP; 2050 2051 csRIP = malloc(sizeof(int) + sizeof(short)); 2052 FORKEE_ASSERT(csRIP != NULL); 2053 2054 __asm__ __volatile__( 2055 " leal 24(%%eip), %%eax\n\t" 2056 " movq %0, %%rdx\n\t" 2057 " movl %%eax, (%%rdx)\n\t" 2058 " movw $0x73, 4(%%rdx)\n\t" 2059 " movq %1, %%rax\n\t" 2060 " ljmp *(%%rax)\n\t" 2061 " .code32\n\t" 2062 " movl $0x5000, %%esp\n\t" 2063 " pop %%ss\n\t" 2064 " int $4\n\t" 2065 " .code64\n\t" 2066 : "=m"(csRIP) 2067 : "m"(csRIP) 2068 : "%rax", "%rdx", "%rsp" 2069 ); 2070 #else /* !__PIE__ */ 2071 __asm__ __volatile__( 2072 " movq $farjmp32, %%rax\n\t" 2073 " ljmp *(%%rax)\n\t" 2074 "farjmp32:\n\t" 2075 " .long trigger32\n\t" 2076 " .word 0x73\n\t" 2077 " .code32\n\t" 2078 "trigger32:\n\t" 2079 " movl $0x5000, %%esp\n\t" 2080 " pop %%ss\n\t" 2081 " int $4\n\t" 2082 " .code64\n\t" 2083 : 2084 : 2085 : "%rax", "%rsp" 2086 ); 2087 #endif 2088 #elif __i386__ 2089 __asm__ __volatile__( 2090 "movl $0x5000, %%esp\n\t" 2091 "pop %%ss\n\t" 2092 "int $4\n\t" 2093 : 2094 : 2095 : "%esp" 2096 ); 2097 #endif 2098 } 2099 2100 ATF_TC_BODY(x86_cve_2018_8897, tc) 2101 { 2102 const int sigval = SIGSTOP; 2103 pid_t child, wpid; 2104 #if defined(TWAIT_HAVE_STATUS) 2105 int status; 2106 #endif 2107 char *trap_page; 2108 struct dbreg db; 2109 2110 2111 if (!can_we_set_dbregs()) { 2112 atf_tc_skip("Either run this test as root or set sysctl(3) " 2113 "security.models.extensions.user_set_dbregs to 1"); 2114 } 2115 2116 DPRINTF("Before forking process PID=%d\n", getpid()); 2117 SYSCALL_REQUIRE((child = fork()) != -1); 2118 if (child == 0) { 2119 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 2120 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 2121 2122 trap_page = mmap((void *)X86_CVE_2018_8897_PAGE, 2123 sysconf(_SC_PAGESIZE), PROT_READ|PROT_WRITE, 2124 MAP_FIXED|MAP_ANON|MAP_PRIVATE, -1, 0); 2125 2126 /* trigger page fault */ 2127 memset(trap_page, 0, sysconf(_SC_PAGESIZE)); 2128 2129 // kernel GDT 2130 #if __x86_64__ 2131 /* SS selector (descriptor 9 (0x4f >> 3)) */ 2132 *trap_page = 0x4f; 2133 #elif __i386__ 2134 /* SS selector (descriptor 4 (0x23 >> 3)) */ 2135 *trap_page = 0x23; 2136 #endif 2137 2138 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 2139 FORKEE_ASSERT(raise(sigval) == 0); 2140 2141 x86_cve_2018_8897_trigger(); 2142 2143 /* NOTREACHED */ 2144 FORKEE_ASSERTX(0 && "This shall not be reached"); 2145 } 2146 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 2147 2148 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 2149 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 2150 2151 validate_status_stopped(status, sigval); 2152 2153 DPRINTF("Call GETDBREGS for the child process\n"); 2154 SYSCALL_REQUIRE(ptrace(PT_GETDBREGS, child, &db, 0) != -1); 2155 2156 /* 2157 * Set up the dbregs. We put the 0x5000 address in DR0. 2158 * It means that, the first time we touch this, the CPU will trigger a 2159 * #DB exception. 2160 */ 2161 db.dr[0] = X86_CVE_2018_8897_PAGE; 2162 db.dr[7] = 0x30003; 2163 2164 DPRINTF("Call SETDBREGS for the child process\n"); 2165 SYSCALL_REQUIRE(ptrace(PT_SETDBREGS, child, &db, 0) != -1); 2166 2167 DPRINTF("Before resuming the child process where it left off and " 2168 "without signal to be sent\n"); 2169 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 2170 2171 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 2172 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 2173 2174 // In this test we receive SIGFPE, is this appropriate? 2175 // validate_status_stopped(status, SIGFPE); 2176 2177 DPRINTF("Kill the child process\n"); 2178 SYSCALL_REQUIRE(ptrace(PT_KILL, child, NULL, 0) != -1); 2179 2180 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 2181 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 2182 2183 validate_status_signaled(status, SIGKILL, 0); 2184 2185 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 2186 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 2187 } 2188 2189 /// ---------------------------------------------------------------------------- 2190 2191 #define ATF_TP_ADD_TCS_PTRACE_WAIT_X86() \ 2192 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_print); \ 2193 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_preserve_dr0); \ 2194 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_preserve_dr1); \ 2195 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_preserve_dr2); \ 2196 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_preserve_dr3); \ 2197 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_preserve_dr0_yield); \ 2198 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_preserve_dr1_yield); \ 2199 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_preserve_dr2_yield); \ 2200 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_preserve_dr3_yield); \ 2201 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_preserve_dr0_continued); \ 2202 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_preserve_dr1_continued); \ 2203 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_preserve_dr2_continued); \ 2204 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_preserve_dr3_continued); \ 2205 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr0_trap_variable_writeonly_byte); \ 2206 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr1_trap_variable_writeonly_byte); \ 2207 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr2_trap_variable_writeonly_byte); \ 2208 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr3_trap_variable_writeonly_byte); \ 2209 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr0_trap_variable_writeonly_2bytes); \ 2210 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr1_trap_variable_writeonly_2bytes); \ 2211 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr2_trap_variable_writeonly_2bytes); \ 2212 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr3_trap_variable_writeonly_2bytes); \ 2213 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr0_trap_variable_writeonly_4bytes); \ 2214 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr1_trap_variable_writeonly_4bytes); \ 2215 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr2_trap_variable_writeonly_4bytes); \ 2216 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr3_trap_variable_writeonly_4bytes); \ 2217 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr0_trap_variable_readwrite_write_byte); \ 2218 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr1_trap_variable_readwrite_write_byte); \ 2219 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr2_trap_variable_readwrite_write_byte); \ 2220 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr3_trap_variable_readwrite_write_byte); \ 2221 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr0_trap_variable_readwrite_write_2bytes); \ 2222 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr1_trap_variable_readwrite_write_2bytes); \ 2223 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr2_trap_variable_readwrite_write_2bytes); \ 2224 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr3_trap_variable_readwrite_write_2bytes); \ 2225 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr0_trap_variable_readwrite_write_4bytes); \ 2226 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr1_trap_variable_readwrite_write_4bytes); \ 2227 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr2_trap_variable_readwrite_write_4bytes); \ 2228 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr3_trap_variable_readwrite_write_4bytes); \ 2229 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr0_trap_variable_readwrite_read_byte); \ 2230 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr1_trap_variable_readwrite_read_byte); \ 2231 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr2_trap_variable_readwrite_read_byte); \ 2232 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr3_trap_variable_readwrite_read_byte); \ 2233 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr0_trap_variable_readwrite_read_2bytes); \ 2234 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr1_trap_variable_readwrite_read_2bytes); \ 2235 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr2_trap_variable_readwrite_read_2bytes); \ 2236 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr3_trap_variable_readwrite_read_2bytes); \ 2237 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr0_trap_variable_readwrite_read_4bytes); \ 2238 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr1_trap_variable_readwrite_read_4bytes); \ 2239 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr2_trap_variable_readwrite_read_4bytes); \ 2240 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr3_trap_variable_readwrite_read_4bytes); \ 2241 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr0_trap_code); \ 2242 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr1_trap_code); \ 2243 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr2_trap_code); \ 2244 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr3_trap_code); \ 2245 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr0_dont_inherit_lwp); \ 2246 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr1_dont_inherit_lwp); \ 2247 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr2_dont_inherit_lwp); \ 2248 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr3_dont_inherit_lwp); \ 2249 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr0_dont_inherit_execve); \ 2250 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr1_dont_inherit_execve); \ 2251 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr2_dont_inherit_execve); \ 2252 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr3_dont_inherit_execve); \ 2253 ATF_TP_ADD_TC_HAVE_DBREGS(tp, x86_cve_2018_8897); 2254 #else 2255 #define ATF_TP_ADD_TCS_PTRACE_WAIT_X86() 2256 #endif 2257