1 /* $NetBSD: t_ptrace_x86_wait.h,v 1.25 2020/04/24 03:25:20 thorpej Exp $ */ 2 3 /*- 4 * Copyright (c) 2016, 2017, 2018, 2019 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 break; 409 case 1: 410 dr7.bits.global_dr1_breakpoint = 1; 411 dr7.bits.condition_dr1 = cond; 412 dr7.bits.len_dr1 = len; 413 break; 414 case 2: 415 dr7.bits.global_dr2_breakpoint = 1; 416 dr7.bits.condition_dr2 = cond; 417 dr7.bits.len_dr2 = len; 418 break; 419 case 3: 420 dr7.bits.global_dr3_breakpoint = 1; 421 dr7.bits.condition_dr3 = cond; 422 dr7.bits.len_dr3 = len; 423 break; 424 } 425 426 DPRINTF("Before forking process PID=%d\n", getpid()); 427 SYSCALL_REQUIRE((child = fork()) != -1); 428 if (child == 0) { 429 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 430 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 431 432 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 433 FORKEE_ASSERT(raise(sigval) == 0); 434 435 if (write) 436 watchme = 1; 437 else 438 printf("watchme=%d\n", watchme); 439 440 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 441 FORKEE_ASSERT(raise(sigval) == 0); 442 443 DPRINTF("Before exiting of the child process\n"); 444 _exit(exitval); 445 } 446 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 447 448 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 449 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 450 451 validate_status_stopped(status, sigval); 452 453 DPRINTF("Call GETDBREGS for the child process (r1)\n"); 454 SYSCALL_REQUIRE(ptrace(PT_GETDBREGS, child, &r1, 0) != -1); 455 456 DPRINTF("State of the debug registers (r1):\n"); 457 for (i = 0; i < __arraycount(r1.dr); i++) 458 DPRINTF("r1[%zu]=%" PRIxREGISTER "\n", i, r1.dr[i]); 459 460 r1.dr[reg] = (long)(intptr_t)&watchme; 461 DPRINTF("Set DR%d (r1.dr[%d]) to new value %" PRIxREGISTER "\n", 462 reg, reg, r1.dr[reg]); 463 464 r1.dr[7] = dr7.raw; 465 DPRINTF("Set DR7 (r1.dr[7]) to new value %" PRIxREGISTER "\n", 466 r1.dr[7]); 467 468 DPRINTF("New state of the debug registers (r1):\n"); 469 for (i = 0; i < __arraycount(r1.dr); i++) 470 DPRINTF("r1[%zu]=%" PRIxREGISTER "\n", i, r1.dr[i]); 471 472 DPRINTF("Call SETDBREGS for the child process (r1)\n"); 473 SYSCALL_REQUIRE(ptrace(PT_SETDBREGS, child, &r1, 0) != -1); 474 475 DPRINTF("Call CONTINUE for the child process\n"); 476 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 477 478 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 479 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 480 481 validate_status_stopped(status, SIGTRAP); 482 483 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 484 SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 485 486 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 487 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 488 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 489 info.psi_siginfo.si_errno); 490 491 DPRINTF("Before checking siginfo_t\n"); 492 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); 493 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_DBREG); 494 495 DPRINTF("Call CONTINUE for the child process\n"); 496 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 497 498 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 499 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 500 501 validate_status_stopped(status, sigval); 502 503 DPRINTF("Before resuming the child process where it left off and " 504 "without signal to be sent\n"); 505 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 506 507 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 508 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 509 510 validate_status_exited(status, exitval); 511 512 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 513 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 514 } 515 516 ATF_TC(dbregs_dr0_trap_variable_writeonly_byte); 517 ATF_TC_HEAD(dbregs_dr0_trap_variable_writeonly_byte, tc) 518 { 519 atf_tc_set_md_var(tc, "descr", 520 "Verify that setting trap with DR0 triggers SIGTRAP " 521 "(break on data writes only and 1 byte mode)"); 522 } 523 524 ATF_TC_BODY(dbregs_dr0_trap_variable_writeonly_byte, tc) 525 { 526 /* 0b01 -- break on data write only */ 527 /* 0b00 -- 1 byte */ 528 529 dbregs_trap_variable(0, 1, 0, true); 530 } 531 532 ATF_TC(dbregs_dr1_trap_variable_writeonly_byte); 533 ATF_TC_HEAD(dbregs_dr1_trap_variable_writeonly_byte, tc) 534 { 535 atf_tc_set_md_var(tc, "descr", 536 "Verify that setting trap with DR1 triggers SIGTRAP " 537 "(break on data writes only and 1 byte mode)"); 538 } 539 540 ATF_TC_BODY(dbregs_dr1_trap_variable_writeonly_byte, tc) 541 { 542 /* 0b01 -- break on data write only */ 543 /* 0b00 -- 1 byte */ 544 545 dbregs_trap_variable(1, 1, 0, true); 546 } 547 548 ATF_TC(dbregs_dr2_trap_variable_writeonly_byte); 549 ATF_TC_HEAD(dbregs_dr2_trap_variable_writeonly_byte, tc) 550 { 551 atf_tc_set_md_var(tc, "descr", 552 "Verify that setting trap with DR2 triggers SIGTRAP " 553 "(break on data writes only and 1 byte mode)"); 554 } 555 556 ATF_TC_BODY(dbregs_dr2_trap_variable_writeonly_byte, tc) 557 { 558 /* 0b01 -- break on data write only */ 559 /* 0b00 -- 1 byte */ 560 561 dbregs_trap_variable(2, 1, 0, true); 562 } 563 564 ATF_TC(dbregs_dr3_trap_variable_writeonly_byte); 565 ATF_TC_HEAD(dbregs_dr3_trap_variable_writeonly_byte, tc) 566 { 567 atf_tc_set_md_var(tc, "descr", 568 "Verify that setting trap with DR3 triggers SIGTRAP " 569 "(break on data writes only and 1 byte mode)"); 570 } 571 572 ATF_TC_BODY(dbregs_dr3_trap_variable_writeonly_byte, tc) 573 { 574 /* 0b01 -- break on data write only */ 575 /* 0b00 -- 1 byte */ 576 577 dbregs_trap_variable(3, 1, 0, true); 578 } 579 580 ATF_TC(dbregs_dr0_trap_variable_writeonly_2bytes); 581 ATF_TC_HEAD(dbregs_dr0_trap_variable_writeonly_2bytes, tc) 582 { 583 atf_tc_set_md_var(tc, "descr", 584 "Verify that setting trap with DR0 triggers SIGTRAP " 585 "(break on data writes only and 2 bytes mode)"); 586 } 587 588 ATF_TC_BODY(dbregs_dr0_trap_variable_writeonly_2bytes, tc) 589 { 590 /* 0b01 -- break on data write only */ 591 /* 0b01 -- 2 bytes */ 592 593 dbregs_trap_variable(0, 1, 1, true); 594 } 595 596 ATF_TC(dbregs_dr1_trap_variable_writeonly_2bytes); 597 ATF_TC_HEAD(dbregs_dr1_trap_variable_writeonly_2bytes, tc) 598 { 599 atf_tc_set_md_var(tc, "descr", 600 "Verify that setting trap with DR1 triggers SIGTRAP " 601 "(break on data writes only and 2 bytes mode)"); 602 } 603 604 ATF_TC_BODY(dbregs_dr1_trap_variable_writeonly_2bytes, tc) 605 { 606 /* 0b01 -- break on data write only */ 607 /* 0b01 -- 2 bytes */ 608 609 dbregs_trap_variable(1, 1, 1, true); 610 } 611 612 ATF_TC(dbregs_dr2_trap_variable_writeonly_2bytes); 613 ATF_TC_HEAD(dbregs_dr2_trap_variable_writeonly_2bytes, tc) 614 { 615 atf_tc_set_md_var(tc, "descr", 616 "Verify that setting trap with DR2 triggers SIGTRAP " 617 "(break on data writes only and 2 bytes mode)"); 618 } 619 620 ATF_TC_BODY(dbregs_dr2_trap_variable_writeonly_2bytes, tc) 621 { 622 /* 0b01 -- break on data write only */ 623 /* 0b01 -- 2 bytes */ 624 625 dbregs_trap_variable(2, 1, 1, true); 626 } 627 628 ATF_TC(dbregs_dr3_trap_variable_writeonly_2bytes); 629 ATF_TC_HEAD(dbregs_dr3_trap_variable_writeonly_2bytes, tc) 630 { 631 atf_tc_set_md_var(tc, "descr", 632 "Verify that setting trap with DR3 triggers SIGTRAP " 633 "(break on data writes only and 2 bytes mode)"); 634 } 635 636 ATF_TC_BODY(dbregs_dr3_trap_variable_writeonly_2bytes, tc) 637 { 638 /* 0b01 -- break on data write only */ 639 /* 0b01 -- 2 bytes */ 640 641 dbregs_trap_variable(3, 1, 1, true); 642 } 643 644 ATF_TC(dbregs_dr0_trap_variable_writeonly_4bytes); 645 ATF_TC_HEAD(dbregs_dr0_trap_variable_writeonly_4bytes, tc) 646 { 647 atf_tc_set_md_var(tc, "descr", 648 "Verify that setting trap with DR0 triggers SIGTRAP " 649 "(break on data writes only and 4 bytes mode)"); 650 } 651 652 ATF_TC_BODY(dbregs_dr0_trap_variable_writeonly_4bytes, tc) 653 { 654 /* 0b01 -- break on data write only */ 655 /* 0b11 -- 4 bytes */ 656 657 dbregs_trap_variable(0, 1, 3, true); 658 } 659 660 ATF_TC(dbregs_dr1_trap_variable_writeonly_4bytes); 661 ATF_TC_HEAD(dbregs_dr1_trap_variable_writeonly_4bytes, tc) 662 { 663 atf_tc_set_md_var(tc, "descr", 664 "Verify that setting trap with DR1 triggers SIGTRAP " 665 "(break on data writes only and 4 bytes mode)"); 666 } 667 668 ATF_TC_BODY(dbregs_dr1_trap_variable_writeonly_4bytes, tc) 669 { 670 /* 0b01 -- break on data write only */ 671 /* 0b11 -- 4 bytes */ 672 673 dbregs_trap_variable(1, 1, 3, true); 674 } 675 676 ATF_TC(dbregs_dr2_trap_variable_writeonly_4bytes); 677 ATF_TC_HEAD(dbregs_dr2_trap_variable_writeonly_4bytes, tc) 678 { 679 atf_tc_set_md_var(tc, "descr", 680 "Verify that setting trap with DR2 triggers SIGTRAP " 681 "(break on data writes only and 4 bytes mode)"); 682 } 683 684 ATF_TC_BODY(dbregs_dr2_trap_variable_writeonly_4bytes, tc) 685 { 686 /* 0b01 -- break on data write only */ 687 /* 0b11 -- 4 bytes */ 688 689 dbregs_trap_variable(2, 1, 3, true); 690 } 691 692 ATF_TC(dbregs_dr3_trap_variable_writeonly_4bytes); 693 ATF_TC_HEAD(dbregs_dr3_trap_variable_writeonly_4bytes, tc) 694 { 695 atf_tc_set_md_var(tc, "descr", 696 "Verify that setting trap with DR3 triggers SIGTRAP " 697 "(break on data writes only and 4 bytes mode)"); 698 } 699 700 ATF_TC_BODY(dbregs_dr3_trap_variable_writeonly_4bytes, tc) 701 { 702 /* 0b01 -- break on data write only */ 703 /* 0b11 -- 4 bytes */ 704 705 dbregs_trap_variable(3, 1, 3, true); 706 } 707 708 ATF_TC(dbregs_dr0_trap_variable_readwrite_write_byte); 709 ATF_TC_HEAD(dbregs_dr0_trap_variable_readwrite_write_byte, tc) 710 { 711 atf_tc_set_md_var(tc, "descr", 712 "Verify that setting trap with DR0 triggers SIGTRAP " 713 "(break on data read/write trap in read 1 byte mode)"); 714 } 715 716 ATF_TC_BODY(dbregs_dr0_trap_variable_readwrite_write_byte, tc) 717 { 718 /* 0b11 -- break on data write&read */ 719 /* 0b00 -- 1 byte */ 720 721 dbregs_trap_variable(0, 3, 0, true); 722 } 723 724 ATF_TC(dbregs_dr1_trap_variable_readwrite_write_byte); 725 ATF_TC_HEAD(dbregs_dr1_trap_variable_readwrite_write_byte, tc) 726 { 727 atf_tc_set_md_var(tc, "descr", 728 "Verify that setting trap with DR1 triggers SIGTRAP " 729 "(break on data read/write trap in read 1 byte mode)"); 730 } 731 732 ATF_TC_BODY(dbregs_dr1_trap_variable_readwrite_write_byte, tc) 733 { 734 /* 0b11 -- break on data write&read */ 735 /* 0b00 -- 1 byte */ 736 737 dbregs_trap_variable(1, 3, 0, true); 738 } 739 740 ATF_TC(dbregs_dr2_trap_variable_readwrite_write_byte); 741 ATF_TC_HEAD(dbregs_dr2_trap_variable_readwrite_write_byte, tc) 742 { 743 atf_tc_set_md_var(tc, "descr", 744 "Verify that setting trap with DR2 triggers SIGTRAP " 745 "(break on data read/write trap in read 1 byte mode)"); 746 } 747 748 ATF_TC_BODY(dbregs_dr2_trap_variable_readwrite_write_byte, tc) 749 { 750 /* 0b11 -- break on data write&read */ 751 /* 0b00 -- 1 byte */ 752 753 dbregs_trap_variable(2, 3, 0, true); 754 } 755 756 ATF_TC(dbregs_dr3_trap_variable_readwrite_write_byte); 757 ATF_TC_HEAD(dbregs_dr3_trap_variable_readwrite_write_byte, tc) 758 { 759 atf_tc_set_md_var(tc, "descr", 760 "Verify that setting trap with DR3 triggers SIGTRAP " 761 "(break on data read/write trap in read 1 byte mode)"); 762 } 763 764 ATF_TC_BODY(dbregs_dr3_trap_variable_readwrite_write_byte, tc) 765 { 766 /* 0b11 -- break on data write&read */ 767 /* 0b00 -- 1 byte */ 768 769 dbregs_trap_variable(3, 3, 0, true); 770 } 771 772 ATF_TC(dbregs_dr0_trap_variable_readwrite_write_2bytes); 773 ATF_TC_HEAD(dbregs_dr0_trap_variable_readwrite_write_2bytes, tc) 774 { 775 atf_tc_set_md_var(tc, "descr", 776 "Verify that setting trap with DR0 triggers SIGTRAP " 777 "(break on data read/write trap in read 2 bytes mode)"); 778 } 779 780 ATF_TC_BODY(dbregs_dr0_trap_variable_readwrite_write_2bytes, tc) 781 { 782 /* 0b11 -- break on data write&read */ 783 /* 0b01 -- 2 bytes */ 784 785 dbregs_trap_variable(0, 3, 1, true); 786 } 787 788 ATF_TC(dbregs_dr1_trap_variable_readwrite_write_2bytes); 789 ATF_TC_HEAD(dbregs_dr1_trap_variable_readwrite_write_2bytes, tc) 790 { 791 atf_tc_set_md_var(tc, "descr", 792 "Verify that setting trap with DR1 triggers SIGTRAP " 793 "(break on data read/write trap in read 2 bytes mode)"); 794 } 795 796 ATF_TC_BODY(dbregs_dr1_trap_variable_readwrite_write_2bytes, tc) 797 { 798 /* 0b11 -- break on data write&read */ 799 /* 0b01 -- 2 bytes */ 800 801 dbregs_trap_variable(1, 3, 1, true); 802 } 803 804 ATF_TC(dbregs_dr2_trap_variable_readwrite_write_2bytes); 805 ATF_TC_HEAD(dbregs_dr2_trap_variable_readwrite_write_2bytes, tc) 806 { 807 atf_tc_set_md_var(tc, "descr", 808 "Verify that setting trap with DR2 triggers SIGTRAP " 809 "(break on data read/write trap in read 2 bytes mode)"); 810 } 811 812 ATF_TC_BODY(dbregs_dr2_trap_variable_readwrite_write_2bytes, tc) 813 { 814 /* 0b11 -- break on data write&read */ 815 /* 0b01 -- 2 bytes */ 816 817 dbregs_trap_variable(2, 3, 1, true); 818 } 819 820 ATF_TC(dbregs_dr3_trap_variable_readwrite_write_2bytes); 821 ATF_TC_HEAD(dbregs_dr3_trap_variable_readwrite_write_2bytes, tc) 822 { 823 atf_tc_set_md_var(tc, "descr", 824 "Verify that setting trap with DR3 triggers SIGTRAP " 825 "(break on data read/write trap in read 2 bytes mode)"); 826 } 827 828 ATF_TC_BODY(dbregs_dr3_trap_variable_readwrite_write_2bytes, tc) 829 { 830 /* 0b11 -- break on data write&read */ 831 /* 0b01 -- 2 bytes */ 832 833 dbregs_trap_variable(3, 3, 1, true); 834 } 835 836 ATF_TC(dbregs_dr0_trap_variable_readwrite_write_4bytes); 837 ATF_TC_HEAD(dbregs_dr0_trap_variable_readwrite_write_4bytes, tc) 838 { 839 atf_tc_set_md_var(tc, "descr", 840 "Verify that setting trap with DR0 triggers SIGTRAP " 841 "(break on data read/write trap in read 4 bytes mode)"); 842 } 843 844 ATF_TC_BODY(dbregs_dr0_trap_variable_readwrite_write_4bytes, tc) 845 { 846 /* 0b11 -- break on data write&read */ 847 /* 0b11 -- 4 bytes */ 848 849 dbregs_trap_variable(0, 3, 3, true); 850 } 851 852 ATF_TC(dbregs_dr1_trap_variable_readwrite_write_4bytes); 853 ATF_TC_HEAD(dbregs_dr1_trap_variable_readwrite_write_4bytes, tc) 854 { 855 atf_tc_set_md_var(tc, "descr", 856 "Verify that setting trap with DR1 triggers SIGTRAP " 857 "(break on data read/write trap in read 4 bytes mode)"); 858 } 859 860 ATF_TC_BODY(dbregs_dr1_trap_variable_readwrite_write_4bytes, tc) 861 { 862 /* 0b11 -- break on data write&read */ 863 /* 0b11 -- 4 bytes */ 864 865 dbregs_trap_variable(1, 3, 3, true); 866 } 867 868 ATF_TC(dbregs_dr2_trap_variable_readwrite_write_4bytes); 869 ATF_TC_HEAD(dbregs_dr2_trap_variable_readwrite_write_4bytes, tc) 870 { 871 atf_tc_set_md_var(tc, "descr", 872 "Verify that setting trap with DR2 triggers SIGTRAP " 873 "(break on data read/write trap in read 4 bytes mode)"); 874 } 875 876 ATF_TC_BODY(dbregs_dr2_trap_variable_readwrite_write_4bytes, tc) 877 { 878 /* 0b11 -- break on data write&read */ 879 /* 0b11 -- 4 bytes */ 880 881 dbregs_trap_variable(2, 3, 3, true); 882 } 883 884 ATF_TC(dbregs_dr3_trap_variable_readwrite_write_4bytes); 885 ATF_TC_HEAD(dbregs_dr3_trap_variable_readwrite_write_4bytes, tc) 886 { 887 atf_tc_set_md_var(tc, "descr", 888 "Verify that setting trap with DR3 triggers SIGTRAP " 889 "(break on data read/write trap in read 4 bytes mode)"); 890 } 891 892 ATF_TC_BODY(dbregs_dr3_trap_variable_readwrite_write_4bytes, tc) 893 { 894 /* 0b11 -- break on data write&read */ 895 /* 0b11 -- 4 bytes */ 896 897 dbregs_trap_variable(3, 3, 3, true); 898 } 899 900 ATF_TC(dbregs_dr0_trap_variable_readwrite_read_byte); 901 ATF_TC_HEAD(dbregs_dr0_trap_variable_readwrite_read_byte, tc) 902 { 903 atf_tc_set_md_var(tc, "descr", 904 "Verify that setting trap with DR0 triggers SIGTRAP " 905 "(break on data read/write trap in write 1 byte mode)"); 906 } 907 908 ATF_TC_BODY(dbregs_dr0_trap_variable_readwrite_read_byte, tc) 909 { 910 /* 0b11 -- break on data write&read */ 911 /* 0b00 -- 1 byte */ 912 913 dbregs_trap_variable(0, 3, 0, false); 914 } 915 916 ATF_TC(dbregs_dr1_trap_variable_readwrite_read_byte); 917 ATF_TC_HEAD(dbregs_dr1_trap_variable_readwrite_read_byte, tc) 918 { 919 atf_tc_set_md_var(tc, "descr", 920 "Verify that setting trap with DR1 triggers SIGTRAP " 921 "(break on data read/write trap in write 1 byte mode)"); 922 } 923 924 ATF_TC_BODY(dbregs_dr1_trap_variable_readwrite_read_byte, tc) 925 { 926 /* 0b11 -- break on data write&read */ 927 /* 0b00 -- 1 byte */ 928 929 dbregs_trap_variable(1, 3, 0, false); 930 } 931 932 ATF_TC(dbregs_dr2_trap_variable_readwrite_read_byte); 933 ATF_TC_HEAD(dbregs_dr2_trap_variable_readwrite_read_byte, tc) 934 { 935 atf_tc_set_md_var(tc, "descr", 936 "Verify that setting trap with DR2 triggers SIGTRAP " 937 "(break on data read/write trap in write 1 byte mode)"); 938 } 939 940 ATF_TC_BODY(dbregs_dr2_trap_variable_readwrite_read_byte, tc) 941 { 942 /* 0b11 -- break on data write&read */ 943 /* 0b00 -- 1 byte */ 944 945 dbregs_trap_variable(2, 3, 0, false); 946 } 947 948 ATF_TC(dbregs_dr3_trap_variable_readwrite_read_byte); 949 ATF_TC_HEAD(dbregs_dr3_trap_variable_readwrite_read_byte, tc) 950 { 951 atf_tc_set_md_var(tc, "descr", 952 "Verify that setting trap with DR3 triggers SIGTRAP " 953 "(break on data read/write trap in write 1 byte mode)"); 954 } 955 956 ATF_TC_BODY(dbregs_dr3_trap_variable_readwrite_read_byte, tc) 957 { 958 /* 0b11 -- break on data write&read */ 959 /* 0b00 -- 1 byte */ 960 961 dbregs_trap_variable(3, 3, 0, false); 962 } 963 964 ATF_TC(dbregs_dr0_trap_variable_readwrite_read_2bytes); 965 ATF_TC_HEAD(dbregs_dr0_trap_variable_readwrite_read_2bytes, tc) 966 { 967 atf_tc_set_md_var(tc, "descr", 968 "Verify that setting trap with DR0 triggers SIGTRAP " 969 "(break on data read/write trap in write 2 bytes mode)"); 970 } 971 972 ATF_TC_BODY(dbregs_dr0_trap_variable_readwrite_read_2bytes, tc) 973 { 974 /* 0b11 -- break on data write&read */ 975 /* 0b01 -- 2 bytes */ 976 977 dbregs_trap_variable(0, 3, 1, false); 978 } 979 980 ATF_TC(dbregs_dr1_trap_variable_readwrite_read_2bytes); 981 ATF_TC_HEAD(dbregs_dr1_trap_variable_readwrite_read_2bytes, tc) 982 { 983 atf_tc_set_md_var(tc, "descr", 984 "Verify that setting trap with DR1 triggers SIGTRAP " 985 "(break on data read/write trap in write 2 bytes mode)"); 986 } 987 988 ATF_TC_BODY(dbregs_dr1_trap_variable_readwrite_read_2bytes, tc) 989 { 990 /* 0b11 -- break on data write&read */ 991 /* 0b01 -- 2 bytes */ 992 993 dbregs_trap_variable(1, 3, 1, false); 994 } 995 996 ATF_TC(dbregs_dr2_trap_variable_readwrite_read_2bytes); 997 ATF_TC_HEAD(dbregs_dr2_trap_variable_readwrite_read_2bytes, tc) 998 { 999 atf_tc_set_md_var(tc, "descr", 1000 "Verify that setting trap with DR2 triggers SIGTRAP " 1001 "(break on data read/write trap in write 2 bytes mode)"); 1002 } 1003 1004 ATF_TC_BODY(dbregs_dr2_trap_variable_readwrite_read_2bytes, tc) 1005 { 1006 /* 0b11 -- break on data write&read */ 1007 /* 0b01 -- 2 bytes */ 1008 1009 dbregs_trap_variable(2, 3, 1, false); 1010 } 1011 1012 ATF_TC(dbregs_dr3_trap_variable_readwrite_read_2bytes); 1013 ATF_TC_HEAD(dbregs_dr3_trap_variable_readwrite_read_2bytes, tc) 1014 { 1015 atf_tc_set_md_var(tc, "descr", 1016 "Verify that setting trap with DR3 triggers SIGTRAP " 1017 "(break on data read/write trap in write 2 bytes mode)"); 1018 } 1019 1020 ATF_TC_BODY(dbregs_dr3_trap_variable_readwrite_read_2bytes, tc) 1021 { 1022 /* 0b11 -- break on data write&read */ 1023 /* 0b01 -- 2 bytes */ 1024 1025 dbregs_trap_variable(3, 3, 1, false); 1026 } 1027 1028 ATF_TC(dbregs_dr0_trap_variable_readwrite_read_4bytes); 1029 ATF_TC_HEAD(dbregs_dr0_trap_variable_readwrite_read_4bytes, tc) 1030 { 1031 atf_tc_set_md_var(tc, "descr", 1032 "Verify that setting trap with DR0 triggers SIGTRAP " 1033 "(break on data read/write trap in write 4 bytes mode)"); 1034 } 1035 1036 ATF_TC_BODY(dbregs_dr0_trap_variable_readwrite_read_4bytes, tc) 1037 { 1038 /* 0b11 -- break on data write&read */ 1039 /* 0b11 -- 4 bytes */ 1040 1041 dbregs_trap_variable(0, 3, 3, false); 1042 } 1043 1044 ATF_TC(dbregs_dr1_trap_variable_readwrite_read_4bytes); 1045 ATF_TC_HEAD(dbregs_dr1_trap_variable_readwrite_read_4bytes, tc) 1046 { 1047 atf_tc_set_md_var(tc, "descr", 1048 "Verify that setting trap with DR1 triggers SIGTRAP " 1049 "(break on data read/write trap in write 4 bytes mode)"); 1050 } 1051 1052 ATF_TC_BODY(dbregs_dr1_trap_variable_readwrite_read_4bytes, tc) 1053 { 1054 /* 0b11 -- break on data write&read */ 1055 /* 0b11 -- 4 bytes */ 1056 1057 dbregs_trap_variable(1, 3, 3, false); 1058 } 1059 1060 ATF_TC(dbregs_dr2_trap_variable_readwrite_read_4bytes); 1061 ATF_TC_HEAD(dbregs_dr2_trap_variable_readwrite_read_4bytes, tc) 1062 { 1063 atf_tc_set_md_var(tc, "descr", 1064 "Verify that setting trap with DR2 triggers SIGTRAP " 1065 "(break on data read/write trap in write 4 bytes mode)"); 1066 } 1067 1068 ATF_TC_BODY(dbregs_dr2_trap_variable_readwrite_read_4bytes, tc) 1069 { 1070 /* 0b11 -- break on data write&read */ 1071 /* 0b11 -- 4 bytes */ 1072 1073 dbregs_trap_variable(2, 3, 3, false); 1074 } 1075 1076 ATF_TC(dbregs_dr3_trap_variable_readwrite_read_4bytes); 1077 ATF_TC_HEAD(dbregs_dr3_trap_variable_readwrite_read_4bytes, tc) 1078 { 1079 atf_tc_set_md_var(tc, "descr", 1080 "Verify that setting trap with DR3 triggers SIGTRAP " 1081 "(break on data read/write trap in write 4 bytes mode)"); 1082 } 1083 1084 ATF_TC_BODY(dbregs_dr3_trap_variable_readwrite_read_4bytes, tc) 1085 { 1086 /* 0b11 -- break on data write&read */ 1087 /* 0b11 -- 4 bytes */ 1088 1089 dbregs_trap_variable(3, 3, 3, false); 1090 } 1091 1092 #if defined(HAVE_DBREGS) 1093 ATF_TC(dbregs_dr0_trap_code); 1094 ATF_TC_HEAD(dbregs_dr0_trap_code, tc) 1095 { 1096 atf_tc_set_md_var(tc, "descr", 1097 "Verify that setting trap with DR0 triggers SIGTRAP " 1098 "(break on code execution trap)"); 1099 } 1100 1101 ATF_TC_BODY(dbregs_dr0_trap_code, tc) 1102 { 1103 const int exitval = 5; 1104 const int sigval = SIGSTOP; 1105 pid_t child, wpid; 1106 #if defined(TWAIT_HAVE_STATUS) 1107 int status; 1108 #endif 1109 struct dbreg r1; 1110 size_t i; 1111 volatile int watchme = 1; 1112 union u dr7; 1113 1114 struct ptrace_siginfo info; 1115 memset(&info, 0, sizeof(info)); 1116 1117 if (!can_we_set_dbregs()) { 1118 atf_tc_skip("Either run this test as root or set sysctl(3) " 1119 "security.models.extensions.user_set_dbregs to 1"); 1120 } 1121 1122 dr7.raw = 0; 1123 dr7.bits.global_dr0_breakpoint = 1; 1124 dr7.bits.condition_dr0 = 0; /* 0b00 -- break on code execution */ 1125 dr7.bits.len_dr0 = 0; /* 0b00 -- 1 byte */ 1126 1127 DPRINTF("Before forking process PID=%d\n", getpid()); 1128 SYSCALL_REQUIRE((child = fork()) != -1); 1129 if (child == 0) { 1130 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 1131 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 1132 1133 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 1134 FORKEE_ASSERT(raise(sigval) == 0); 1135 1136 printf("check_happy(%d)=%d\n", watchme, check_happy(watchme)); 1137 1138 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 1139 FORKEE_ASSERT(raise(sigval) == 0); 1140 1141 DPRINTF("Before exiting of the child process\n"); 1142 _exit(exitval); 1143 } 1144 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 1145 1146 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1147 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1148 1149 validate_status_stopped(status, sigval); 1150 1151 DPRINTF("Call GETDBREGS for the child process (r1)\n"); 1152 SYSCALL_REQUIRE(ptrace(PT_GETDBREGS, child, &r1, 0) != -1); 1153 1154 DPRINTF("State of the debug registers (r1):\n"); 1155 for (i = 0; i < __arraycount(r1.dr); i++) 1156 DPRINTF("r1[%zu]=%" PRIxREGISTER "\n", i, r1.dr[i]); 1157 1158 r1.dr[0] = (long)(intptr_t)check_happy; 1159 DPRINTF("Set DR0 (r1.dr[0]) to new value %" PRIxREGISTER "\n", 1160 r1.dr[0]); 1161 1162 r1.dr[7] = dr7.raw; 1163 DPRINTF("Set DR7 (r1.dr[7]) to new value %" PRIxREGISTER "\n", 1164 r1.dr[7]); 1165 1166 DPRINTF("New state of the debug registers (r1):\n"); 1167 for (i = 0; i < __arraycount(r1.dr); i++) 1168 DPRINTF("r1[%zu]=%" PRIxREGISTER "\n", i, r1.dr[i]); 1169 1170 DPRINTF("Call SETDBREGS for the child process (r1)\n"); 1171 SYSCALL_REQUIRE(ptrace(PT_SETDBREGS, child, &r1, 0) != -1); 1172 1173 DPRINTF("Call CONTINUE for the child process\n"); 1174 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 1175 1176 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1177 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1178 1179 validate_status_stopped(status, SIGTRAP); 1180 1181 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 1182 SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 1183 1184 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 1185 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 1186 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 1187 info.psi_siginfo.si_errno); 1188 1189 DPRINTF("Before checking siginfo_t\n"); 1190 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); 1191 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_DBREG); 1192 1193 DPRINTF("Remove code trap from check_happy=%p\n", check_happy); 1194 dr7.bits.global_dr0_breakpoint = 0; 1195 r1.dr[7] = dr7.raw; 1196 DPRINTF("Set DR7 (r1.dr[7]) to new value %" PRIxREGISTER "\n", 1197 r1.dr[7]); 1198 1199 DPRINTF("Call SETDBREGS for the child process (r1)\n"); 1200 SYSCALL_REQUIRE(ptrace(PT_SETDBREGS, child, &r1, 0) != -1); 1201 1202 DPRINTF("Call CONTINUE for the child process\n"); 1203 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 1204 1205 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1206 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1207 1208 validate_status_stopped(status, sigval); 1209 1210 DPRINTF("Before resuming the child process where it left off and " 1211 "without signal to be sent\n"); 1212 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 1213 1214 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1215 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1216 1217 validate_status_exited(status, exitval); 1218 1219 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1220 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 1221 } 1222 #endif 1223 1224 #if defined(HAVE_DBREGS) 1225 ATF_TC(dbregs_dr1_trap_code); 1226 ATF_TC_HEAD(dbregs_dr1_trap_code, tc) 1227 { 1228 atf_tc_set_md_var(tc, "descr", 1229 "Verify that setting trap with DR1 triggers SIGTRAP " 1230 "(break on code execution trap)"); 1231 } 1232 1233 ATF_TC_BODY(dbregs_dr1_trap_code, tc) 1234 { 1235 const int exitval = 5; 1236 const int sigval = SIGSTOP; 1237 pid_t child, wpid; 1238 #if defined(TWAIT_HAVE_STATUS) 1239 int status; 1240 #endif 1241 struct dbreg r1; 1242 size_t i; 1243 volatile int watchme = 1; 1244 union u dr7; 1245 1246 struct ptrace_siginfo info; 1247 memset(&info, 0, sizeof(info)); 1248 1249 if (!can_we_set_dbregs()) { 1250 atf_tc_skip("Either run this test as root or set sysctl(3) " 1251 "security.models.extensions.user_set_dbregs to 1"); 1252 } 1253 1254 dr7.raw = 0; 1255 dr7.bits.global_dr1_breakpoint = 1; 1256 dr7.bits.condition_dr1 = 0; /* 0b00 -- break on code execution */ 1257 dr7.bits.len_dr1 = 0; /* 0b00 -- 1 byte */ 1258 1259 DPRINTF("Before forking process PID=%d\n", getpid()); 1260 SYSCALL_REQUIRE((child = fork()) != -1); 1261 if (child == 0) { 1262 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 1263 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 1264 1265 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 1266 FORKEE_ASSERT(raise(sigval) == 0); 1267 1268 printf("check_happy(%d)=%d\n", watchme, check_happy(watchme)); 1269 1270 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 1271 FORKEE_ASSERT(raise(sigval) == 0); 1272 1273 DPRINTF("Before exiting of the child process\n"); 1274 _exit(exitval); 1275 } 1276 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 1277 1278 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1279 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1280 1281 validate_status_stopped(status, sigval); 1282 1283 DPRINTF("Call GETDBREGS for the child process (r1)\n"); 1284 SYSCALL_REQUIRE(ptrace(PT_GETDBREGS, child, &r1, 0) != -1); 1285 1286 DPRINTF("State of the debug registers (r1):\n"); 1287 for (i = 0; i < __arraycount(r1.dr); i++) 1288 DPRINTF("r1[%zu]=%" PRIxREGISTER "\n", i, r1.dr[i]); 1289 1290 r1.dr[1] = (long)(intptr_t)check_happy; 1291 DPRINTF("Set DR1 (r1.dr[1]) to new value %" PRIxREGISTER "\n", 1292 r1.dr[1]); 1293 1294 r1.dr[7] = dr7.raw; 1295 DPRINTF("Set DR7 (r1.dr[7]) to new value %" PRIxREGISTER "\n", 1296 r1.dr[7]); 1297 1298 DPRINTF("New state of the debug registers (r1):\n"); 1299 for (i = 0; i < __arraycount(r1.dr); i++) 1300 DPRINTF("r1[%zu]=%" PRIxREGISTER "\n", i, r1.dr[i]); 1301 1302 DPRINTF("Call SETDBREGS for the child process (r1)\n"); 1303 SYSCALL_REQUIRE(ptrace(PT_SETDBREGS, child, &r1, 0) != -1); 1304 1305 DPRINTF("Call CONTINUE for the child process\n"); 1306 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 1307 1308 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1309 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1310 1311 validate_status_stopped(status, SIGTRAP); 1312 1313 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 1314 SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 1315 1316 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 1317 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 1318 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 1319 info.psi_siginfo.si_errno); 1320 1321 DPRINTF("Before checking siginfo_t\n"); 1322 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); 1323 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_DBREG); 1324 1325 DPRINTF("Remove code trap from check_happy=%p\n", check_happy); 1326 dr7.bits.global_dr1_breakpoint = 0; 1327 r1.dr[7] = dr7.raw; 1328 DPRINTF("Set DR7 (r1.dr[7]) to new value %" PRIxREGISTER "\n", 1329 r1.dr[7]); 1330 1331 DPRINTF("Call SETDBREGS for the child process (r1)\n"); 1332 SYSCALL_REQUIRE(ptrace(PT_SETDBREGS, child, &r1, 0) != -1); 1333 1334 DPRINTF("Call CONTINUE for the child process\n"); 1335 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 1336 1337 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1338 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1339 1340 validate_status_stopped(status, sigval); 1341 1342 DPRINTF("Before resuming the child process where it left off and " 1343 "without signal to be sent\n"); 1344 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 1345 1346 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1347 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1348 1349 validate_status_exited(status, exitval); 1350 1351 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1352 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 1353 } 1354 #endif 1355 1356 #if defined(HAVE_DBREGS) 1357 ATF_TC(dbregs_dr2_trap_code); 1358 ATF_TC_HEAD(dbregs_dr2_trap_code, tc) 1359 { 1360 atf_tc_set_md_var(tc, "descr", 1361 "Verify that setting trap with DR2 triggers SIGTRAP " 1362 "(break on code execution trap)"); 1363 } 1364 1365 ATF_TC_BODY(dbregs_dr2_trap_code, tc) 1366 { 1367 const int exitval = 5; 1368 const int sigval = SIGSTOP; 1369 pid_t child, wpid; 1370 #if defined(TWAIT_HAVE_STATUS) 1371 int status; 1372 #endif 1373 struct dbreg r1; 1374 size_t i; 1375 volatile int watchme = 1; 1376 union u dr7; 1377 1378 struct ptrace_siginfo info; 1379 memset(&info, 0, sizeof(info)); 1380 1381 if (!can_we_set_dbregs()) { 1382 atf_tc_skip("Either run this test as root or set sysctl(3) " 1383 "security.models.extensions.user_set_dbregs to 1"); 1384 } 1385 1386 dr7.raw = 0; 1387 dr7.bits.global_dr2_breakpoint = 1; 1388 dr7.bits.condition_dr2 = 0; /* 0b00 -- break on code execution */ 1389 dr7.bits.len_dr2 = 0; /* 0b00 -- 1 byte */ 1390 1391 DPRINTF("Before forking process PID=%d\n", getpid()); 1392 SYSCALL_REQUIRE((child = fork()) != -1); 1393 if (child == 0) { 1394 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 1395 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 1396 1397 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 1398 FORKEE_ASSERT(raise(sigval) == 0); 1399 1400 printf("check_happy(%d)=%d\n", watchme, check_happy(watchme)); 1401 1402 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 1403 FORKEE_ASSERT(raise(sigval) == 0); 1404 1405 DPRINTF("Before exiting of the child process\n"); 1406 _exit(exitval); 1407 } 1408 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 1409 1410 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1411 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1412 1413 validate_status_stopped(status, sigval); 1414 1415 DPRINTF("Call GETDBREGS for the child process (r1)\n"); 1416 SYSCALL_REQUIRE(ptrace(PT_GETDBREGS, child, &r1, 0) != -1); 1417 1418 DPRINTF("State of the debug registers (r1):\n"); 1419 for (i = 0; i < __arraycount(r1.dr); i++) 1420 DPRINTF("r1[%zu]=%" PRIxREGISTER "\n", i, r1.dr[i]); 1421 1422 r1.dr[2] = (long)(intptr_t)check_happy; 1423 DPRINTF("Set DR2 (r1.dr[2]) to new value %" PRIxREGISTER "\n", 1424 r1.dr[2]); 1425 1426 r1.dr[7] = dr7.raw; 1427 DPRINTF("Set DR7 (r1.dr[7]) to new value %" PRIxREGISTER "\n", 1428 r1.dr[7]); 1429 1430 DPRINTF("New state of the debug registers (r1):\n"); 1431 for (i = 0; i < __arraycount(r1.dr); i++) 1432 DPRINTF("r1[%zu]=%" PRIxREGISTER "\n", i, r1.dr[i]); 1433 1434 DPRINTF("Call SETDBREGS for the child process (r1)\n"); 1435 SYSCALL_REQUIRE(ptrace(PT_SETDBREGS, child, &r1, 0) != -1); 1436 1437 DPRINTF("Call CONTINUE for the child process\n"); 1438 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 1439 1440 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1441 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1442 1443 validate_status_stopped(status, SIGTRAP); 1444 1445 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 1446 SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 1447 1448 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 1449 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 1450 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 1451 info.psi_siginfo.si_errno); 1452 1453 DPRINTF("Before checking siginfo_t\n"); 1454 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); 1455 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_DBREG); 1456 1457 DPRINTF("Remove code trap from check_happy=%p\n", check_happy); 1458 dr7.bits.global_dr2_breakpoint = 0; 1459 r1.dr[7] = dr7.raw; 1460 DPRINTF("Set DR7 (r1.dr[7]) to new value %" PRIxREGISTER "\n", 1461 r1.dr[7]); 1462 1463 DPRINTF("Call SETDBREGS for the child process (r1)\n"); 1464 SYSCALL_REQUIRE(ptrace(PT_SETDBREGS, child, &r1, 0) != -1); 1465 1466 DPRINTF("Call CONTINUE for the child process\n"); 1467 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 1468 1469 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1470 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1471 1472 validate_status_stopped(status, sigval); 1473 1474 DPRINTF("Before resuming the child process where it left off and " 1475 "without signal to be sent\n"); 1476 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 1477 1478 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1479 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1480 1481 validate_status_exited(status, exitval); 1482 1483 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1484 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 1485 } 1486 #endif 1487 1488 #if defined(HAVE_DBREGS) 1489 ATF_TC(dbregs_dr3_trap_code); 1490 ATF_TC_HEAD(dbregs_dr3_trap_code, tc) 1491 { 1492 atf_tc_set_md_var(tc, "descr", 1493 "Verify that setting trap with DR3 triggers SIGTRAP " 1494 "(break on code execution trap)"); 1495 } 1496 1497 ATF_TC_BODY(dbregs_dr3_trap_code, tc) 1498 { 1499 const int exitval = 5; 1500 const int sigval = SIGSTOP; 1501 pid_t child, wpid; 1502 #if defined(TWAIT_HAVE_STATUS) 1503 int status; 1504 #endif 1505 struct dbreg r1; 1506 size_t i; 1507 volatile int watchme = 1; 1508 union u dr7; 1509 1510 struct ptrace_siginfo info; 1511 memset(&info, 0, sizeof(info)); 1512 1513 if (!can_we_set_dbregs()) { 1514 atf_tc_skip("Either run this test as root or set sysctl(3) " 1515 "security.models.extensions.user_set_dbregs to 1"); 1516 } 1517 1518 dr7.raw = 0; 1519 dr7.bits.global_dr3_breakpoint = 1; 1520 dr7.bits.condition_dr3 = 0; /* 0b00 -- break on code execution */ 1521 dr7.bits.len_dr3 = 0; /* 0b00 -- 1 byte */ 1522 1523 DPRINTF("Before forking process PID=%d\n", getpid()); 1524 SYSCALL_REQUIRE((child = fork()) != -1); 1525 if (child == 0) { 1526 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 1527 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 1528 1529 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 1530 FORKEE_ASSERT(raise(sigval) == 0); 1531 1532 printf("check_happy(%d)=%d\n", watchme, check_happy(watchme)); 1533 1534 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 1535 FORKEE_ASSERT(raise(sigval) == 0); 1536 1537 DPRINTF("Before exiting of the child process\n"); 1538 _exit(exitval); 1539 } 1540 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 1541 1542 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1543 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1544 1545 validate_status_stopped(status, sigval); 1546 1547 DPRINTF("Call GETDBREGS for the child process (r1)\n"); 1548 SYSCALL_REQUIRE(ptrace(PT_GETDBREGS, child, &r1, 0) != -1); 1549 1550 DPRINTF("State of the debug registers (r1):\n"); 1551 for (i = 0; i < __arraycount(r1.dr); i++) 1552 DPRINTF("r1[%zu]=%" PRIxREGISTER "\n", i, r1.dr[i]); 1553 1554 r1.dr[3] = (long)(intptr_t)check_happy; 1555 DPRINTF("Set DR3 (r1.dr[3]) to new value %" PRIxREGISTER "\n", 1556 r1.dr[3]); 1557 1558 r1.dr[7] = dr7.raw; 1559 DPRINTF("Set DR7 (r1.dr[7]) to new value %" PRIxREGISTER "\n", 1560 r1.dr[7]); 1561 1562 DPRINTF("New state of the debug registers (r1):\n"); 1563 for (i = 0; i < __arraycount(r1.dr); i++) 1564 DPRINTF("r1[%zu]=%" PRIxREGISTER "\n", i, r1.dr[i]); 1565 1566 DPRINTF("Call SETDBREGS for the child process (r1)\n"); 1567 SYSCALL_REQUIRE(ptrace(PT_SETDBREGS, child, &r1, 0) != -1); 1568 1569 DPRINTF("Call CONTINUE for the child process\n"); 1570 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 1571 1572 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1573 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1574 1575 validate_status_stopped(status, SIGTRAP); 1576 1577 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 1578 SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 1579 1580 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 1581 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 1582 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 1583 info.psi_siginfo.si_errno); 1584 1585 DPRINTF("Before checking siginfo_t\n"); 1586 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); 1587 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_DBREG); 1588 1589 DPRINTF("Remove code trap from check_happy=%p\n", check_happy); 1590 dr7.bits.global_dr3_breakpoint = 0; 1591 r1.dr[7] = dr7.raw; 1592 DPRINTF("Set DR7 (r1.dr[7]) to new value %" PRIxREGISTER "\n", 1593 r1.dr[7]); 1594 1595 DPRINTF("Call SETDBREGS for the child process (r1)\n"); 1596 SYSCALL_REQUIRE(ptrace(PT_SETDBREGS, child, &r1, 0) != -1); 1597 1598 DPRINTF("Call CONTINUE for the child process\n"); 1599 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 1600 1601 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1602 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1603 1604 validate_status_stopped(status, sigval); 1605 1606 DPRINTF("Before resuming the child process where it left off and " 1607 "without signal to be sent\n"); 1608 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 1609 1610 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1611 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1612 1613 validate_status_exited(status, exitval); 1614 1615 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1616 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 1617 } 1618 #endif 1619 1620 static void * __used 1621 x86_main_func(void *arg) 1622 { 1623 1624 return arg; 1625 } 1626 1627 static void 1628 dbregs_dont_inherit_lwp(int reg) 1629 { 1630 const int exitval = 5; 1631 const int sigval = SIGSTOP; 1632 pid_t child, wpid; 1633 #if defined(TWAIT_HAVE_STATUS) 1634 int status; 1635 #endif 1636 ptrace_state_t state; 1637 const int slen = sizeof(state); 1638 ptrace_event_t event; 1639 const int elen = sizeof(event); 1640 pthread_t t; 1641 lwpid_t lid; 1642 size_t i; 1643 struct dbreg r1; 1644 struct dbreg r2; 1645 1646 if (!can_we_set_dbregs()) { 1647 atf_tc_skip("Either run this test as root or set sysctl(3) " 1648 "security.models.extensions.user_set_dbregs to 1"); 1649 } 1650 1651 DPRINTF("Before forking process PID=%d\n", getpid()); 1652 SYSCALL_REQUIRE((child = fork()) != -1); 1653 if (child == 0) { 1654 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 1655 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 1656 1657 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 1658 FORKEE_ASSERT(raise(sigval) == 0); 1659 1660 FORKEE_ASSERT(!pthread_create(&t, NULL, x86_main_func, NULL)); 1661 1662 DPRINTF("Before waiting for thread to exit\n"); 1663 FORKEE_ASSERT(!pthread_join(t, NULL)); 1664 1665 DPRINTF("Before exiting of the child process\n"); 1666 _exit(exitval); 1667 } 1668 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 1669 1670 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1671 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1672 1673 validate_status_stopped(status, sigval); 1674 1675 DPRINTF("Set empty EVENT_MASK for the child %d\n", child); 1676 event.pe_set_event = PTRACE_LWP_CREATE; 1677 SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); 1678 1679 DPRINTF("Call GETDBREGS for the child process (r1)\n"); 1680 SYSCALL_REQUIRE(ptrace(PT_GETDBREGS, child, &r1, 0) != -1); 1681 1682 DPRINTF("State of the debug registers (r1):\n"); 1683 for (i = 0; i < __arraycount(r1.dr); i++) 1684 DPRINTF("r1[%zu]=%" PRIxREGISTER "\n", i, r1.dr[i]); 1685 1686 r1.dr[reg] = (long)(intptr_t)check_happy; 1687 DPRINTF("Set DR%d (r1.dr[%d]) to new value %" PRIxREGISTER "\n", 1688 reg, reg, r1.dr[0]); 1689 1690 DPRINTF("New state of the debug registers (r1):\n"); 1691 for (i = 0; i < __arraycount(r1.dr); i++) 1692 DPRINTF("r1[%zu]=%" PRIxREGISTER "\n", i, r1.dr[i]); 1693 1694 DPRINTF("Call SETDBREGS for the child process (r1)\n"); 1695 SYSCALL_REQUIRE(ptrace(PT_SETDBREGS, child, &r1, 0) != -1); 1696 1697 DPRINTF("Before resuming the child process where it left off and " 1698 "without signal to be sent\n"); 1699 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 1700 1701 DPRINTF("Before calling %s() for the child - expected stopped " 1702 "SIGTRAP\n", TWAIT_FNAME); 1703 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1704 1705 validate_status_stopped(status, SIGTRAP); 1706 1707 SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 1708 1709 ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_LWP_CREATE); 1710 1711 lid = state.pe_lwp; 1712 DPRINTF("Reported PTRACE_LWP_CREATE event with lid %d\n", lid); 1713 1714 DPRINTF("Call GETDBREGS for the child process new lwp (r2)\n"); 1715 SYSCALL_REQUIRE(ptrace(PT_GETDBREGS, child, &r2, lid) != -1); 1716 1717 DPRINTF("State of the debug registers (r2):\n"); 1718 for (i = 0; i < __arraycount(r2.dr); i++) 1719 DPRINTF("r2[%zu]=%" PRIxREGISTER "\n", i, r2.dr[i]); 1720 1721 DPRINTF("Assert that (r1) and (r2) are not the same\n"); 1722 ATF_REQUIRE(memcmp(&r1, &r2, sizeof(r1)) != 0); 1723 1724 DPRINTF("Before resuming the child process where it left off and " 1725 "without signal to be sent\n"); 1726 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 1727 1728 DPRINTF("Before calling %s() for the child - expected exited\n", 1729 TWAIT_FNAME); 1730 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1731 1732 validate_status_exited(status, exitval); 1733 1734 DPRINTF("Before calling %s() for the child - expected no process\n", 1735 TWAIT_FNAME); 1736 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 1737 } 1738 1739 ATF_TC(dbregs_dr0_dont_inherit_lwp); 1740 ATF_TC_HEAD(dbregs_dr0_dont_inherit_lwp, tc) 1741 { 1742 atf_tc_set_md_var(tc, "descr", 1743 "Verify that 1 LWP creation is intercepted by ptrace(2) with " 1744 "EVENT_MASK set to PTRACE_LWP_CREATE and Debug Register 0 from " 1745 "the forker thread is not inherited"); 1746 } 1747 1748 ATF_TC_BODY(dbregs_dr0_dont_inherit_lwp, tc) 1749 { 1750 dbregs_dont_inherit_lwp(0); 1751 } 1752 1753 ATF_TC(dbregs_dr1_dont_inherit_lwp); 1754 ATF_TC_HEAD(dbregs_dr1_dont_inherit_lwp, tc) 1755 { 1756 atf_tc_set_md_var(tc, "descr", 1757 "Verify that 1 LWP creation is intercepted by ptrace(2) with " 1758 "EVENT_MASK set to PTRACE_LWP_CREATE and Debug Register 1 from " 1759 "the forker thread is not inherited"); 1760 } 1761 1762 ATF_TC_BODY(dbregs_dr1_dont_inherit_lwp, tc) 1763 { 1764 dbregs_dont_inherit_lwp(1); 1765 } 1766 1767 ATF_TC(dbregs_dr2_dont_inherit_lwp); 1768 ATF_TC_HEAD(dbregs_dr2_dont_inherit_lwp, tc) 1769 { 1770 atf_tc_set_md_var(tc, "descr", 1771 "Verify that 1 LWP creation is intercepted by ptrace(2) with " 1772 "EVENT_MASK set to PTRACE_LWP_CREATE and Debug Register 2 from " 1773 "the forker thread is not inherited"); 1774 } 1775 1776 ATF_TC_BODY(dbregs_dr2_dont_inherit_lwp, tc) 1777 { 1778 dbregs_dont_inherit_lwp(2); 1779 } 1780 1781 ATF_TC(dbregs_dr3_dont_inherit_lwp); 1782 ATF_TC_HEAD(dbregs_dr3_dont_inherit_lwp, tc) 1783 { 1784 atf_tc_set_md_var(tc, "descr", 1785 "Verify that 1 LWP creation is intercepted by ptrace(2) with " 1786 "EVENT_MASK set to PTRACE_LWP_CREATE and Debug Register 3 from " 1787 "the forker thread is not inherited"); 1788 } 1789 1790 ATF_TC_BODY(dbregs_dr3_dont_inherit_lwp, tc) 1791 { 1792 dbregs_dont_inherit_lwp(3); 1793 } 1794 1795 static void 1796 dbregs_dont_inherit_execve(int reg) 1797 { 1798 const int sigval = SIGTRAP; 1799 pid_t child, wpid; 1800 #if defined(TWAIT_HAVE_STATUS) 1801 int status; 1802 #endif 1803 size_t i; 1804 struct dbreg r1; 1805 struct dbreg r2; 1806 1807 struct ptrace_siginfo info; 1808 memset(&info, 0, sizeof(info)); 1809 1810 if (!can_we_set_dbregs()) { 1811 atf_tc_skip("Either run this test as root or set sysctl(3) " 1812 "security.models.extensions.user_set_dbregs to 1"); 1813 } 1814 1815 DPRINTF("Before forking process PID=%d\n", getpid()); 1816 SYSCALL_REQUIRE((child = fork()) != -1); 1817 if (child == 0) { 1818 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 1819 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 1820 1821 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 1822 FORKEE_ASSERT(raise(sigval) == 0); 1823 1824 DPRINTF("Before calling execve(2) from child\n"); 1825 execlp("/bin/echo", "/bin/echo", NULL); 1826 1827 FORKEE_ASSERT(0 && "Not reached"); 1828 } 1829 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 1830 1831 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1832 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1833 1834 validate_status_stopped(status, sigval); 1835 1836 DPRINTF("Call GETDBREGS for the child process (r1)\n"); 1837 SYSCALL_REQUIRE(ptrace(PT_GETDBREGS, child, &r1, 0) != -1); 1838 1839 DPRINTF("State of the debug registers (r1):\n"); 1840 for (i = 0; i < __arraycount(r1.dr); i++) 1841 DPRINTF("r1[%zu]=%" PRIxREGISTER "\n", i, r1.dr[i]); 1842 1843 r1.dr[reg] = (long)(intptr_t)check_happy; 1844 DPRINTF("Set DR%d (r1.dr[%d]) to new value %" PRIxREGISTER "\n", 1845 reg, reg, r1.dr[reg]); 1846 1847 DPRINTF("New state of the debug registers (r1):\n"); 1848 for (i = 0; i < __arraycount(r1.dr); i++) 1849 DPRINTF("r1[%zu]=%" PRIxREGISTER "\n", i, r1.dr[i]); 1850 1851 DPRINTF("Call SETDBREGS for the child process (r1)\n"); 1852 SYSCALL_REQUIRE(ptrace(PT_SETDBREGS, child, &r1, 0) != -1); 1853 1854 DPRINTF("Before resuming the child process where it left off and " 1855 "without signal to be sent\n"); 1856 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 1857 1858 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1859 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1860 1861 validate_status_stopped(status, sigval); 1862 1863 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 1864 SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 1865 1866 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 1867 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 1868 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 1869 info.psi_siginfo.si_errno); 1870 1871 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 1872 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_EXEC); 1873 1874 DPRINTF("Call GETDBREGS for the child process after execve(2)\n"); 1875 SYSCALL_REQUIRE(ptrace(PT_GETDBREGS, child, &r2, 0) != -1); 1876 1877 DPRINTF("State of the debug registers (r2):\n"); 1878 for (i = 0; i < __arraycount(r2.dr); i++) 1879 DPRINTF("r2[%zu]=%" PRIxREGISTER "\n", i, r2.dr[i]); 1880 1881 DPRINTF("Assert that (r1) and (r2) are not the same\n"); 1882 ATF_REQUIRE(memcmp(&r1, &r2, sizeof(r1)) != 0); 1883 1884 DPRINTF("Before resuming the child process where it left off and " 1885 "without signal to be sent\n"); 1886 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 1887 1888 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1889 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1890 1891 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1892 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 1893 } 1894 1895 ATF_TC(dbregs_dr0_dont_inherit_execve); 1896 ATF_TC_HEAD(dbregs_dr0_dont_inherit_execve, tc) 1897 { 1898 atf_tc_set_md_var(tc, "descr", 1899 "Verify that execve(2) is intercepted by tracer and Debug " 1900 "Register 0 is reset"); 1901 } 1902 1903 ATF_TC_BODY(dbregs_dr0_dont_inherit_execve, tc) 1904 { 1905 dbregs_dont_inherit_execve(0); 1906 } 1907 1908 ATF_TC(dbregs_dr1_dont_inherit_execve); 1909 ATF_TC_HEAD(dbregs_dr1_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 1 is reset"); 1914 } 1915 1916 ATF_TC_BODY(dbregs_dr1_dont_inherit_execve, tc) 1917 { 1918 dbregs_dont_inherit_execve(1); 1919 } 1920 1921 ATF_TC(dbregs_dr2_dont_inherit_execve); 1922 ATF_TC_HEAD(dbregs_dr2_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 2 is reset"); 1927 } 1928 1929 ATF_TC_BODY(dbregs_dr2_dont_inherit_execve, tc) 1930 { 1931 dbregs_dont_inherit_execve(2); 1932 } 1933 1934 ATF_TC(dbregs_dr3_dont_inherit_execve); 1935 ATF_TC_HEAD(dbregs_dr3_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 3 is reset"); 1940 } 1941 1942 ATF_TC_BODY(dbregs_dr3_dont_inherit_execve, tc) 1943 { 1944 dbregs_dont_inherit_execve(3); 1945 } 1946 1947 /// ---------------------------------------------------------------------------- 1948 1949 ATF_TC(x86_cve_2018_8897); 1950 ATF_TC_HEAD(x86_cve_2018_8897, tc) 1951 { 1952 atf_tc_set_md_var(tc, "descr", 1953 "Verify mitigation for CVE-2018-8897 (POP SS debug exception)"); 1954 } 1955 1956 #define X86_CVE_2018_8897_PAGE 0x5000 /* page addressable by 32-bit registers */ 1957 1958 static void 1959 x86_cve_2018_8897_trigger(void) 1960 { 1961 /* 1962 * A function to trigger the POP SS (CVE-2018-8897) vulnerability 1963 * 1964 * ifdef __x86_64__ 1965 * 1966 * We need to switch to 32-bit mode execution on 64-bit kernel. 1967 * This is achieved with far jump instruction and GDT descriptor 1968 * set to 32-bit CS selector. The 32-bit CS selector is kernel 1969 * specific, in the NetBSD case registered as GUCODE32_SEL 1970 * that is equal to (14 (decimal) << 3) with GDT and user 1971 * privilege level (this makes it 0x73). 1972 * 1973 * In UNIX as(1) assembly x86_64 far jump is coded as ljmp. 1974 * amd64 ljmp requires an indirect address with cs:RIP. 1975 * 1976 * When we are running in 32-bit mode, it's similar to the 1977 * mode as if the binary had been launched in netbsd32. 1978 * 1979 * There are two versions of this exploit, one with RIP 1980 * relative code and the other with static addresses. 1981 * The first one is PIE code aware, the other no-PIE one. 1982 * 1983 * 1984 * After switching to the 32-bit mode we can move on to the remaining 1985 * part of the exploit. 1986 * 1987 * endif // __x86_64__ 1988 * 1989 * Set the stack pointer to the page we allocated earlier. Remember 1990 * that we put an SS selector exactly at this address, so we can pop. 1991 * 1992 * movl $0x5000,%esp 1993 * 1994 * Pop the SS selector off the stack. This reloads the SS selector, 1995 * which is fine. Remember that we set DR0 at address 0x5000, which 1996 * we are now reading. Therefore, on this instruction, the CPU will 1997 * raise a #DB exception. 1998 * 1999 * But the "pop %ss" instruction is special: it blocks exceptions 2000 * until the next instruction is executed. So the #DB that we just 2001 * raised is actually blocked. 2002 * 2003 * pop %ss 2004 * 2005 * We are still here, and didn't receive the #DB. After we execute 2006 * this instruction, the effect of "pop %ss" will disappear, and 2007 * we will receive the #DB for real. 2008 * 2009 * int $4 2010 * 2011 * Here the bug happens. We executed "int $4", so we entered the 2012 * kernel, with interrupts disabled. The #DB that was pending is 2013 * received. But, it is received immediately in kernel mode, and is 2014 * _NOT_ received when interrupts are enabled again. 2015 * 2016 * It means that, in the first instruction of the $4 handler, we 2017 * think we are safe with interrupts disabled. But we aren't, and 2018 * just got interrupted. 2019 * 2020 * The new interrupt handler doesn't handle this particular context: 2021 * we are entered in kernel mode, the previous context was kernel 2022 * mode too but it still had the user context loaded. 2023 * 2024 * We find ourselves not doing a 'swapgs'. At the end of the day, it 2025 * means that we call trap() with a curcpu() that is fully 2026 * controllable by userland. From then on, it is easy to escalate 2027 * privileges. 2028 * 2029 * With SVS it also means we don't switch CR3, so this results in a 2030 * triple fault, which this time cannot be turned to a privilege 2031 * escalation. 2032 */ 2033 2034 #if __x86_64__ 2035 #if __PIE__ 2036 void *csRIP; 2037 2038 csRIP = malloc(sizeof(int) + sizeof(short)); 2039 FORKEE_ASSERT(csRIP != NULL); 2040 2041 __asm__ __volatile__( 2042 " leal 24(%%eip), %%eax\n\t" 2043 " movq %0, %%rdx\n\t" 2044 " movl %%eax, (%%rdx)\n\t" 2045 " movw $0x73, 4(%%rdx)\n\t" 2046 " movq %1, %%rax\n\t" 2047 " ljmp *(%%rax)\n\t" 2048 " .code32\n\t" 2049 " movl $0x5000, %%esp\n\t" 2050 " pop %%ss\n\t" 2051 " int $4\n\t" 2052 " .code64\n\t" 2053 : "=m"(csRIP) 2054 : "m"(csRIP) 2055 : "%rax", "%rdx", "%rsp" 2056 ); 2057 #else /* !__PIE__ */ 2058 __asm__ __volatile__( 2059 " movq $farjmp32%=, %%rax\n\t" 2060 " ljmp *(%%rax)\n\t" 2061 "farjmp32%=:\n\t" 2062 " .long trigger32%=\n\t" 2063 " .word 0x73\n\t" 2064 " .code32\n\t" 2065 "trigger32%=:\n\t" 2066 " movl $0x5000, %%esp\n\t" 2067 " pop %%ss\n\t" 2068 " int $4\n\t" 2069 " .code64\n\t" 2070 : 2071 : 2072 : "%rax", "%rsp" 2073 ); 2074 #endif 2075 #elif __i386__ 2076 __asm__ __volatile__( 2077 "movl $0x5000, %%esp\n\t" 2078 "pop %%ss\n\t" 2079 "int $4\n\t" 2080 : 2081 : 2082 : "%esp" 2083 ); 2084 #endif 2085 } 2086 2087 ATF_TC_BODY(x86_cve_2018_8897, tc) 2088 { 2089 const int sigval = SIGSTOP; 2090 pid_t child, wpid; 2091 #if defined(TWAIT_HAVE_STATUS) 2092 int status; 2093 #endif 2094 char *trap_page; 2095 struct dbreg db; 2096 2097 2098 if (!can_we_set_dbregs()) { 2099 atf_tc_skip("Either run this test as root or set sysctl(3) " 2100 "security.models.extensions.user_set_dbregs to 1"); 2101 } 2102 2103 DPRINTF("Before forking process PID=%d\n", getpid()); 2104 SYSCALL_REQUIRE((child = fork()) != -1); 2105 if (child == 0) { 2106 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 2107 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 2108 2109 trap_page = mmap((void *)X86_CVE_2018_8897_PAGE, 2110 sysconf(_SC_PAGESIZE), PROT_READ|PROT_WRITE, 2111 MAP_FIXED|MAP_ANON|MAP_PRIVATE, -1, 0); 2112 2113 /* trigger page fault */ 2114 memset(trap_page, 0, sysconf(_SC_PAGESIZE)); 2115 2116 // kernel GDT 2117 #if __x86_64__ 2118 /* SS selector (descriptor 9 (0x4f >> 3)) */ 2119 *trap_page = 0x4f; 2120 #elif __i386__ 2121 /* SS selector (descriptor 4 (0x23 >> 3)) */ 2122 *trap_page = 0x23; 2123 #endif 2124 2125 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 2126 FORKEE_ASSERT(raise(sigval) == 0); 2127 2128 x86_cve_2018_8897_trigger(); 2129 2130 /* NOTREACHED */ 2131 FORKEE_ASSERTX(0 && "This shall not be reached"); 2132 } 2133 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 2134 2135 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 2136 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 2137 2138 validate_status_stopped(status, sigval); 2139 2140 DPRINTF("Call GETDBREGS for the child process\n"); 2141 SYSCALL_REQUIRE(ptrace(PT_GETDBREGS, child, &db, 0) != -1); 2142 2143 /* 2144 * Set up the dbregs. We put the 0x5000 address in DR0. 2145 * It means that, the first time we touch this, the CPU will trigger a 2146 * #DB exception. 2147 */ 2148 db.dr[0] = X86_CVE_2018_8897_PAGE; 2149 db.dr[7] = 0x30003; 2150 2151 DPRINTF("Call SETDBREGS for the child process\n"); 2152 SYSCALL_REQUIRE(ptrace(PT_SETDBREGS, child, &db, 0) != -1); 2153 2154 DPRINTF("Before resuming the child process where it left off and " 2155 "without signal to be sent\n"); 2156 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 2157 2158 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 2159 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 2160 2161 // In this test we receive SIGFPE, is this appropriate? 2162 // validate_status_stopped(status, SIGFPE); 2163 2164 DPRINTF("Kill the child process\n"); 2165 SYSCALL_REQUIRE(ptrace(PT_KILL, child, NULL, 0) != -1); 2166 2167 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 2168 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 2169 2170 validate_status_signaled(status, SIGKILL, 0); 2171 2172 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 2173 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 2174 } 2175 2176 /// ---------------------------------------------------------------------------- 2177 2178 union x86_test_register { 2179 struct { 2180 uint64_t a, b, c, d; 2181 } ymm; 2182 struct { 2183 uint64_t a, b; 2184 } xmm; 2185 uint64_t u64; 2186 uint32_t u32; 2187 }; 2188 2189 enum x86_test_regset { 2190 TEST_GPREGS, 2191 TEST_FPREGS, 2192 TEST_XMMREGS, 2193 TEST_XSTATE 2194 }; 2195 2196 /* Please keep them grouped by acceptable x86_test_regset. */ 2197 enum x86_test_registers { 2198 /* TEST_GPREGS */ 2199 GPREGS_32, 2200 GPREGS_32_EBP_ESP, 2201 GPREGS_64, 2202 GPREGS_64_R8, 2203 /* TEST_FPREGS/TEST_XMMREGS */ 2204 FPREGS_MM, 2205 FPREGS_XMM, 2206 /* TEST_XSTATE */ 2207 FPREGS_YMM 2208 }; 2209 2210 enum x86_test_regmode { 2211 TEST_GETREGS, 2212 TEST_SETREGS, 2213 TEST_COREDUMP 2214 }; 2215 2216 static __inline void get_gp32_regs(union x86_test_register out[]) 2217 { 2218 #if defined(__i386__) 2219 const uint32_t fill = 0x0F0F0F0F; 2220 2221 __asm__ __volatile__( 2222 /* fill registers with clobber pattern */ 2223 "movl %6, %%eax\n\t" 2224 "movl %6, %%ebx\n\t" 2225 "movl %6, %%ecx\n\t" 2226 "movl %6, %%edx\n\t" 2227 "movl %6, %%esi\n\t" 2228 "movl %6, %%edi\n\t" 2229 "\n\t" 2230 "int3\n\t" 2231 : "=a"(out[0].u32), "=b"(out[1].u32), "=c"(out[2].u32), 2232 "=d"(out[3].u32), "=S"(out[4].u32), "=D"(out[5].u32) 2233 : "g"(fill) 2234 ); 2235 #else 2236 __unreachable(); 2237 #endif 2238 } 2239 2240 static __inline void set_gp32_regs(const union x86_test_register data[]) 2241 { 2242 #if defined(__i386__) 2243 __asm__ __volatile__( 2244 "int3\n\t" 2245 : 2246 : "a"(data[0].u32), "b"(data[1].u32), "c"(data[2].u32), 2247 "d"(data[3].u32), "S"(data[4].u32), "D"(data[5].u32) 2248 : 2249 ); 2250 #else 2251 __unreachable(); 2252 #endif 2253 } 2254 2255 static __inline void get_gp32_ebp_esp_regs(union x86_test_register out[]) 2256 { 2257 #if defined(__i386__) 2258 const uint32_t fill = 0x0F0F0F0F; 2259 2260 __asm__ __volatile__( 2261 /* save original ebp & esp using our output registers */ 2262 "movl %%esp, %0\n\t" 2263 "movl %%ebp, %1\n\t" 2264 /* fill them with clobber pattern */ 2265 "movl %2, %%esp\n\t" 2266 "movl %2, %%ebp\n\t" 2267 "\n\t" 2268 "int3\n\t" 2269 "\n\t" 2270 /* restore ebp & esp, and save the result */ 2271 "xchgl %%esp, %0\n\t" 2272 "xchgl %%ebp, %1\n\t" 2273 : "=r"(out[0].u32), "=r"(out[1].u32) 2274 : "g"(fill) 2275 : 2276 ); 2277 #else 2278 __unreachable(); 2279 #endif 2280 } 2281 2282 static __inline void set_gp32_ebp_esp_regs(const union x86_test_register data[]) 2283 { 2284 #if defined(__i386__) 2285 __asm__ __volatile__( 2286 /* ebp & ebp are a bit tricky, we must not clobber them */ 2287 "movl %%esp, %%eax\n\t" 2288 "movl %%ebp, %%ebx\n\t" 2289 "movl %0, %%esp\n\t" 2290 "movl %1, %%ebp\n\t" 2291 "\n\t" 2292 "int3\n\t" 2293 "\n\t" 2294 "movl %%eax, %%esp\n\t" 2295 "movl %%ebx, %%ebp\n\t" 2296 : 2297 : "ri"(data[0].u32), "ri"(data[1].u32) 2298 : "%eax", "%ebx" 2299 ); 2300 #else 2301 __unreachable(); 2302 #endif 2303 } 2304 2305 static __inline void get_gp64_regs(union x86_test_register out[]) 2306 { 2307 #if defined(__x86_64__) 2308 const uint64_t fill = 0x0F0F0F0F0F0F0F0F; 2309 2310 __asm__ __volatile__( 2311 /* save rsp & rbp */ 2312 "movq %%rsp, %6\n\t" 2313 "movq %%rbp, %7\n\t" 2314 "\n\t" 2315 /* fill registers with clobber pattern */ 2316 "movq %8, %%rax\n\t" 2317 "movq %8, %%rbx\n\t" 2318 "movq %8, %%rcx\n\t" 2319 "movq %8, %%rdx\n\t" 2320 "movq %8, %%rsp\n\t" 2321 "movq %8, %%rbp\n\t" 2322 "movq %8, %%rsi\n\t" 2323 "movq %8, %%rdi\n\t" 2324 "\n\t" 2325 "int3\n\t" 2326 "\n\t" 2327 /* swap saved & current rsp & rbp */ 2328 "xchgq %%rsp, %6\n\t" 2329 "xchgq %%rbp, %7\n\t" 2330 : "=a"(out[0].u64), "=b"(out[1].u64), "=c"(out[2].u64), 2331 "=d"(out[3].u64), "=S"(out[4].u64), "=D"(out[5].u64), 2332 "=r"(out[6].u64), "=r"(out[7].u64) 2333 : "g"(fill) 2334 ); 2335 #else 2336 __unreachable(); 2337 #endif 2338 } 2339 2340 static __inline void set_gp64_regs(const union x86_test_register data[]) 2341 { 2342 #if defined(__x86_64__) 2343 __asm__ __volatile__( 2344 /* rbp & rbp are a bit tricky, we must not clobber them */ 2345 "movq %%rsp, %%r8\n\t" 2346 "movq %%rbp, %%r9\n\t" 2347 "movq %6, %%rsp\n\t" 2348 "movq %7, %%rbp\n\t" 2349 "\n\t" 2350 "int3\n\t" 2351 "\n\t" 2352 "movq %%r8, %%rsp\n\t" 2353 "movq %%r9, %%rbp\n\t" 2354 : 2355 : "a"(data[0].u64), "b"(data[1].u64), "c"(data[2].u64), 2356 "d"(data[3].u64), "S"(data[4].u64), "D"(data[5].u64), 2357 "r"(data[6].u64), "r"(data[7].u64) 2358 : "%r8", "%r9" 2359 ); 2360 #else 2361 __unreachable(); 2362 #endif 2363 } 2364 2365 static __inline void get_gp64_r8_regs(union x86_test_register out[]) 2366 { 2367 #if defined(__x86_64__) 2368 const uint64_t fill = 0x0F0F0F0F0F0F0F0F; 2369 2370 __asm__ __volatile__( 2371 /* fill registers with clobber pattern */ 2372 "movq %1, %%r8\n\t" 2373 "movq %1, %%r9\n\t" 2374 "movq %1, %%r10\n\t" 2375 "movq %1, %%r11\n\t" 2376 "movq %1, %%r12\n\t" 2377 "movq %1, %%r13\n\t" 2378 "movq %1, %%r14\n\t" 2379 "movq %1, %%r15\n\t" 2380 "\n\t" 2381 "int3\n\t" 2382 "\n\t" 2383 "movq %%r8, 0x00(%0)\n\t" 2384 "movq %%r9, 0x20(%0)\n\t" 2385 "movq %%r10, 0x40(%0)\n\t" 2386 "movq %%r11, 0x60(%0)\n\t" 2387 "movq %%r12, 0x80(%0)\n\t" 2388 "movq %%r13, 0xA0(%0)\n\t" 2389 "movq %%r14, 0xC0(%0)\n\t" 2390 "movq %%r15, 0xE0(%0)\n\t" 2391 : 2392 : "a"(out), "m"(fill) 2393 : "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15" 2394 ); 2395 #else 2396 __unreachable(); 2397 #endif 2398 } 2399 2400 static __inline void set_gp64_r8_regs(const union x86_test_register data[]) 2401 { 2402 #if defined(__x86_64__) 2403 __asm__ __volatile__( 2404 "movq 0x00(%0), %%r8\n\t" 2405 "movq 0x20(%0), %%r9\n\t" 2406 "movq 0x40(%0), %%r10\n\t" 2407 "movq 0x60(%0), %%r11\n\t" 2408 "movq 0x80(%0), %%r12\n\t" 2409 "movq 0xA0(%0), %%r13\n\t" 2410 "movq 0xC0(%0), %%r14\n\t" 2411 "movq 0xE0(%0), %%r15\n\t" 2412 "int3\n\t" 2413 : 2414 : "b"(data) 2415 : "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15" 2416 ); 2417 #else 2418 __unreachable(); 2419 #endif 2420 } 2421 2422 __attribute__((target("mmx"))) 2423 static __inline void get_mm_regs(union x86_test_register out[]) 2424 { 2425 const uint64_t fill = 0x0F0F0F0F0F0F0F0F; 2426 2427 __asm__ __volatile__( 2428 /* fill registers with clobber pattern */ 2429 "movq %1, %%mm0\n\t" 2430 "movq %1, %%mm1\n\t" 2431 "movq %1, %%mm2\n\t" 2432 "movq %1, %%mm3\n\t" 2433 "movq %1, %%mm4\n\t" 2434 "movq %1, %%mm5\n\t" 2435 "movq %1, %%mm6\n\t" 2436 "movq %1, %%mm7\n\t" 2437 "\n\t" 2438 "int3\n\t" 2439 "\n\t" 2440 "movq %%mm0, 0x00(%0)\n\t" 2441 "movq %%mm1, 0x20(%0)\n\t" 2442 "movq %%mm2, 0x40(%0)\n\t" 2443 "movq %%mm3, 0x60(%0)\n\t" 2444 "movq %%mm4, 0x80(%0)\n\t" 2445 "movq %%mm5, 0xA0(%0)\n\t" 2446 "movq %%mm6, 0xC0(%0)\n\t" 2447 "movq %%mm7, 0xE0(%0)\n\t" 2448 : 2449 : "a"(out), "m"(fill) 2450 : "%mm0", "%mm1", "%mm2", "%mm3", "%mm4", "%mm5", "%mm6", "%mm7" 2451 ); 2452 } 2453 2454 __attribute__((target("mmx"))) 2455 static __inline void set_mm_regs(const union x86_test_register data[]) 2456 { 2457 __asm__ __volatile__( 2458 "movq 0x00(%0), %%mm0\n\t" 2459 "movq 0x20(%0), %%mm1\n\t" 2460 "movq 0x40(%0), %%mm2\n\t" 2461 "movq 0x60(%0), %%mm3\n\t" 2462 "movq 0x80(%0), %%mm4\n\t" 2463 "movq 0xA0(%0), %%mm5\n\t" 2464 "movq 0xC0(%0), %%mm6\n\t" 2465 "movq 0xE0(%0), %%mm7\n\t" 2466 "int3\n\t" 2467 : 2468 : "b"(data) 2469 : "%mm0", "%mm1", "%mm2", "%mm3", "%mm4", "%mm5", "%mm6", "%mm7" 2470 ); 2471 } 2472 2473 __attribute__((target("sse"))) 2474 static __inline void get_xmm_regs(union x86_test_register out[]) 2475 { 2476 union x86_test_register fill __aligned(32) = { 2477 .xmm={ 0x0F0F0F0F0F0F0F0F, 0x0F0F0F0F0F0F0F0F } 2478 }; 2479 2480 __asm__ __volatile__( 2481 /* fill registers with clobber pattern */ 2482 "movaps %1, %%xmm0\n\t" 2483 "movaps %1, %%xmm1\n\t" 2484 "movaps %1, %%xmm2\n\t" 2485 "movaps %1, %%xmm3\n\t" 2486 "movaps %1, %%xmm4\n\t" 2487 "movaps %1, %%xmm5\n\t" 2488 "movaps %1, %%xmm6\n\t" 2489 "movaps %1, %%xmm7\n\t" 2490 #if defined(__x86_64__) 2491 "movaps %1, %%xmm8\n\t" 2492 "movaps %1, %%xmm9\n\t" 2493 "movaps %1, %%xmm10\n\t" 2494 "movaps %1, %%xmm11\n\t" 2495 "movaps %1, %%xmm12\n\t" 2496 "movaps %1, %%xmm13\n\t" 2497 "movaps %1, %%xmm14\n\t" 2498 "movaps %1, %%xmm15\n\t" 2499 #endif 2500 "\n\t" 2501 "int3\n\t" 2502 "\n\t" 2503 "movaps %%xmm0, 0x000(%0)\n\t" 2504 "movaps %%xmm1, 0x020(%0)\n\t" 2505 "movaps %%xmm2, 0x040(%0)\n\t" 2506 "movaps %%xmm3, 0x060(%0)\n\t" 2507 "movaps %%xmm4, 0x080(%0)\n\t" 2508 "movaps %%xmm5, 0x0A0(%0)\n\t" 2509 "movaps %%xmm6, 0x0C0(%0)\n\t" 2510 "movaps %%xmm7, 0x0E0(%0)\n\t" 2511 #if defined(__x86_64__) 2512 "movaps %%xmm8, 0x100(%0)\n\t" 2513 "movaps %%xmm9, 0x120(%0)\n\t" 2514 "movaps %%xmm10, 0x140(%0)\n\t" 2515 "movaps %%xmm11, 0x160(%0)\n\t" 2516 "movaps %%xmm12, 0x180(%0)\n\t" 2517 "movaps %%xmm13, 0x1A0(%0)\n\t" 2518 "movaps %%xmm14, 0x1C0(%0)\n\t" 2519 "movaps %%xmm15, 0x1E0(%0)\n\t" 2520 #endif 2521 : 2522 : "a"(out), "m"(fill) 2523 : "%xmm0", "%xmm1", "%xmm2", "%xmm3", "%xmm4", "%xmm5", "%xmm6", "%xmm7" 2524 #if defined(__x86_64__) 2525 , "%xmm8", "%xmm9", "%xmm10", "%xmm11", "%xmm12", "%xmm13", "%xmm14", 2526 "%xmm15" 2527 #endif 2528 ); 2529 } 2530 2531 __attribute__((target("sse"))) 2532 static __inline void set_xmm_regs(const union x86_test_register data[]) 2533 { 2534 __asm__ __volatile__( 2535 "movaps 0x000(%0), %%xmm0\n\t" 2536 "movaps 0x020(%0), %%xmm1\n\t" 2537 "movaps 0x040(%0), %%xmm2\n\t" 2538 "movaps 0x060(%0), %%xmm3\n\t" 2539 "movaps 0x080(%0), %%xmm4\n\t" 2540 "movaps 0x0A0(%0), %%xmm5\n\t" 2541 "movaps 0x0C0(%0), %%xmm6\n\t" 2542 "movaps 0x0E0(%0), %%xmm7\n\t" 2543 #if defined(__x86_64__) 2544 "movaps 0x100(%0), %%xmm8\n\t" 2545 "movaps 0x120(%0), %%xmm9\n\t" 2546 "movaps 0x140(%0), %%xmm10\n\t" 2547 "movaps 0x160(%0), %%xmm11\n\t" 2548 "movaps 0x180(%0), %%xmm12\n\t" 2549 "movaps 0x1A0(%0), %%xmm13\n\t" 2550 "movaps 0x1C0(%0), %%xmm14\n\t" 2551 "movaps 0x1E0(%0), %%xmm15\n\t" 2552 #endif 2553 "int3\n\t" 2554 : 2555 : "b"(data) 2556 : "%xmm0", "%xmm1", "%xmm2", "%xmm3", "%xmm4", "%xmm5", "%xmm6", 2557 "%xmm7" 2558 #if defined(__x86_64__) 2559 , "%xmm8", "%xmm9", "%xmm10", "%xmm11", "%xmm12", "%xmm13", 2560 "%xmm14", "%xmm15" 2561 #endif 2562 ); 2563 } 2564 2565 __attribute__((target("avx"))) 2566 static __inline void get_ymm_regs(union x86_test_register out[]) 2567 { 2568 union x86_test_register fill __aligned(32) = { 2569 { 0x0F0F0F0F0F0F0F0F, 0x0F0F0F0F0F0F0F0F, 2570 0x0F0F0F0F0F0F0F0F, 0x0F0F0F0F0F0F0F0F } 2571 }; 2572 2573 __asm__ __volatile__( 2574 /* fill registers with clobber pattern */ 2575 "vmovaps %1, %%ymm0\n\t" 2576 "vmovaps %1, %%ymm1\n\t" 2577 "vmovaps %1, %%ymm2\n\t" 2578 "vmovaps %1, %%ymm3\n\t" 2579 "vmovaps %1, %%ymm4\n\t" 2580 "vmovaps %1, %%ymm5\n\t" 2581 "vmovaps %1, %%ymm6\n\t" 2582 "vmovaps %1, %%ymm7\n\t" 2583 #if defined(__x86_64__) 2584 "vmovaps %1, %%ymm8\n\t" 2585 "vmovaps %1, %%ymm9\n\t" 2586 "vmovaps %1, %%ymm10\n\t" 2587 "vmovaps %1, %%ymm11\n\t" 2588 "vmovaps %1, %%ymm12\n\t" 2589 "vmovaps %1, %%ymm13\n\t" 2590 "vmovaps %1, %%ymm14\n\t" 2591 "vmovaps %1, %%ymm15\n\t" 2592 #endif 2593 "\n\t" 2594 "int3\n\t" 2595 "\n\t" 2596 "vmovaps %%ymm0, 0x000(%0)\n\t" 2597 "vmovaps %%ymm1, 0x020(%0)\n\t" 2598 "vmovaps %%ymm2, 0x040(%0)\n\t" 2599 "vmovaps %%ymm3, 0x060(%0)\n\t" 2600 "vmovaps %%ymm4, 0x080(%0)\n\t" 2601 "vmovaps %%ymm5, 0x0A0(%0)\n\t" 2602 "vmovaps %%ymm6, 0x0C0(%0)\n\t" 2603 "vmovaps %%ymm7, 0x0E0(%0)\n\t" 2604 #if defined(__x86_64__) 2605 "vmovaps %%ymm8, 0x100(%0)\n\t" 2606 "vmovaps %%ymm9, 0x120(%0)\n\t" 2607 "vmovaps %%ymm10, 0x140(%0)\n\t" 2608 "vmovaps %%ymm11, 0x160(%0)\n\t" 2609 "vmovaps %%ymm12, 0x180(%0)\n\t" 2610 "vmovaps %%ymm13, 0x1A0(%0)\n\t" 2611 "vmovaps %%ymm14, 0x1C0(%0)\n\t" 2612 "vmovaps %%ymm15, 0x1E0(%0)\n\t" 2613 #endif 2614 : 2615 : "a"(out), "m"(fill) 2616 : "%ymm0", "%ymm1", "%ymm2", "%ymm3", "%ymm4", "%ymm5", "%ymm6", "%ymm7" 2617 #if defined(__x86_64__) 2618 , "%ymm8", "%ymm9", "%ymm10", "%ymm11", "%ymm12", "%ymm13", "%ymm14", 2619 "%ymm15" 2620 #endif 2621 ); 2622 } 2623 2624 __attribute__((target("avx"))) 2625 static __inline void set_ymm_regs(const union x86_test_register data[]) 2626 { 2627 __asm__ __volatile__( 2628 "vmovaps 0x000(%0), %%ymm0\n\t" 2629 "vmovaps 0x020(%0), %%ymm1\n\t" 2630 "vmovaps 0x040(%0), %%ymm2\n\t" 2631 "vmovaps 0x060(%0), %%ymm3\n\t" 2632 "vmovaps 0x080(%0), %%ymm4\n\t" 2633 "vmovaps 0x0A0(%0), %%ymm5\n\t" 2634 "vmovaps 0x0C0(%0), %%ymm6\n\t" 2635 "vmovaps 0x0E0(%0), %%ymm7\n\t" 2636 #if defined(__x86_64__) 2637 "vmovaps 0x100(%0), %%ymm8\n\t" 2638 "vmovaps 0x120(%0), %%ymm9\n\t" 2639 "vmovaps 0x140(%0), %%ymm10\n\t" 2640 "vmovaps 0x160(%0), %%ymm11\n\t" 2641 "vmovaps 0x180(%0), %%ymm12\n\t" 2642 "vmovaps 0x1A0(%0), %%ymm13\n\t" 2643 "vmovaps 0x1C0(%0), %%ymm14\n\t" 2644 "vmovaps 0x1E0(%0), %%ymm15\n\t" 2645 #endif 2646 "int3\n\t" 2647 : 2648 : "b"(data) 2649 : "%ymm0", "%ymm1", "%ymm2", "%ymm3", "%ymm4", "%ymm5", "%ymm6", 2650 "%ymm7" 2651 #if defined(__x86_64__) 2652 , "%ymm8", "%ymm9", "%ymm10", "%ymm11", "%ymm12", "%ymm13", 2653 "%ymm14", "%ymm15" 2654 #endif 2655 ); 2656 } 2657 2658 static void 2659 x86_register_test(enum x86_test_regset regset, enum x86_test_registers regs, 2660 enum x86_test_regmode regmode) 2661 { 2662 const int exitval = 5; 2663 pid_t child, wpid; 2664 #if defined(TWAIT_HAVE_STATUS) 2665 const int sigval = SIGTRAP; 2666 int status; 2667 #endif 2668 struct reg gpr; 2669 struct fpreg fpr; 2670 #if defined(__i386__) 2671 struct xmmregs xmm; 2672 #endif 2673 struct xstate xst; 2674 struct iovec iov; 2675 struct fxsave* fxs = NULL; 2676 uint64_t xst_flags = 0; 2677 char core_path[] = "/tmp/core.XXXXXX"; 2678 int core_fd; 2679 2680 const union x86_test_register expected[] __aligned(32) = { 2681 {{ 0x0706050403020100, 0x0F0E0D0C0B0A0908, 2682 0x1716151413121110, 0x1F1E1D1C1B1A1918, }}, 2683 {{ 0x0807060504030201, 0x100F0E0D0C0B0A09, 2684 0x1817161514131211, 0x201F1E1D1C1B1A19, }}, 2685 {{ 0x0908070605040302, 0x11100F0E0D0C0B0A, 2686 0x1918171615141312, 0x21201F1E1D1C1B1A, }}, 2687 {{ 0x0A09080706050403, 0x1211100F0E0D0C0B, 2688 0x1A19181716151413, 0x2221201F1E1D1C1B, }}, 2689 {{ 0x0B0A090807060504, 0x131211100F0E0D0C, 2690 0x1B1A191817161514, 0x232221201F1E1D1C, }}, 2691 {{ 0x0C0B0A0908070605, 0x14131211100F0E0D, 2692 0x1C1B1A1918171615, 0x24232221201F1E1D, }}, 2693 {{ 0x0D0C0B0A09080706, 0x1514131211100F0E, 2694 0x1D1C1B1A19181716, 0x2524232221201F1E, }}, 2695 {{ 0x0E0D0C0B0A090807, 0x161514131211100F, 2696 0x1E1D1C1B1A191817, 0x262524232221201F, }}, 2697 {{ 0x0F0E0D0C0B0A0908, 0x1716151413121110, 2698 0x1F1E1D1C1B1A1918, 0x2726252423222120, }}, 2699 {{ 0x100F0E0D0C0B0A09, 0x1817161514131211, 2700 0x201F1E1D1C1B1A19, 0x2827262524232221, }}, 2701 {{ 0x11100F0E0D0C0B0A, 0x1918171615141312, 2702 0x21201F1E1D1C1B1A, 0x2928272625242322, }}, 2703 {{ 0x1211100F0E0D0C0B, 0x1A19181716151413, 2704 0x2221201F1E1D1C1B, 0x2A29282726252423, }}, 2705 {{ 0x131211100F0E0D0C, 0x1B1A191817161514, 2706 0x232221201F1E1D1C, 0x2B2A292827262524, }}, 2707 {{ 0x14131211100F0E0D, 0x1C1B1A1918171615, 2708 0x24232221201F1E1D, 0x2C2B2A2928272625, }}, 2709 {{ 0x1514131211100F0E, 0x1D1C1B1A19181716, 2710 0x2524232221201F1E, 0x2D2C2B2A29282726, }}, 2711 {{ 0x161514131211100F, 0x1E1D1C1B1A191817, 2712 0x262524232221201F, 0x2E2D2C2B2A292827, }}, 2713 }; 2714 2715 bool need_32 = false, need_64 = false, need_cpuid = false; 2716 2717 switch (regs) { 2718 case GPREGS_32: 2719 case GPREGS_32_EBP_ESP: 2720 need_32 = true; 2721 break; 2722 case GPREGS_64: 2723 case GPREGS_64_R8: 2724 need_64 = true; 2725 break; 2726 case FPREGS_MM: 2727 case FPREGS_XMM: 2728 case FPREGS_YMM: 2729 need_cpuid = true; 2730 break; 2731 } 2732 2733 if (need_32) { 2734 #if defined(__x86_64__) 2735 atf_tc_skip("Test requires 32-bit mode"); 2736 #endif 2737 } 2738 if (need_64) { 2739 #if defined(__i386__) 2740 atf_tc_skip("Test requires 64-bit mode"); 2741 #endif 2742 } 2743 2744 if (need_cpuid) { 2745 /* verify whether needed instruction sets are supported here */ 2746 unsigned int eax, ebx, ecx, edx; 2747 2748 DPRINTF("Before invoking cpuid\n"); 2749 if (!__get_cpuid(1, &eax, &ebx, &ecx, &edx)) 2750 atf_tc_skip("CPUID is not supported by the CPU"); 2751 2752 DPRINTF("cpuid: ECX = %08x, EDX = %08xd\n", ecx, edx); 2753 2754 switch (regs) { 2755 case FPREGS_YMM: 2756 if (!(ecx & bit_AVX)) 2757 atf_tc_skip("AVX is not supported by the CPU"); 2758 /*FALLTHROUGH*/ 2759 case FPREGS_XMM: 2760 if (!(edx & bit_SSE)) 2761 atf_tc_skip("SSE is not supported by the CPU"); 2762 break; 2763 case FPREGS_MM: 2764 if (!(edx & bit_MMX)) 2765 atf_tc_skip("MMX is not supported by the CPU"); 2766 break; 2767 case GPREGS_32: 2768 case GPREGS_32_EBP_ESP: 2769 case GPREGS_64: 2770 case GPREGS_64_R8: 2771 __unreachable(); 2772 } 2773 } 2774 2775 DPRINTF("Before forking process PID=%d\n", getpid()); 2776 SYSCALL_REQUIRE((child = fork()) != -1); 2777 if (child == 0) { 2778 union x86_test_register vals[16] __aligned(32); 2779 2780 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 2781 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 2782 2783 DPRINTF("Before running assembly from child\n"); 2784 switch (regmode) { 2785 case TEST_GETREGS: 2786 case TEST_COREDUMP: 2787 switch (regs) { 2788 case GPREGS_32: 2789 set_gp32_regs(expected); 2790 break; 2791 case GPREGS_32_EBP_ESP: 2792 set_gp32_ebp_esp_regs(expected); 2793 break; 2794 case GPREGS_64: 2795 set_gp64_regs(expected); 2796 break; 2797 case GPREGS_64_R8: 2798 set_gp64_r8_regs(expected); 2799 break; 2800 case FPREGS_MM: 2801 set_mm_regs(expected); 2802 break; 2803 case FPREGS_XMM: 2804 set_xmm_regs(expected); 2805 break; 2806 case FPREGS_YMM: 2807 set_ymm_regs(expected); 2808 break; 2809 } 2810 break; 2811 case TEST_SETREGS: 2812 switch (regs) { 2813 case GPREGS_32: 2814 get_gp32_regs(vals); 2815 break; 2816 case GPREGS_32_EBP_ESP: 2817 get_gp32_ebp_esp_regs(vals); 2818 break; 2819 case GPREGS_64: 2820 get_gp64_regs(vals); 2821 break; 2822 case GPREGS_64_R8: 2823 get_gp64_r8_regs(vals); 2824 break; 2825 case FPREGS_MM: 2826 get_mm_regs(vals); 2827 break; 2828 case FPREGS_XMM: 2829 get_xmm_regs(vals); 2830 break; 2831 case FPREGS_YMM: 2832 get_ymm_regs(vals); 2833 break; 2834 } 2835 2836 DPRINTF("Before comparing results\n"); 2837 switch (regs) { 2838 case GPREGS_32: 2839 FORKEE_ASSERT(!memcmp(&vals[5].u32, 2840 &expected[5].u32, sizeof(vals->u32))); 2841 FORKEE_ASSERT(!memcmp(&vals[4].u32, 2842 &expected[4].u32, sizeof(vals->u32))); 2843 FORKEE_ASSERT(!memcmp(&vals[3].u32, 2844 &expected[3].u32, sizeof(vals->u32))); 2845 FORKEE_ASSERT(!memcmp(&vals[2].u32, 2846 &expected[2].u32, sizeof(vals->u32))); 2847 /*FALLTHROUGH*/ 2848 case GPREGS_32_EBP_ESP: 2849 FORKEE_ASSERT(!memcmp(&vals[1].u32, 2850 &expected[1].u32, sizeof(vals->u32))); 2851 FORKEE_ASSERT(!memcmp(&vals[0].u32, 2852 &expected[0].u32, sizeof(vals->u32))); 2853 break; 2854 case GPREGS_64: 2855 case GPREGS_64_R8: 2856 case FPREGS_MM: 2857 FORKEE_ASSERT(!memcmp(&vals[0].u64, 2858 &expected[0].u64, sizeof(vals->u64))); 2859 FORKEE_ASSERT(!memcmp(&vals[1].u64, 2860 &expected[1].u64, sizeof(vals->u64))); 2861 FORKEE_ASSERT(!memcmp(&vals[2].u64, 2862 &expected[2].u64, sizeof(vals->u64))); 2863 FORKEE_ASSERT(!memcmp(&vals[3].u64, 2864 &expected[3].u64, sizeof(vals->u64))); 2865 FORKEE_ASSERT(!memcmp(&vals[4].u64, 2866 &expected[4].u64, sizeof(vals->u64))); 2867 FORKEE_ASSERT(!memcmp(&vals[5].u64, 2868 &expected[5].u64, sizeof(vals->u64))); 2869 FORKEE_ASSERT(!memcmp(&vals[6].u64, 2870 &expected[6].u64, sizeof(vals->u64))); 2871 FORKEE_ASSERT(!memcmp(&vals[7].u64, 2872 &expected[7].u64, sizeof(vals->u64))); 2873 break; 2874 case FPREGS_XMM: 2875 FORKEE_ASSERT(!memcmp(&vals[0].xmm, 2876 &expected[0].xmm, sizeof(vals->xmm))); 2877 FORKEE_ASSERT(!memcmp(&vals[1].xmm, 2878 &expected[1].xmm, sizeof(vals->xmm))); 2879 FORKEE_ASSERT(!memcmp(&vals[2].xmm, 2880 &expected[2].xmm, sizeof(vals->xmm))); 2881 FORKEE_ASSERT(!memcmp(&vals[3].xmm, 2882 &expected[3].xmm, sizeof(vals->xmm))); 2883 FORKEE_ASSERT(!memcmp(&vals[4].xmm, 2884 &expected[4].xmm, sizeof(vals->xmm))); 2885 FORKEE_ASSERT(!memcmp(&vals[5].xmm, 2886 &expected[5].xmm, sizeof(vals->xmm))); 2887 FORKEE_ASSERT(!memcmp(&vals[6].xmm, 2888 &expected[6].xmm, sizeof(vals->xmm))); 2889 FORKEE_ASSERT(!memcmp(&vals[7].xmm, 2890 &expected[7].xmm, sizeof(vals->xmm))); 2891 #if defined(__x86_64__) 2892 FORKEE_ASSERT(!memcmp(&vals[8].xmm, 2893 &expected[8].xmm, sizeof(vals->xmm))); 2894 FORKEE_ASSERT(!memcmp(&vals[9].xmm, 2895 &expected[9].xmm, sizeof(vals->xmm))); 2896 FORKEE_ASSERT(!memcmp(&vals[10].xmm, 2897 &expected[10].xmm, sizeof(vals->xmm))); 2898 FORKEE_ASSERT(!memcmp(&vals[11].xmm, 2899 &expected[11].xmm, sizeof(vals->xmm))); 2900 FORKEE_ASSERT(!memcmp(&vals[12].xmm, 2901 &expected[12].xmm, sizeof(vals->xmm))); 2902 FORKEE_ASSERT(!memcmp(&vals[13].xmm, 2903 &expected[13].xmm, sizeof(vals->xmm))); 2904 FORKEE_ASSERT(!memcmp(&vals[14].xmm, 2905 &expected[14].xmm, sizeof(vals->xmm))); 2906 FORKEE_ASSERT(!memcmp(&vals[15].xmm, 2907 &expected[15].xmm, sizeof(vals->xmm))); 2908 #endif 2909 break; 2910 case FPREGS_YMM: 2911 FORKEE_ASSERT(!memcmp(&vals[0].ymm, 2912 &expected[0].ymm, sizeof(vals->ymm))); 2913 FORKEE_ASSERT(!memcmp(&vals[1].ymm, 2914 &expected[1].ymm, sizeof(vals->ymm))); 2915 FORKEE_ASSERT(!memcmp(&vals[2].ymm, 2916 &expected[2].ymm, sizeof(vals->ymm))); 2917 FORKEE_ASSERT(!memcmp(&vals[3].ymm, 2918 &expected[3].ymm, sizeof(vals->ymm))); 2919 FORKEE_ASSERT(!memcmp(&vals[4].ymm, 2920 &expected[4].ymm, sizeof(vals->ymm))); 2921 FORKEE_ASSERT(!memcmp(&vals[5].ymm, 2922 &expected[5].ymm, sizeof(vals->ymm))); 2923 FORKEE_ASSERT(!memcmp(&vals[6].ymm, 2924 &expected[6].ymm, sizeof(vals->ymm))); 2925 FORKEE_ASSERT(!memcmp(&vals[7].ymm, 2926 &expected[7].ymm, sizeof(vals->ymm))); 2927 #if defined(__x86_64__) 2928 FORKEE_ASSERT(!memcmp(&vals[8].ymm, 2929 &expected[8].ymm, sizeof(vals->ymm))); 2930 FORKEE_ASSERT(!memcmp(&vals[9].ymm, 2931 &expected[9].ymm, sizeof(vals->ymm))); 2932 FORKEE_ASSERT(!memcmp(&vals[10].ymm, 2933 &expected[10].ymm, sizeof(vals->ymm))); 2934 FORKEE_ASSERT(!memcmp(&vals[11].ymm, 2935 &expected[11].ymm, sizeof(vals->ymm))); 2936 FORKEE_ASSERT(!memcmp(&vals[12].ymm, 2937 &expected[12].ymm, sizeof(vals->ymm))); 2938 FORKEE_ASSERT(!memcmp(&vals[13].ymm, 2939 &expected[13].ymm, sizeof(vals->ymm))); 2940 FORKEE_ASSERT(!memcmp(&vals[14].ymm, 2941 &expected[14].ymm, sizeof(vals->ymm))); 2942 FORKEE_ASSERT(!memcmp(&vals[15].ymm, 2943 &expected[15].ymm, sizeof(vals->ymm))); 2944 #endif 2945 break; 2946 } 2947 break; 2948 } 2949 2950 DPRINTF("Before exiting of the child process\n"); 2951 _exit(exitval); 2952 } 2953 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 2954 2955 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 2956 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 2957 2958 validate_status_stopped(status, sigval); 2959 2960 if (regset == TEST_XSTATE) { 2961 switch (regs) { 2962 case FPREGS_MM: 2963 xst_flags |= XCR0_X87; 2964 break; 2965 case FPREGS_YMM: 2966 xst_flags |= XCR0_YMM_Hi128; 2967 /*FALLTHROUGH*/ 2968 case FPREGS_XMM: 2969 xst_flags |= XCR0_SSE; 2970 break; 2971 case GPREGS_32: 2972 case GPREGS_32_EBP_ESP: 2973 case GPREGS_64: 2974 case GPREGS_64_R8: 2975 __unreachable(); 2976 break; 2977 } 2978 } 2979 2980 switch (regmode) { 2981 case TEST_GETREGS: 2982 case TEST_SETREGS: 2983 switch (regset) { 2984 case TEST_GPREGS: 2985 ATF_REQUIRE(regs < FPREGS_MM); 2986 DPRINTF("Call GETREGS for the child process\n"); 2987 SYSCALL_REQUIRE(ptrace(PT_GETREGS, child, &gpr, 0) 2988 != -1); 2989 break; 2990 case TEST_XMMREGS: 2991 #if defined(__i386__) 2992 ATF_REQUIRE(regs >= FPREGS_MM && regs < FPREGS_YMM); 2993 DPRINTF("Call GETXMMREGS for the child process\n"); 2994 SYSCALL_REQUIRE(ptrace(PT_GETXMMREGS, child, &xmm, 0) 2995 != -1); 2996 fxs = &xmm.fxstate; 2997 break; 2998 #else 2999 /*FALLTHROUGH*/ 3000 #endif 3001 case TEST_FPREGS: 3002 #if defined(__x86_64__) 3003 ATF_REQUIRE(regs >= FPREGS_MM && regs < FPREGS_YMM); 3004 fxs = &fpr.fxstate; 3005 #else 3006 ATF_REQUIRE(regs >= FPREGS_MM && regs < FPREGS_XMM); 3007 #endif 3008 DPRINTF("Call GETFPREGS for the child process\n"); 3009 SYSCALL_REQUIRE(ptrace(PT_GETFPREGS, child, &fpr, 0) 3010 != -1); 3011 break; 3012 case TEST_XSTATE: 3013 ATF_REQUIRE(regs >= FPREGS_MM); 3014 iov.iov_base = &xst; 3015 iov.iov_len = sizeof(xst); 3016 3017 DPRINTF("Call GETXSTATE for the child process\n"); 3018 SYSCALL_REQUIRE(ptrace(PT_GETXSTATE, child, &iov, 0) 3019 != -1); 3020 3021 ATF_REQUIRE((xst.xs_rfbm & xst_flags) == xst_flags); 3022 switch (regmode) { 3023 case TEST_SETREGS: 3024 xst.xs_rfbm = xst_flags; 3025 xst.xs_xstate_bv = xst_flags; 3026 break; 3027 case TEST_GETREGS: 3028 ATF_REQUIRE((xst.xs_xstate_bv & xst_flags) 3029 == xst_flags); 3030 break; 3031 case TEST_COREDUMP: 3032 __unreachable(); 3033 break; 3034 } 3035 3036 fxs = &xst.xs_fxsave; 3037 break; 3038 } 3039 break; 3040 case TEST_COREDUMP: 3041 SYSCALL_REQUIRE((core_fd = mkstemp(core_path)) != -1); 3042 close(core_fd); 3043 3044 DPRINTF("Call DUMPCORE for the child process\n"); 3045 SYSCALL_REQUIRE(ptrace(PT_DUMPCORE, child, core_path, 3046 strlen(core_path)) != -1); 3047 3048 switch (regset) { 3049 case TEST_GPREGS: 3050 ATF_REQUIRE(regs < FPREGS_MM); 3051 DPRINTF("Parse core file for PT_GETREGS\n"); 3052 ATF_REQUIRE_EQ(core_find_note(core_path, 3053 "NetBSD-CORE@*", PT_GETREGS, &gpr, sizeof(gpr)), 3054 sizeof(gpr)); 3055 break; 3056 case TEST_XMMREGS: 3057 #if defined(__i386__) 3058 ATF_REQUIRE(regs >= FPREGS_MM && regs < FPREGS_YMM); 3059 unlink(core_path); 3060 atf_tc_skip("XMMREGS not supported in core dumps"); 3061 break; 3062 #else 3063 /*FALLTHROUGH*/ 3064 #endif 3065 case TEST_FPREGS: 3066 #if defined(__x86_64__) 3067 ATF_REQUIRE(regs >= FPREGS_MM && regs < FPREGS_YMM); 3068 fxs = &fpr.fxstate; 3069 #else 3070 ATF_REQUIRE(regs >= FPREGS_MM && regs < FPREGS_XMM); 3071 #endif 3072 DPRINTF("Parse core file for PT_GETFPREGS\n"); 3073 ATF_REQUIRE_EQ(core_find_note(core_path, 3074 "NetBSD-CORE@*", PT_GETFPREGS, &fpr, sizeof(fpr)), 3075 sizeof(fpr)); 3076 break; 3077 case TEST_XSTATE: 3078 ATF_REQUIRE(regs >= FPREGS_MM); 3079 DPRINTF("Parse core file for PT_GETXSTATE\n"); 3080 ATF_REQUIRE_EQ(core_find_note(core_path, 3081 "NetBSD-CORE@*", PT_GETXSTATE, &xst, sizeof(xst)), 3082 sizeof(xst)); 3083 ATF_REQUIRE((xst.xs_xstate_bv & xst_flags) 3084 == xst_flags); 3085 fxs = &xst.xs_fxsave; 3086 break; 3087 } 3088 unlink(core_path); 3089 } 3090 3091 #if defined(__x86_64__) 3092 #define MM_REG(n) fpr.fxstate.fx_87_ac[n].r.f87_mantissa 3093 #else 3094 #define MM_REG(n) fpr.fstate.s87_ac[n].f87_mantissa 3095 #endif 3096 3097 switch (regmode) { 3098 case TEST_GETREGS: 3099 case TEST_COREDUMP: 3100 switch (regs) { 3101 case GPREGS_32: 3102 #if defined(__i386__) 3103 ATF_CHECK_EQ((uint32_t)gpr.r_eax, expected[0].u32); 3104 ATF_CHECK_EQ((uint32_t)gpr.r_ebx, expected[1].u32); 3105 ATF_CHECK_EQ((uint32_t)gpr.r_ecx, expected[2].u32); 3106 ATF_CHECK_EQ((uint32_t)gpr.r_edx, expected[3].u32); 3107 ATF_CHECK_EQ((uint32_t)gpr.r_esi, expected[4].u32); 3108 ATF_CHECK_EQ((uint32_t)gpr.r_edi, expected[5].u32); 3109 #endif 3110 break; 3111 case GPREGS_32_EBP_ESP: 3112 #if defined(__i386__) 3113 ATF_CHECK_EQ((uint32_t)gpr.r_esp, expected[0].u32); 3114 ATF_CHECK_EQ((uint32_t)gpr.r_ebp, expected[1].u32); 3115 #endif 3116 break; 3117 case GPREGS_64: 3118 #if defined(__x86_64__) 3119 ATF_CHECK_EQ((uint64_t)gpr.regs[_REG_RAX], 3120 expected[0].u64); 3121 ATF_CHECK_EQ((uint64_t)gpr.regs[_REG_RBX], 3122 expected[1].u64); 3123 ATF_CHECK_EQ((uint64_t)gpr.regs[_REG_RCX], 3124 expected[2].u64); 3125 ATF_CHECK_EQ((uint64_t)gpr.regs[_REG_RDX], 3126 expected[3].u64); 3127 ATF_CHECK_EQ((uint64_t)gpr.regs[_REG_RSI], 3128 expected[4].u64); 3129 ATF_CHECK_EQ((uint64_t)gpr.regs[_REG_RDI], 3130 expected[5].u64); 3131 ATF_CHECK_EQ((uint64_t)gpr.regs[_REG_RSP], 3132 expected[6].u64); 3133 ATF_CHECK_EQ((uint64_t)gpr.regs[_REG_RBP], 3134 expected[7].u64); 3135 #endif 3136 break; 3137 case GPREGS_64_R8: 3138 #if defined(__x86_64__) 3139 ATF_CHECK_EQ((uint64_t)gpr.regs[_REG_R8], 3140 expected[0].u64); 3141 ATF_CHECK_EQ((uint64_t)gpr.regs[_REG_R9], 3142 expected[1].u64); 3143 ATF_CHECK_EQ((uint64_t)gpr.regs[_REG_R10], 3144 expected[2].u64); 3145 ATF_CHECK_EQ((uint64_t)gpr.regs[_REG_R11], 3146 expected[3].u64); 3147 ATF_CHECK_EQ((uint64_t)gpr.regs[_REG_R12], 3148 expected[4].u64); 3149 ATF_CHECK_EQ((uint64_t)gpr.regs[_REG_R13], 3150 expected[5].u64); 3151 ATF_CHECK_EQ((uint64_t)gpr.regs[_REG_R14], 3152 expected[6].u64); 3153 ATF_CHECK_EQ((uint64_t)gpr.regs[_REG_R15], 3154 expected[7].u64); 3155 #endif 3156 break; 3157 case FPREGS_MM: 3158 if (regset == TEST_FPREGS) { 3159 ATF_CHECK_EQ(MM_REG(0), expected[0].u64); 3160 ATF_CHECK_EQ(MM_REG(1), expected[1].u64); 3161 ATF_CHECK_EQ(MM_REG(2), expected[2].u64); 3162 ATF_CHECK_EQ(MM_REG(3), expected[3].u64); 3163 ATF_CHECK_EQ(MM_REG(4), expected[4].u64); 3164 ATF_CHECK_EQ(MM_REG(5), expected[5].u64); 3165 ATF_CHECK_EQ(MM_REG(6), expected[6].u64); 3166 ATF_CHECK_EQ(MM_REG(7), expected[7].u64); 3167 } else { 3168 ATF_CHECK_EQ(fxs->fx_87_ac[0].r.f87_mantissa, 3169 expected[0].u64); 3170 ATF_CHECK_EQ(fxs->fx_87_ac[1].r.f87_mantissa, 3171 expected[1].u64); 3172 ATF_CHECK_EQ(fxs->fx_87_ac[2].r.f87_mantissa, 3173 expected[2].u64); 3174 ATF_CHECK_EQ(fxs->fx_87_ac[3].r.f87_mantissa, 3175 expected[3].u64); 3176 ATF_CHECK_EQ(fxs->fx_87_ac[4].r.f87_mantissa, 3177 expected[4].u64); 3178 ATF_CHECK_EQ(fxs->fx_87_ac[5].r.f87_mantissa, 3179 expected[5].u64); 3180 ATF_CHECK_EQ(fxs->fx_87_ac[6].r.f87_mantissa, 3181 expected[6].u64); 3182 ATF_CHECK_EQ(fxs->fx_87_ac[7].r.f87_mantissa, 3183 expected[7].u64); 3184 } 3185 break; 3186 case FPREGS_YMM: 3187 ATF_CHECK(!memcmp(&xst.xs_ymm_hi128.xs_ymm[0], 3188 &expected[0].ymm.c, sizeof(expected->ymm)/2)); 3189 ATF_CHECK(!memcmp(&xst.xs_ymm_hi128.xs_ymm[1], 3190 &expected[1].ymm.c, sizeof(expected->ymm)/2)); 3191 ATF_CHECK(!memcmp(&xst.xs_ymm_hi128.xs_ymm[2], 3192 &expected[2].ymm.c, sizeof(expected->ymm)/2)); 3193 ATF_CHECK(!memcmp(&xst.xs_ymm_hi128.xs_ymm[3], 3194 &expected[3].ymm.c, sizeof(expected->ymm)/2)); 3195 ATF_CHECK(!memcmp(&xst.xs_ymm_hi128.xs_ymm[4], 3196 &expected[4].ymm.c, sizeof(expected->ymm)/2)); 3197 ATF_CHECK(!memcmp(&xst.xs_ymm_hi128.xs_ymm[5], 3198 &expected[5].ymm.c, sizeof(expected->ymm)/2)); 3199 ATF_CHECK(!memcmp(&xst.xs_ymm_hi128.xs_ymm[6], 3200 &expected[6].ymm.c, sizeof(expected->ymm)/2)); 3201 ATF_CHECK(!memcmp(&xst.xs_ymm_hi128.xs_ymm[7], 3202 &expected[7].ymm.c, sizeof(expected->ymm)/2)); 3203 #if defined(__x86_64__) 3204 ATF_CHECK(!memcmp(&xst.xs_ymm_hi128.xs_ymm[8], 3205 &expected[8].ymm.c, sizeof(expected->ymm)/2)); 3206 ATF_CHECK(!memcmp(&xst.xs_ymm_hi128.xs_ymm[9], 3207 &expected[9].ymm.c, sizeof(expected->ymm)/2)); 3208 ATF_CHECK(!memcmp(&xst.xs_ymm_hi128.xs_ymm[10], 3209 &expected[10].ymm.c, sizeof(expected->ymm)/2)); 3210 ATF_CHECK(!memcmp(&xst.xs_ymm_hi128.xs_ymm[11], 3211 &expected[11].ymm.c, sizeof(expected->ymm)/2)); 3212 ATF_CHECK(!memcmp(&xst.xs_ymm_hi128.xs_ymm[12], 3213 &expected[12].ymm.c, sizeof(expected->ymm)/2)); 3214 ATF_CHECK(!memcmp(&xst.xs_ymm_hi128.xs_ymm[13], 3215 &expected[13].ymm.c, sizeof(expected->ymm)/2)); 3216 ATF_CHECK(!memcmp(&xst.xs_ymm_hi128.xs_ymm[14], 3217 &expected[14].ymm.c, sizeof(expected->ymm)/2)); 3218 ATF_CHECK(!memcmp(&xst.xs_ymm_hi128.xs_ymm[15], 3219 &expected[15].ymm.c, sizeof(expected->ymm)/2)); 3220 #endif 3221 /*FALLTHROUGH*/ 3222 case FPREGS_XMM: 3223 ATF_CHECK(!memcmp(&fxs->fx_xmm[0], &expected[0].ymm.a, 3224 sizeof(expected->ymm)/2)); 3225 ATF_CHECK(!memcmp(&fxs->fx_xmm[1], &expected[1].ymm.a, 3226 sizeof(expected->ymm)/2)); 3227 ATF_CHECK(!memcmp(&fxs->fx_xmm[2], &expected[2].ymm.a, 3228 sizeof(expected->ymm)/2)); 3229 ATF_CHECK(!memcmp(&fxs->fx_xmm[3], &expected[3].ymm.a, 3230 sizeof(expected->ymm)/2)); 3231 ATF_CHECK(!memcmp(&fxs->fx_xmm[4], &expected[4].ymm.a, 3232 sizeof(expected->ymm)/2)); 3233 ATF_CHECK(!memcmp(&fxs->fx_xmm[5], &expected[5].ymm.a, 3234 sizeof(expected->ymm)/2)); 3235 ATF_CHECK(!memcmp(&fxs->fx_xmm[6], &expected[6].ymm.a, 3236 sizeof(expected->ymm)/2)); 3237 ATF_CHECK(!memcmp(&fxs->fx_xmm[7], &expected[7].ymm.a, 3238 sizeof(expected->ymm)/2)); 3239 #if defined(__x86_64__) 3240 ATF_CHECK(!memcmp(&fxs->fx_xmm[8], &expected[8].ymm.a, 3241 sizeof(expected->ymm)/2)); 3242 ATF_CHECK(!memcmp(&fxs->fx_xmm[9], &expected[9].ymm.a, 3243 sizeof(expected->ymm)/2)); 3244 ATF_CHECK(!memcmp(&fxs->fx_xmm[10], &expected[10].ymm.a, 3245 sizeof(expected->ymm)/2)); 3246 ATF_CHECK(!memcmp(&fxs->fx_xmm[11], &expected[11].ymm.a, 3247 sizeof(expected->ymm)/2)); 3248 ATF_CHECK(!memcmp(&fxs->fx_xmm[12], &expected[12].ymm.a, 3249 sizeof(expected->ymm)/2)); 3250 ATF_CHECK(!memcmp(&fxs->fx_xmm[13], &expected[13].ymm.a, 3251 sizeof(expected->ymm)/2)); 3252 ATF_CHECK(!memcmp(&fxs->fx_xmm[14], &expected[14].ymm.a, 3253 sizeof(expected->ymm)/2)); 3254 ATF_CHECK(!memcmp(&fxs->fx_xmm[15], &expected[15].ymm.a, 3255 sizeof(expected->ymm)/2)); 3256 #endif 3257 break; 3258 } 3259 break; 3260 case TEST_SETREGS: 3261 switch (regs) { 3262 case GPREGS_32: 3263 #if defined(__i386__) 3264 gpr.r_eax = expected[0].u32; 3265 gpr.r_ebx = expected[1].u32; 3266 gpr.r_ecx = expected[2].u32; 3267 gpr.r_edx = expected[3].u32; 3268 gpr.r_esi = expected[4].u32; 3269 gpr.r_edi = expected[5].u32; 3270 #endif 3271 break; 3272 case GPREGS_32_EBP_ESP: 3273 #if defined(__i386__) 3274 gpr.r_esp = expected[0].u32; 3275 gpr.r_ebp = expected[1].u32; 3276 #endif 3277 break; 3278 case GPREGS_64: 3279 #if defined(__x86_64__) 3280 gpr.regs[_REG_RAX] = expected[0].u64; 3281 gpr.regs[_REG_RBX] = expected[1].u64; 3282 gpr.regs[_REG_RCX] = expected[2].u64; 3283 gpr.regs[_REG_RDX] = expected[3].u64; 3284 gpr.regs[_REG_RSI] = expected[4].u64; 3285 gpr.regs[_REG_RDI] = expected[5].u64; 3286 gpr.regs[_REG_RSP] = expected[6].u64; 3287 gpr.regs[_REG_RBP] = expected[7].u64; 3288 #endif 3289 break; 3290 case GPREGS_64_R8: 3291 #if defined(__x86_64__) 3292 gpr.regs[_REG_R8] = expected[0].u64; 3293 gpr.regs[_REG_R9] = expected[1].u64; 3294 gpr.regs[_REG_R10] = expected[2].u64; 3295 gpr.regs[_REG_R11] = expected[3].u64; 3296 gpr.regs[_REG_R12] = expected[4].u64; 3297 gpr.regs[_REG_R13] = expected[5].u64; 3298 gpr.regs[_REG_R14] = expected[6].u64; 3299 gpr.regs[_REG_R15] = expected[7].u64; 3300 #endif 3301 break; 3302 case FPREGS_MM: 3303 if (regset == TEST_FPREGS) { 3304 MM_REG(0) = expected[0].u64; 3305 MM_REG(1) = expected[1].u64; 3306 MM_REG(2) = expected[2].u64; 3307 MM_REG(3) = expected[3].u64; 3308 MM_REG(4) = expected[4].u64; 3309 MM_REG(5) = expected[5].u64; 3310 MM_REG(6) = expected[6].u64; 3311 MM_REG(7) = expected[7].u64; 3312 } else { 3313 fxs->fx_87_ac[0].r.f87_mantissa = 3314 expected[0].u64; 3315 fxs->fx_87_ac[1].r.f87_mantissa = 3316 expected[1].u64; 3317 fxs->fx_87_ac[2].r.f87_mantissa = 3318 expected[2].u64; 3319 fxs->fx_87_ac[3].r.f87_mantissa = 3320 expected[3].u64; 3321 fxs->fx_87_ac[4].r.f87_mantissa = 3322 expected[4].u64; 3323 fxs->fx_87_ac[5].r.f87_mantissa = 3324 expected[5].u64; 3325 fxs->fx_87_ac[6].r.f87_mantissa = 3326 expected[6].u64; 3327 fxs->fx_87_ac[7].r.f87_mantissa = 3328 expected[7].u64; 3329 } 3330 break; 3331 case FPREGS_YMM: 3332 memcpy(&xst.xs_ymm_hi128.xs_ymm[0], 3333 &expected[0].ymm.c, sizeof(expected->ymm)/2); 3334 memcpy(&xst.xs_ymm_hi128.xs_ymm[1], 3335 &expected[1].ymm.c, sizeof(expected->ymm)/2); 3336 memcpy(&xst.xs_ymm_hi128.xs_ymm[2], 3337 &expected[2].ymm.c, sizeof(expected->ymm)/2); 3338 memcpy(&xst.xs_ymm_hi128.xs_ymm[3], 3339 &expected[3].ymm.c, sizeof(expected->ymm)/2); 3340 memcpy(&xst.xs_ymm_hi128.xs_ymm[4], 3341 &expected[4].ymm.c, sizeof(expected->ymm)/2); 3342 memcpy(&xst.xs_ymm_hi128.xs_ymm[5], 3343 &expected[5].ymm.c, sizeof(expected->ymm)/2); 3344 memcpy(&xst.xs_ymm_hi128.xs_ymm[6], 3345 &expected[6].ymm.c, sizeof(expected->ymm)/2); 3346 memcpy(&xst.xs_ymm_hi128.xs_ymm[7], 3347 &expected[7].ymm.c, sizeof(expected->ymm)/2); 3348 #if defined(__x86_64__) 3349 memcpy(&xst.xs_ymm_hi128.xs_ymm[8], 3350 &expected[8].ymm.c, sizeof(expected->ymm)/2); 3351 memcpy(&xst.xs_ymm_hi128.xs_ymm[9], 3352 &expected[9].ymm.c, sizeof(expected->ymm)/2); 3353 memcpy(&xst.xs_ymm_hi128.xs_ymm[10], 3354 &expected[10].ymm.c, sizeof(expected->ymm)/2); 3355 memcpy(&xst.xs_ymm_hi128.xs_ymm[11], 3356 &expected[11].ymm.c, sizeof(expected->ymm)/2); 3357 memcpy(&xst.xs_ymm_hi128.xs_ymm[12], 3358 &expected[12].ymm.c, sizeof(expected->ymm)/2); 3359 memcpy(&xst.xs_ymm_hi128.xs_ymm[13], 3360 &expected[13].ymm.c, sizeof(expected->ymm)/2); 3361 memcpy(&xst.xs_ymm_hi128.xs_ymm[14], 3362 &expected[14].ymm.c, sizeof(expected->ymm)/2); 3363 memcpy(&xst.xs_ymm_hi128.xs_ymm[15], 3364 &expected[15].ymm.c, sizeof(expected->ymm)/2); 3365 #endif 3366 /*FALLTHROUGH*/ 3367 case FPREGS_XMM: 3368 memcpy(&fxs->fx_xmm[0], &expected[0].ymm.a, 3369 sizeof(expected->ymm)/2); 3370 memcpy(&fxs->fx_xmm[1], &expected[1].ymm.a, 3371 sizeof(expected->ymm)/2); 3372 memcpy(&fxs->fx_xmm[2], &expected[2].ymm.a, 3373 sizeof(expected->ymm)/2); 3374 memcpy(&fxs->fx_xmm[3], &expected[3].ymm.a, 3375 sizeof(expected->ymm)/2); 3376 memcpy(&fxs->fx_xmm[4], &expected[4].ymm.a, 3377 sizeof(expected->ymm)/2); 3378 memcpy(&fxs->fx_xmm[5], &expected[5].ymm.a, 3379 sizeof(expected->ymm)/2); 3380 memcpy(&fxs->fx_xmm[6], &expected[6].ymm.a, 3381 sizeof(expected->ymm)/2); 3382 memcpy(&fxs->fx_xmm[7], &expected[7].ymm.a, 3383 sizeof(expected->ymm)/2); 3384 #if defined(__x86_64__) 3385 memcpy(&fxs->fx_xmm[8], &expected[8].ymm.a, 3386 sizeof(expected->ymm)/2); 3387 memcpy(&fxs->fx_xmm[9], &expected[9].ymm.a, 3388 sizeof(expected->ymm)/2); 3389 memcpy(&fxs->fx_xmm[10], &expected[10].ymm.a, 3390 sizeof(expected->ymm)/2); 3391 memcpy(&fxs->fx_xmm[11], &expected[11].ymm.a, 3392 sizeof(expected->ymm)/2); 3393 memcpy(&fxs->fx_xmm[12], &expected[12].ymm.a, 3394 sizeof(expected->ymm)/2); 3395 memcpy(&fxs->fx_xmm[13], &expected[13].ymm.a, 3396 sizeof(expected->ymm)/2); 3397 memcpy(&fxs->fx_xmm[14], &expected[14].ymm.a, 3398 sizeof(expected->ymm)/2); 3399 memcpy(&fxs->fx_xmm[15], &expected[15].ymm.a, 3400 sizeof(expected->ymm)/2); 3401 #endif 3402 break; 3403 } 3404 3405 switch (regset) { 3406 case TEST_GPREGS: 3407 DPRINTF("Call SETREGS for the child process\n"); 3408 SYSCALL_REQUIRE(ptrace(PT_SETREGS, child, &gpr, 0) 3409 != -1); 3410 break; 3411 case TEST_XMMREGS: 3412 #if defined(__i386__) 3413 DPRINTF("Call SETXMMREGS for the child process\n"); 3414 SYSCALL_REQUIRE(ptrace(PT_SETXMMREGS, child, &xmm, 0) 3415 != -1); 3416 break; 3417 #else 3418 /*FALLTHROUGH*/ 3419 #endif 3420 case TEST_FPREGS: 3421 DPRINTF("Call SETFPREGS for the child process\n"); 3422 SYSCALL_REQUIRE(ptrace(PT_SETFPREGS, child, &fpr, 0) 3423 != -1); 3424 break; 3425 case TEST_XSTATE: 3426 DPRINTF("Call SETXSTATE for the child process\n"); 3427 SYSCALL_REQUIRE(ptrace(PT_SETXSTATE, child, &iov, 0) 3428 != -1); 3429 break; 3430 } 3431 break; 3432 } 3433 3434 #undef MM_REG 3435 3436 DPRINTF("Before resuming the child process where it left off and " 3437 "without signal to be sent\n"); 3438 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 3439 3440 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 3441 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 3442 3443 validate_status_exited(status, exitval); 3444 3445 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 3446 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 3447 } 3448 3449 #define X86_REGISTER_TEST(test, regset, regs, regmode, descr) \ 3450 ATF_TC(test); \ 3451 ATF_TC_HEAD(test, tc) \ 3452 { \ 3453 atf_tc_set_md_var(tc, "descr", descr); \ 3454 } \ 3455 \ 3456 ATF_TC_BODY(test, tc) \ 3457 { \ 3458 x86_register_test(regset, regs, regmode); \ 3459 } 3460 3461 X86_REGISTER_TEST(x86_gpregs32_read, TEST_GPREGS, GPREGS_32, TEST_GETREGS, 3462 "Test reading basic 32-bit gp registers from debugged program " 3463 "via PT_GETREGS."); 3464 X86_REGISTER_TEST(x86_gpregs32_write, TEST_GPREGS, GPREGS_32, TEST_SETREGS, 3465 "Test writing basic 32-bit gp registers into debugged program " 3466 "via PT_SETREGS."); 3467 X86_REGISTER_TEST(x86_gpregs32_core, TEST_GPREGS, GPREGS_32, TEST_COREDUMP, 3468 "Test reading basic 32-bit gp registers from core dump."); 3469 X86_REGISTER_TEST(x86_gpregs32_ebp_esp_read, TEST_GPREGS, GPREGS_32_EBP_ESP, 3470 TEST_GETREGS, "Test reading ebp & esp registers from debugged program " 3471 "via PT_GETREGS."); 3472 X86_REGISTER_TEST(x86_gpregs32_ebp_esp_write, TEST_GPREGS, GPREGS_32_EBP_ESP, 3473 TEST_SETREGS, "Test writing ebp & esp registers into debugged program " 3474 "via PT_SETREGS."); 3475 X86_REGISTER_TEST(x86_gpregs32_ebp_esp_core, TEST_GPREGS, GPREGS_32_EBP_ESP, 3476 TEST_COREDUMP, "Test reading ebp & esp registers from core dump."); 3477 3478 X86_REGISTER_TEST(x86_gpregs64_read, TEST_GPREGS, GPREGS_64, TEST_GETREGS, 3479 "Test reading basic 64-bit gp registers from debugged program " 3480 "via PT_GETREGS."); 3481 X86_REGISTER_TEST(x86_gpregs64_write, TEST_GPREGS, GPREGS_64, TEST_SETREGS, 3482 "Test writing basic 64-bit gp registers into debugged program " 3483 "via PT_SETREGS."); 3484 X86_REGISTER_TEST(x86_gpregs64_core, TEST_GPREGS, GPREGS_64, TEST_COREDUMP, 3485 "Test reading basic 64-bit gp registers from core dump."); 3486 X86_REGISTER_TEST(x86_gpregs64_r8_read, TEST_GPREGS, GPREGS_64_R8, TEST_GETREGS, 3487 "Test reading r8..r15 registers from debugged program via PT_GETREGS."); 3488 X86_REGISTER_TEST(x86_gpregs64_r8_write, TEST_GPREGS, GPREGS_64_R8, 3489 TEST_SETREGS, "Test writing r8..r15 registers into debugged program " 3490 "via PT_SETREGS."); 3491 X86_REGISTER_TEST(x86_gpregs64_r8_core, TEST_GPREGS, GPREGS_64_R8, 3492 TEST_COREDUMP, "Test reading r8..r15 registers from core dump."); 3493 3494 X86_REGISTER_TEST(x86_fpregs_mm_read, TEST_FPREGS, FPREGS_MM, TEST_GETREGS, 3495 "Test reading mm0..mm7 registers from debugged program " 3496 "via PT_GETFPREGS."); 3497 X86_REGISTER_TEST(x86_fpregs_mm_write, TEST_FPREGS, FPREGS_MM, TEST_SETREGS, 3498 "Test writing mm0..mm7 registers into debugged program " 3499 "via PT_SETFPREGS."); 3500 X86_REGISTER_TEST(x86_fpregs_mm_core, TEST_FPREGS, FPREGS_MM, TEST_COREDUMP, 3501 "Test reading mm0..mm7 registers from coredump."); 3502 X86_REGISTER_TEST(x86_fpregs_xmm_read, TEST_XMMREGS, FPREGS_XMM, TEST_GETREGS, 3503 "Test reading xmm0..xmm15 (..xmm7 on i386) from debugged program " 3504 "via PT_GETFPREGS (PT_GETXMMREGS on i386)."); 3505 X86_REGISTER_TEST(x86_fpregs_xmm_write, TEST_XMMREGS, FPREGS_XMM, TEST_SETREGS, 3506 "Test writing xmm0..xmm15 (..xmm7 on i386) into debugged program " 3507 "via PT_SETFPREGS (PT_SETXMMREGS on i386)."); 3508 X86_REGISTER_TEST(x86_fpregs_xmm_core, TEST_XMMREGS, FPREGS_XMM, TEST_COREDUMP, 3509 "Test reading xmm0..xmm15 (..xmm7 on i386) from coredump."); 3510 3511 X86_REGISTER_TEST(x86_xstate_mm_read, TEST_XSTATE, FPREGS_MM, TEST_GETREGS, 3512 "Test reading mm0..mm7 registers from debugged program " 3513 "via PT_GETXSTATE."); 3514 X86_REGISTER_TEST(x86_xstate_mm_write, TEST_XSTATE, FPREGS_MM, TEST_SETREGS, 3515 "Test writing mm0..mm7 registers into debugged program " 3516 "via PT_SETXSTATE."); 3517 X86_REGISTER_TEST(x86_xstate_mm_core, TEST_XSTATE, FPREGS_MM, TEST_COREDUMP, 3518 "Test reading mm0..mm7 registers from core dump via XSTATE note."); 3519 X86_REGISTER_TEST(x86_xstate_xmm_read, TEST_XSTATE, FPREGS_XMM, TEST_GETREGS, 3520 "Test reading xmm0..xmm15 (..xmm7 on i386) from debugged program " 3521 "via PT_GETXSTATE."); 3522 X86_REGISTER_TEST(x86_xstate_xmm_write, TEST_XSTATE, FPREGS_XMM, TEST_SETREGS, 3523 "Test writing xmm0..xmm15 (..xmm7 on i386) into debugged program " 3524 "via PT_SETXSTATE."); 3525 X86_REGISTER_TEST(x86_xstate_xmm_core, TEST_XSTATE, FPREGS_XMM, TEST_COREDUMP, 3526 "Test reading xmm0..xmm15 (..xmm7 on i386) from coredump via XSTATE note."); 3527 X86_REGISTER_TEST(x86_xstate_ymm_read, TEST_XSTATE, FPREGS_YMM, TEST_GETREGS, 3528 "Test reading ymm0..ymm15 (..ymm7 on i386) from debugged program " 3529 "via PT_GETXSTATE."); 3530 X86_REGISTER_TEST(x86_xstate_ymm_write, TEST_XSTATE, FPREGS_YMM, TEST_SETREGS, 3531 "Test writing ymm0..ymm15 (..ymm7 on i386) into debugged program " 3532 "via PT_SETXSTATE."); 3533 X86_REGISTER_TEST(x86_xstate_ymm_core, TEST_XSTATE, FPREGS_YMM, TEST_COREDUMP, 3534 "Test reading ymm0..ymm15 (..ymm7 on i386) from coredump via XSTATE note."); 3535 3536 /// ---------------------------------------------------------------------------- 3537 3538 #if defined(TWAIT_HAVE_STATUS) 3539 3540 static void 3541 thread_concurrent_lwp_setup(pid_t child, lwpid_t lwpid) 3542 { 3543 struct dbreg r; 3544 union u dr7; 3545 3546 /* We need to set debug registers for every child */ 3547 DPRINTF("Call GETDBREGS for LWP %d\n", lwpid); 3548 SYSCALL_REQUIRE(ptrace(PT_GETDBREGS, child, &r, lwpid) != -1); 3549 3550 dr7.raw = 0; 3551 /* should be set to 1 according to Intel manual, 17.2 */ 3552 dr7.bits.reserved_10 = 1; 3553 dr7.bits.local_exact_breakpt = 1; 3554 dr7.bits.global_exact_breakpt = 1; 3555 /* use DR0 for breakpoints */ 3556 dr7.bits.global_dr0_breakpoint = 1; 3557 dr7.bits.condition_dr0 = 0; /* exec */ 3558 dr7.bits.len_dr0 = 0; 3559 /* use DR1 for watchpoints */ 3560 dr7.bits.global_dr1_breakpoint = 1; 3561 dr7.bits.condition_dr1 = 1; /* write */ 3562 dr7.bits.len_dr1 = 3; /* 4 bytes */ 3563 r.dr[7] = dr7.raw; 3564 r.dr[0] = (long)(intptr_t)check_happy; 3565 r.dr[1] = (long)(intptr_t)&thread_concurrent_watchpoint_var; 3566 DPRINTF("dr0=%" PRIxREGISTER "\n", r.dr[0]); 3567 DPRINTF("dr1=%" PRIxREGISTER "\n", r.dr[1]); 3568 DPRINTF("dr7=%" PRIxREGISTER "\n", r.dr[7]); 3569 3570 DPRINTF("Call SETDBREGS for LWP %d\n", lwpid); 3571 SYSCALL_REQUIRE(ptrace(PT_SETDBREGS, child, &r, lwpid) != -1); 3572 } 3573 3574 static enum thread_concurrent_sigtrap_event 3575 thread_concurrent_handle_sigtrap(pid_t child, ptrace_siginfo_t *info) 3576 { 3577 enum thread_concurrent_sigtrap_event ret = TCSE_UNKNOWN; 3578 struct dbreg r; 3579 union u dr7; 3580 3581 ATF_CHECK_EQ_MSG(info->psi_siginfo.si_code, TRAP_DBREG, 3582 "lwp=%d, expected TRAP_DBREG (%d), got %d", info->psi_lwpid, 3583 TRAP_DBREG, info->psi_siginfo.si_code); 3584 3585 DPRINTF("Call GETDBREGS for LWP %d\n", info->psi_lwpid); 3586 SYSCALL_REQUIRE(ptrace(PT_GETDBREGS, child, &r, info->psi_lwpid) != -1); 3587 DPRINTF("dr6=%" PRIxREGISTER ", dr7=%" PRIxREGISTER "\n", 3588 r.dr[6], r.dr[7]); 3589 3590 ATF_CHECK_MSG(r.dr[6] & 3, "lwp=%d, got DR6=%" PRIxREGISTER, 3591 info->psi_lwpid, r.dr[6]); 3592 3593 /* Handle only one event at a time, we should get 3594 * a separate SIGTRAP for the other one. 3595 */ 3596 if (r.dr[6] & 1) { 3597 r.dr[6] &= ~1; 3598 3599 /* We need to disable the breakpoint to move 3600 * past it. 3601 * 3602 * TODO: single-step and reenable it? 3603 */ 3604 dr7.raw = r.dr[7]; 3605 dr7.bits.global_dr0_breakpoint = 0; 3606 r.dr[7] = dr7.raw; 3607 3608 ret = TCSE_BREAKPOINT; 3609 } else if (r.dr[6] & 2) { 3610 r.dr[6] &= ~2; 3611 ret = TCSE_WATCHPOINT; 3612 } 3613 3614 DPRINTF("Call SETDBREGS for LWP %d\n", info->psi_lwpid); 3615 DPRINTF("dr6=%" PRIxREGISTER ", dr7=%" PRIxREGISTER "\n", 3616 r.dr[6], r.dr[7]); 3617 SYSCALL_REQUIRE(ptrace(PT_SETDBREGS, child, &r, info->psi_lwpid) != -1); 3618 3619 return ret; 3620 } 3621 3622 #endif /*defined(TWAIT_HAVE_STATUS)*/ 3623 3624 /// ---------------------------------------------------------------------------- 3625 3626 #define ATF_TP_ADD_TCS_PTRACE_WAIT_X86() \ 3627 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_print); \ 3628 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_preserve_dr0); \ 3629 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_preserve_dr1); \ 3630 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_preserve_dr2); \ 3631 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_preserve_dr3); \ 3632 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_preserve_dr0_yield); \ 3633 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_preserve_dr1_yield); \ 3634 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_preserve_dr2_yield); \ 3635 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_preserve_dr3_yield); \ 3636 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_preserve_dr0_continued); \ 3637 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_preserve_dr1_continued); \ 3638 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_preserve_dr2_continued); \ 3639 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_preserve_dr3_continued); \ 3640 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr0_trap_variable_writeonly_byte); \ 3641 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr1_trap_variable_writeonly_byte); \ 3642 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr2_trap_variable_writeonly_byte); \ 3643 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr3_trap_variable_writeonly_byte); \ 3644 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr0_trap_variable_writeonly_2bytes); \ 3645 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr1_trap_variable_writeonly_2bytes); \ 3646 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr2_trap_variable_writeonly_2bytes); \ 3647 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr3_trap_variable_writeonly_2bytes); \ 3648 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr0_trap_variable_writeonly_4bytes); \ 3649 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr1_trap_variable_writeonly_4bytes); \ 3650 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr2_trap_variable_writeonly_4bytes); \ 3651 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr3_trap_variable_writeonly_4bytes); \ 3652 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr0_trap_variable_readwrite_write_byte); \ 3653 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr1_trap_variable_readwrite_write_byte); \ 3654 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr2_trap_variable_readwrite_write_byte); \ 3655 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr3_trap_variable_readwrite_write_byte); \ 3656 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr0_trap_variable_readwrite_write_2bytes); \ 3657 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr1_trap_variable_readwrite_write_2bytes); \ 3658 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr2_trap_variable_readwrite_write_2bytes); \ 3659 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr3_trap_variable_readwrite_write_2bytes); \ 3660 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr0_trap_variable_readwrite_write_4bytes); \ 3661 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr1_trap_variable_readwrite_write_4bytes); \ 3662 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr2_trap_variable_readwrite_write_4bytes); \ 3663 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr3_trap_variable_readwrite_write_4bytes); \ 3664 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr0_trap_variable_readwrite_read_byte); \ 3665 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr1_trap_variable_readwrite_read_byte); \ 3666 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr2_trap_variable_readwrite_read_byte); \ 3667 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr3_trap_variable_readwrite_read_byte); \ 3668 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr0_trap_variable_readwrite_read_2bytes); \ 3669 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr1_trap_variable_readwrite_read_2bytes); \ 3670 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr2_trap_variable_readwrite_read_2bytes); \ 3671 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr3_trap_variable_readwrite_read_2bytes); \ 3672 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr0_trap_variable_readwrite_read_4bytes); \ 3673 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr1_trap_variable_readwrite_read_4bytes); \ 3674 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr2_trap_variable_readwrite_read_4bytes); \ 3675 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr3_trap_variable_readwrite_read_4bytes); \ 3676 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr0_trap_code); \ 3677 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr1_trap_code); \ 3678 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr2_trap_code); \ 3679 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr3_trap_code); \ 3680 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr0_dont_inherit_lwp); \ 3681 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr1_dont_inherit_lwp); \ 3682 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr2_dont_inherit_lwp); \ 3683 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr3_dont_inherit_lwp); \ 3684 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr0_dont_inherit_execve); \ 3685 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr1_dont_inherit_execve); \ 3686 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr2_dont_inherit_execve); \ 3687 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr3_dont_inherit_execve); \ 3688 ATF_TP_ADD_TC_HAVE_DBREGS(tp, x86_cve_2018_8897); \ 3689 ATF_TP_ADD_TC(tp, x86_gpregs32_read); \ 3690 ATF_TP_ADD_TC(tp, x86_gpregs32_write); \ 3691 ATF_TP_ADD_TC(tp, x86_gpregs32_core); \ 3692 ATF_TP_ADD_TC(tp, x86_gpregs32_ebp_esp_read); \ 3693 ATF_TP_ADD_TC(tp, x86_gpregs32_ebp_esp_write); \ 3694 ATF_TP_ADD_TC(tp, x86_gpregs32_ebp_esp_core); \ 3695 ATF_TP_ADD_TC(tp, x86_gpregs64_read); \ 3696 ATF_TP_ADD_TC(tp, x86_gpregs64_write); \ 3697 ATF_TP_ADD_TC(tp, x86_gpregs64_core); \ 3698 ATF_TP_ADD_TC(tp, x86_gpregs64_r8_read); \ 3699 ATF_TP_ADD_TC(tp, x86_gpregs64_r8_write); \ 3700 ATF_TP_ADD_TC(tp, x86_gpregs64_r8_core); \ 3701 ATF_TP_ADD_TC(tp, x86_fpregs_mm_read); \ 3702 ATF_TP_ADD_TC(tp, x86_fpregs_mm_write); \ 3703 ATF_TP_ADD_TC(tp, x86_fpregs_mm_core); \ 3704 ATF_TP_ADD_TC(tp, x86_fpregs_xmm_read); \ 3705 ATF_TP_ADD_TC(tp, x86_fpregs_xmm_write); \ 3706 ATF_TP_ADD_TC(tp, x86_fpregs_xmm_core); \ 3707 ATF_TP_ADD_TC(tp, x86_xstate_mm_read); \ 3708 ATF_TP_ADD_TC(tp, x86_xstate_mm_write); \ 3709 ATF_TP_ADD_TC(tp, x86_xstate_mm_core); \ 3710 ATF_TP_ADD_TC(tp, x86_xstate_xmm_read); \ 3711 ATF_TP_ADD_TC(tp, x86_xstate_xmm_write); \ 3712 ATF_TP_ADD_TC(tp, x86_xstate_xmm_core); \ 3713 ATF_TP_ADD_TC(tp, x86_xstate_ymm_read); \ 3714 ATF_TP_ADD_TC(tp, x86_xstate_ymm_write); \ 3715 ATF_TP_ADD_TC(tp, x86_xstate_ymm_core); 3716 #else 3717 #define ATF_TP_ADD_TCS_PTRACE_WAIT_X86() 3718 #endif 3719