1 /* $NetBSD: t_ptrace_x86_wait.h,v 1.21 2020/02/13 15:27:25 mgorny 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 volatile lwpid_t x86_the_lwp_id = 0; 1621 1622 static void __used 1623 x86_lwp_main_func(void *arg) 1624 { 1625 x86_the_lwp_id = _lwp_self(); 1626 _lwp_exit(); 1627 } 1628 1629 static void 1630 dbregs_dont_inherit_lwp(int reg) 1631 { 1632 const int exitval = 5; 1633 const int sigval = SIGSTOP; 1634 pid_t child, wpid; 1635 #if defined(TWAIT_HAVE_STATUS) 1636 int status; 1637 #endif 1638 ptrace_state_t state; 1639 const int slen = sizeof(state); 1640 ptrace_event_t event; 1641 const int elen = sizeof(event); 1642 ucontext_t uc; 1643 lwpid_t lid; 1644 static const size_t ssize = 16*1024; 1645 void *stack; 1646 size_t i; 1647 struct dbreg r1; 1648 struct dbreg r2; 1649 1650 if (!can_we_set_dbregs()) { 1651 atf_tc_skip("Either run this test as root or set sysctl(3) " 1652 "security.models.extensions.user_set_dbregs to 1"); 1653 } 1654 1655 DPRINTF("Before forking process PID=%d\n", getpid()); 1656 SYSCALL_REQUIRE((child = fork()) != -1); 1657 if (child == 0) { 1658 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 1659 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 1660 1661 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 1662 FORKEE_ASSERT(raise(sigval) == 0); 1663 1664 DPRINTF("Before allocating memory for stack in child\n"); 1665 FORKEE_ASSERT((stack = malloc(ssize)) != NULL); 1666 1667 DPRINTF("Before making context for new lwp in child\n"); 1668 _lwp_makecontext(&uc, x86_lwp_main_func, NULL, NULL, stack, 1669 ssize); 1670 1671 DPRINTF("Before creating new in child\n"); 1672 FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0); 1673 1674 DPRINTF("Before waiting for lwp %d to exit\n", lid); 1675 FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0); 1676 1677 DPRINTF("Before verifying that reported %d and running lid %d " 1678 "are the same\n", lid, x86_the_lwp_id); 1679 FORKEE_ASSERT_EQ(lid, x86_the_lwp_id); 1680 1681 DPRINTF("Before exiting of the child process\n"); 1682 _exit(exitval); 1683 } 1684 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 1685 1686 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1687 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1688 1689 validate_status_stopped(status, sigval); 1690 1691 DPRINTF("Set empty EVENT_MASK for the child %d\n", child); 1692 event.pe_set_event = PTRACE_LWP_CREATE; 1693 SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); 1694 1695 DPRINTF("Call GETDBREGS for the child process (r1)\n"); 1696 SYSCALL_REQUIRE(ptrace(PT_GETDBREGS, child, &r1, 0) != -1); 1697 1698 DPRINTF("State of the debug registers (r1):\n"); 1699 for (i = 0; i < __arraycount(r1.dr); i++) 1700 DPRINTF("r1[%zu]=%" PRIxREGISTER "\n", i, r1.dr[i]); 1701 1702 r1.dr[reg] = (long)(intptr_t)check_happy; 1703 DPRINTF("Set DR%d (r1.dr[%d]) to new value %" PRIxREGISTER "\n", 1704 reg, reg, r1.dr[0]); 1705 1706 DPRINTF("New state of the debug registers (r1):\n"); 1707 for (i = 0; i < __arraycount(r1.dr); i++) 1708 DPRINTF("r1[%zu]=%" PRIxREGISTER "\n", i, r1.dr[i]); 1709 1710 DPRINTF("Call SETDBREGS for the child process (r1)\n"); 1711 SYSCALL_REQUIRE(ptrace(PT_SETDBREGS, child, &r1, 0) != -1); 1712 1713 DPRINTF("Before resuming the child process where it left off and " 1714 "without signal to be sent\n"); 1715 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 1716 1717 DPRINTF("Before calling %s() for the child - expected stopped " 1718 "SIGTRAP\n", TWAIT_FNAME); 1719 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1720 1721 validate_status_stopped(status, SIGTRAP); 1722 1723 SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 1724 1725 ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_LWP_CREATE); 1726 1727 lid = state.pe_lwp; 1728 DPRINTF("Reported PTRACE_LWP_CREATE event with lid %d\n", lid); 1729 1730 DPRINTF("Call GETDBREGS for the child process new lwp (r2)\n"); 1731 SYSCALL_REQUIRE(ptrace(PT_GETDBREGS, child, &r2, lid) != -1); 1732 1733 DPRINTF("State of the debug registers (r2):\n"); 1734 for (i = 0; i < __arraycount(r2.dr); i++) 1735 DPRINTF("r2[%zu]=%" PRIxREGISTER "\n", i, r2.dr[i]); 1736 1737 DPRINTF("Assert that (r1) and (r2) are not the same\n"); 1738 ATF_REQUIRE(memcmp(&r1, &r2, sizeof(r1)) != 0); 1739 1740 DPRINTF("Before resuming the child process where it left off and " 1741 "without signal to be sent\n"); 1742 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 1743 1744 DPRINTF("Before calling %s() for the child - expected exited\n", 1745 TWAIT_FNAME); 1746 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1747 1748 validate_status_exited(status, exitval); 1749 1750 DPRINTF("Before calling %s() for the child - expected no process\n", 1751 TWAIT_FNAME); 1752 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 1753 } 1754 1755 ATF_TC(dbregs_dr0_dont_inherit_lwp); 1756 ATF_TC_HEAD(dbregs_dr0_dont_inherit_lwp, tc) 1757 { 1758 atf_tc_set_md_var(tc, "descr", 1759 "Verify that 1 LWP creation is intercepted by ptrace(2) with " 1760 "EVENT_MASK set to PTRACE_LWP_CREATE and Debug Register 0 from " 1761 "the forker thread is not inherited"); 1762 } 1763 1764 ATF_TC_BODY(dbregs_dr0_dont_inherit_lwp, tc) 1765 { 1766 dbregs_dont_inherit_lwp(0); 1767 } 1768 1769 ATF_TC(dbregs_dr1_dont_inherit_lwp); 1770 ATF_TC_HEAD(dbregs_dr1_dont_inherit_lwp, tc) 1771 { 1772 atf_tc_set_md_var(tc, "descr", 1773 "Verify that 1 LWP creation is intercepted by ptrace(2) with " 1774 "EVENT_MASK set to PTRACE_LWP_CREATE and Debug Register 1 from " 1775 "the forker thread is not inherited"); 1776 } 1777 1778 ATF_TC_BODY(dbregs_dr1_dont_inherit_lwp, tc) 1779 { 1780 dbregs_dont_inherit_lwp(1); 1781 } 1782 1783 ATF_TC(dbregs_dr2_dont_inherit_lwp); 1784 ATF_TC_HEAD(dbregs_dr2_dont_inherit_lwp, tc) 1785 { 1786 atf_tc_set_md_var(tc, "descr", 1787 "Verify that 1 LWP creation is intercepted by ptrace(2) with " 1788 "EVENT_MASK set to PTRACE_LWP_CREATE and Debug Register 2 from " 1789 "the forker thread is not inherited"); 1790 } 1791 1792 ATF_TC_BODY(dbregs_dr2_dont_inherit_lwp, tc) 1793 { 1794 dbregs_dont_inherit_lwp(2); 1795 } 1796 1797 ATF_TC(dbregs_dr3_dont_inherit_lwp); 1798 ATF_TC_HEAD(dbregs_dr3_dont_inherit_lwp, tc) 1799 { 1800 atf_tc_set_md_var(tc, "descr", 1801 "Verify that 1 LWP creation is intercepted by ptrace(2) with " 1802 "EVENT_MASK set to PTRACE_LWP_CREATE and Debug Register 3 from " 1803 "the forker thread is not inherited"); 1804 } 1805 1806 ATF_TC_BODY(dbregs_dr3_dont_inherit_lwp, tc) 1807 { 1808 dbregs_dont_inherit_lwp(3); 1809 } 1810 1811 static void 1812 dbregs_dont_inherit_execve(int reg) 1813 { 1814 const int sigval = SIGTRAP; 1815 pid_t child, wpid; 1816 #if defined(TWAIT_HAVE_STATUS) 1817 int status; 1818 #endif 1819 size_t i; 1820 struct dbreg r1; 1821 struct dbreg r2; 1822 1823 struct ptrace_siginfo info; 1824 memset(&info, 0, sizeof(info)); 1825 1826 if (!can_we_set_dbregs()) { 1827 atf_tc_skip("Either run this test as root or set sysctl(3) " 1828 "security.models.extensions.user_set_dbregs to 1"); 1829 } 1830 1831 DPRINTF("Before forking process PID=%d\n", getpid()); 1832 SYSCALL_REQUIRE((child = fork()) != -1); 1833 if (child == 0) { 1834 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 1835 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 1836 1837 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 1838 FORKEE_ASSERT(raise(sigval) == 0); 1839 1840 DPRINTF("Before calling execve(2) from child\n"); 1841 execlp("/bin/echo", "/bin/echo", NULL); 1842 1843 FORKEE_ASSERT(0 && "Not reached"); 1844 } 1845 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 1846 1847 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1848 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1849 1850 validate_status_stopped(status, sigval); 1851 1852 DPRINTF("Call GETDBREGS for the child process (r1)\n"); 1853 SYSCALL_REQUIRE(ptrace(PT_GETDBREGS, child, &r1, 0) != -1); 1854 1855 DPRINTF("State of the debug registers (r1):\n"); 1856 for (i = 0; i < __arraycount(r1.dr); i++) 1857 DPRINTF("r1[%zu]=%" PRIxREGISTER "\n", i, r1.dr[i]); 1858 1859 r1.dr[reg] = (long)(intptr_t)check_happy; 1860 DPRINTF("Set DR%d (r1.dr[%d]) to new value %" PRIxREGISTER "\n", 1861 reg, reg, r1.dr[reg]); 1862 1863 DPRINTF("New state of the debug registers (r1):\n"); 1864 for (i = 0; i < __arraycount(r1.dr); i++) 1865 DPRINTF("r1[%zu]=%" PRIxREGISTER "\n", i, r1.dr[i]); 1866 1867 DPRINTF("Call SETDBREGS for the child process (r1)\n"); 1868 SYSCALL_REQUIRE(ptrace(PT_SETDBREGS, child, &r1, 0) != -1); 1869 1870 DPRINTF("Before resuming the child process where it left off and " 1871 "without signal to be sent\n"); 1872 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 1873 1874 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1875 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1876 1877 validate_status_stopped(status, sigval); 1878 1879 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 1880 SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 1881 1882 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 1883 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 1884 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 1885 info.psi_siginfo.si_errno); 1886 1887 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 1888 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_EXEC); 1889 1890 DPRINTF("Call GETDBREGS for the child process after execve(2)\n"); 1891 SYSCALL_REQUIRE(ptrace(PT_GETDBREGS, child, &r2, 0) != -1); 1892 1893 DPRINTF("State of the debug registers (r2):\n"); 1894 for (i = 0; i < __arraycount(r2.dr); i++) 1895 DPRINTF("r2[%zu]=%" PRIxREGISTER "\n", i, r2.dr[i]); 1896 1897 DPRINTF("Assert that (r1) and (r2) are not the same\n"); 1898 ATF_REQUIRE(memcmp(&r1, &r2, sizeof(r1)) != 0); 1899 1900 DPRINTF("Before resuming the child process where it left off and " 1901 "without signal to be sent\n"); 1902 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 1903 1904 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1905 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1906 1907 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1908 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 1909 } 1910 1911 ATF_TC(dbregs_dr0_dont_inherit_execve); 1912 ATF_TC_HEAD(dbregs_dr0_dont_inherit_execve, tc) 1913 { 1914 atf_tc_set_md_var(tc, "descr", 1915 "Verify that execve(2) is intercepted by tracer and Debug " 1916 "Register 0 is reset"); 1917 } 1918 1919 ATF_TC_BODY(dbregs_dr0_dont_inherit_execve, tc) 1920 { 1921 dbregs_dont_inherit_execve(0); 1922 } 1923 1924 ATF_TC(dbregs_dr1_dont_inherit_execve); 1925 ATF_TC_HEAD(dbregs_dr1_dont_inherit_execve, tc) 1926 { 1927 atf_tc_set_md_var(tc, "descr", 1928 "Verify that execve(2) is intercepted by tracer and Debug " 1929 "Register 1 is reset"); 1930 } 1931 1932 ATF_TC_BODY(dbregs_dr1_dont_inherit_execve, tc) 1933 { 1934 dbregs_dont_inherit_execve(1); 1935 } 1936 1937 ATF_TC(dbregs_dr2_dont_inherit_execve); 1938 ATF_TC_HEAD(dbregs_dr2_dont_inherit_execve, tc) 1939 { 1940 atf_tc_set_md_var(tc, "descr", 1941 "Verify that execve(2) is intercepted by tracer and Debug " 1942 "Register 2 is reset"); 1943 } 1944 1945 ATF_TC_BODY(dbregs_dr2_dont_inherit_execve, tc) 1946 { 1947 dbregs_dont_inherit_execve(2); 1948 } 1949 1950 ATF_TC(dbregs_dr3_dont_inherit_execve); 1951 ATF_TC_HEAD(dbregs_dr3_dont_inherit_execve, tc) 1952 { 1953 atf_tc_set_md_var(tc, "descr", 1954 "Verify that execve(2) is intercepted by tracer and Debug " 1955 "Register 3 is reset"); 1956 } 1957 1958 ATF_TC_BODY(dbregs_dr3_dont_inherit_execve, tc) 1959 { 1960 dbregs_dont_inherit_execve(3); 1961 } 1962 1963 /// ---------------------------------------------------------------------------- 1964 1965 ATF_TC(x86_cve_2018_8897); 1966 ATF_TC_HEAD(x86_cve_2018_8897, tc) 1967 { 1968 atf_tc_set_md_var(tc, "descr", 1969 "Verify mitigation for CVE-2018-8897 (POP SS debug exception)"); 1970 } 1971 1972 #define X86_CVE_2018_8897_PAGE 0x5000 /* page addressable by 32-bit registers */ 1973 1974 static __attribute__((__optimize__("O0"))) void 1975 x86_cve_2018_8897_trigger(void) 1976 { 1977 /* 1978 * A function to trigger the POP SS (CVE-2018-8897) vulnerability 1979 * 1980 * ifdef __x86_64__ 1981 * 1982 * We need to switch to 32-bit mode execution on 64-bit kernel. 1983 * This is achieved with far jump instruction and GDT descriptor 1984 * set to 32-bit CS selector. The 32-bit CS selector is kernel 1985 * specific, in the NetBSD case registered as GUCODE32_SEL 1986 * that is equal to (14 (decimal) << 3) with GDT and user 1987 * privilege level (this makes it 0x73). 1988 * 1989 * In UNIX as(1) assembly x86_64 far jump is coded as ljmp. 1990 * amd64 ljmp requires an indirect address with cs:RIP. 1991 * 1992 * When we are running in 32-bit mode, it's similar to the 1993 * mode as if the binary had been launched in netbsd32. 1994 * 1995 * There are two versions of this exploit, one with RIP 1996 * relative code and the other with static addresses. 1997 * The first one is PIE code aware, the other no-PIE one. 1998 * 1999 * 2000 * After switching to the 32-bit mode we can move on to the remaining 2001 * part of the exploit. 2002 * 2003 * endif // __x86_64__ 2004 * 2005 * Set the stack pointer to the page we allocated earlier. Remember 2006 * that we put an SS selector exactly at this address, so we can pop. 2007 * 2008 * movl $0x5000,%esp 2009 * 2010 * Pop the SS selector off the stack. This reloads the SS selector, 2011 * which is fine. Remember that we set DR0 at address 0x5000, which 2012 * we are now reading. Therefore, on this instruction, the CPU will 2013 * raise a #DB exception. 2014 * 2015 * But the "pop %ss" instruction is special: it blocks exceptions 2016 * until the next instruction is executed. So the #DB that we just 2017 * raised is actually blocked. 2018 * 2019 * pop %ss 2020 * 2021 * We are still here, and didn't receive the #DB. After we execute 2022 * this instruction, the effect of "pop %ss" will disappear, and 2023 * we will receive the #DB for real. 2024 * 2025 * int $4 2026 * 2027 * Here the bug happens. We executed "int $4", so we entered the 2028 * kernel, with interrupts disabled. The #DB that was pending is 2029 * received. But, it is received immediately in kernel mode, and is 2030 * _NOT_ received when interrupts are enabled again. 2031 * 2032 * It means that, in the first instruction of the $4 handler, we 2033 * think we are safe with interrupts disabled. But we aren't, and 2034 * just got interrupted. 2035 * 2036 * The new interrupt handler doesn't handle this particular context: 2037 * we are entered in kernel mode, the previous context was kernel 2038 * mode too but it still had the user context loaded. 2039 * 2040 * We find ourselves not doing a 'swapgs'. At the end of the day, it 2041 * means that we call trap() with a curcpu() that is fully 2042 * controllable by userland. From then on, it is easy to escalate 2043 * privileges. 2044 * 2045 * With SVS it also means we don't switch CR3, so this results in a 2046 * triple fault, which this time cannot be turned to a privilege 2047 * escalation. 2048 */ 2049 2050 #if __x86_64__ 2051 #if __PIE__ 2052 void *csRIP; 2053 2054 csRIP = malloc(sizeof(int) + sizeof(short)); 2055 FORKEE_ASSERT(csRIP != NULL); 2056 2057 __asm__ __volatile__( 2058 " leal 24(%%eip), %%eax\n\t" 2059 " movq %0, %%rdx\n\t" 2060 " movl %%eax, (%%rdx)\n\t" 2061 " movw $0x73, 4(%%rdx)\n\t" 2062 " movq %1, %%rax\n\t" 2063 " ljmp *(%%rax)\n\t" 2064 " .code32\n\t" 2065 " movl $0x5000, %%esp\n\t" 2066 " pop %%ss\n\t" 2067 " int $4\n\t" 2068 " .code64\n\t" 2069 : "=m"(csRIP) 2070 : "m"(csRIP) 2071 : "%rax", "%rdx", "%rsp" 2072 ); 2073 #else /* !__PIE__ */ 2074 __asm__ __volatile__( 2075 " movq $farjmp32, %%rax\n\t" 2076 " ljmp *(%%rax)\n\t" 2077 "farjmp32:\n\t" 2078 " .long trigger32\n\t" 2079 " .word 0x73\n\t" 2080 " .code32\n\t" 2081 "trigger32:\n\t" 2082 " movl $0x5000, %%esp\n\t" 2083 " pop %%ss\n\t" 2084 " int $4\n\t" 2085 " .code64\n\t" 2086 : 2087 : 2088 : "%rax", "%rsp" 2089 ); 2090 #endif 2091 #elif __i386__ 2092 __asm__ __volatile__( 2093 "movl $0x5000, %%esp\n\t" 2094 "pop %%ss\n\t" 2095 "int $4\n\t" 2096 : 2097 : 2098 : "%esp" 2099 ); 2100 #endif 2101 } 2102 2103 ATF_TC_BODY(x86_cve_2018_8897, tc) 2104 { 2105 const int sigval = SIGSTOP; 2106 pid_t child, wpid; 2107 #if defined(TWAIT_HAVE_STATUS) 2108 int status; 2109 #endif 2110 char *trap_page; 2111 struct dbreg db; 2112 2113 2114 if (!can_we_set_dbregs()) { 2115 atf_tc_skip("Either run this test as root or set sysctl(3) " 2116 "security.models.extensions.user_set_dbregs to 1"); 2117 } 2118 2119 DPRINTF("Before forking process PID=%d\n", getpid()); 2120 SYSCALL_REQUIRE((child = fork()) != -1); 2121 if (child == 0) { 2122 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 2123 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 2124 2125 trap_page = mmap((void *)X86_CVE_2018_8897_PAGE, 2126 sysconf(_SC_PAGESIZE), PROT_READ|PROT_WRITE, 2127 MAP_FIXED|MAP_ANON|MAP_PRIVATE, -1, 0); 2128 2129 /* trigger page fault */ 2130 memset(trap_page, 0, sysconf(_SC_PAGESIZE)); 2131 2132 // kernel GDT 2133 #if __x86_64__ 2134 /* SS selector (descriptor 9 (0x4f >> 3)) */ 2135 *trap_page = 0x4f; 2136 #elif __i386__ 2137 /* SS selector (descriptor 4 (0x23 >> 3)) */ 2138 *trap_page = 0x23; 2139 #endif 2140 2141 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 2142 FORKEE_ASSERT(raise(sigval) == 0); 2143 2144 x86_cve_2018_8897_trigger(); 2145 2146 /* NOTREACHED */ 2147 FORKEE_ASSERTX(0 && "This shall not be reached"); 2148 } 2149 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 2150 2151 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 2152 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 2153 2154 validate_status_stopped(status, sigval); 2155 2156 DPRINTF("Call GETDBREGS for the child process\n"); 2157 SYSCALL_REQUIRE(ptrace(PT_GETDBREGS, child, &db, 0) != -1); 2158 2159 /* 2160 * Set up the dbregs. We put the 0x5000 address in DR0. 2161 * It means that, the first time we touch this, the CPU will trigger a 2162 * #DB exception. 2163 */ 2164 db.dr[0] = X86_CVE_2018_8897_PAGE; 2165 db.dr[7] = 0x30003; 2166 2167 DPRINTF("Call SETDBREGS for the child process\n"); 2168 SYSCALL_REQUIRE(ptrace(PT_SETDBREGS, child, &db, 0) != -1); 2169 2170 DPRINTF("Before resuming the child process where it left off and " 2171 "without signal to be sent\n"); 2172 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 2173 2174 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 2175 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 2176 2177 // In this test we receive SIGFPE, is this appropriate? 2178 // validate_status_stopped(status, SIGFPE); 2179 2180 DPRINTF("Kill the child process\n"); 2181 SYSCALL_REQUIRE(ptrace(PT_KILL, child, NULL, 0) != -1); 2182 2183 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 2184 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 2185 2186 validate_status_signaled(status, SIGKILL, 0); 2187 2188 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 2189 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 2190 } 2191 2192 /// ---------------------------------------------------------------------------- 2193 2194 union x86_test_register { 2195 struct { 2196 uint64_t a, b, c, d; 2197 } ymm; 2198 struct { 2199 uint64_t a, b; 2200 } xmm; 2201 uint64_t u64; 2202 uint32_t u32; 2203 }; 2204 2205 enum x86_test_regset { 2206 TEST_GPREGS, 2207 TEST_FPREGS, 2208 TEST_XMMREGS, 2209 TEST_XSTATE 2210 }; 2211 2212 /* Please keep them grouped by acceptable x86_test_regset. */ 2213 enum x86_test_registers { 2214 /* TEST_GPREGS */ 2215 GPREGS_32, 2216 GPREGS_32_EBP_ESP, 2217 GPREGS_64, 2218 GPREGS_64_R8, 2219 /* TEST_FPREGS/TEST_XMMREGS */ 2220 FPREGS_MM, 2221 FPREGS_XMM, 2222 /* TEST_XSTATE */ 2223 FPREGS_YMM 2224 }; 2225 2226 enum x86_test_regmode { 2227 TEST_GETREGS, 2228 TEST_SETREGS, 2229 TEST_COREDUMP 2230 }; 2231 2232 static __inline void get_gp32_regs(union x86_test_register out[]) 2233 { 2234 #if defined(__i386__) 2235 const uint32_t fill = 0x0F0F0F0F; 2236 2237 __asm__ __volatile__( 2238 /* fill registers with clobber pattern */ 2239 "movl %6, %%eax\n\t" 2240 "movl %6, %%ebx\n\t" 2241 "movl %6, %%ecx\n\t" 2242 "movl %6, %%edx\n\t" 2243 "movl %6, %%esi\n\t" 2244 "movl %6, %%edi\n\t" 2245 "\n\t" 2246 "int3\n\t" 2247 : "=a"(out[0].u32), "=b"(out[1].u32), "=c"(out[2].u32), 2248 "=d"(out[3].u32), "=S"(out[4].u32), "=D"(out[5].u32) 2249 : "g"(fill) 2250 ); 2251 #else 2252 __unreachable(); 2253 #endif 2254 } 2255 2256 static __inline void set_gp32_regs(const union x86_test_register data[]) 2257 { 2258 #if defined(__i386__) 2259 __asm__ __volatile__( 2260 "int3\n\t" 2261 : 2262 : "a"(data[0].u32), "b"(data[1].u32), "c"(data[2].u32), 2263 "d"(data[3].u32), "S"(data[4].u32), "D"(data[5].u32) 2264 : 2265 ); 2266 #else 2267 __unreachable(); 2268 #endif 2269 } 2270 2271 static __inline void get_gp32_ebp_esp_regs(union x86_test_register out[]) 2272 { 2273 #if defined(__i386__) 2274 const uint32_t fill = 0x0F0F0F0F; 2275 2276 __asm__ __volatile__( 2277 /* save original ebp & esp using our output registers */ 2278 "movl %%esp, %0\n\t" 2279 "movl %%ebp, %1\n\t" 2280 /* fill them with clobber pattern */ 2281 "movl %2, %%esp\n\t" 2282 "movl %2, %%ebp\n\t" 2283 "\n\t" 2284 "int3\n\t" 2285 "\n\t" 2286 /* restore ebp & esp, and save the result */ 2287 "xchgl %%esp, %0\n\t" 2288 "xchgl %%ebp, %1\n\t" 2289 : "=r"(out[0].u32), "=r"(out[1].u32) 2290 : "g"(fill) 2291 : 2292 ); 2293 #else 2294 __unreachable(); 2295 #endif 2296 } 2297 2298 static __inline void set_gp32_ebp_esp_regs(const union x86_test_register data[]) 2299 { 2300 #if defined(__i386__) 2301 __asm__ __volatile__( 2302 /* ebp & ebp are a bit tricky, we must not clobber them */ 2303 "movl %%esp, %%eax\n\t" 2304 "movl %%ebp, %%ebx\n\t" 2305 "movl %0, %%esp\n\t" 2306 "movl %1, %%ebp\n\t" 2307 "\n\t" 2308 "int3\n\t" 2309 "\n\t" 2310 "movl %%eax, %%esp\n\t" 2311 "movl %%ebx, %%ebp\n\t" 2312 : 2313 : "ri"(data[0].u32), "ri"(data[1].u32) 2314 : "%eax", "%ebx" 2315 ); 2316 #else 2317 __unreachable(); 2318 #endif 2319 } 2320 2321 static __inline void get_gp64_regs(union x86_test_register out[]) 2322 { 2323 #if defined(__x86_64__) 2324 const uint64_t fill = 0x0F0F0F0F0F0F0F0F; 2325 2326 __asm__ __volatile__( 2327 /* save rsp & rbp */ 2328 "movq %%rsp, %6\n\t" 2329 "movq %%rbp, %7\n\t" 2330 "\n\t" 2331 /* fill registers with clobber pattern */ 2332 "movq %8, %%rax\n\t" 2333 "movq %8, %%rbx\n\t" 2334 "movq %8, %%rcx\n\t" 2335 "movq %8, %%rdx\n\t" 2336 "movq %8, %%rsp\n\t" 2337 "movq %8, %%rbp\n\t" 2338 "movq %8, %%rsi\n\t" 2339 "movq %8, %%rdi\n\t" 2340 "\n\t" 2341 "int3\n\t" 2342 "\n\t" 2343 /* swap saved & current rsp & rbp */ 2344 "xchgq %%rsp, %6\n\t" 2345 "xchgq %%rbp, %7\n\t" 2346 : "=a"(out[0].u64), "=b"(out[1].u64), "=c"(out[2].u64), 2347 "=d"(out[3].u64), "=S"(out[4].u64), "=D"(out[5].u64), 2348 "=r"(out[6].u64), "=r"(out[7].u64) 2349 : "g"(fill) 2350 ); 2351 #else 2352 __unreachable(); 2353 #endif 2354 } 2355 2356 static __inline void set_gp64_regs(const union x86_test_register data[]) 2357 { 2358 #if defined(__x86_64__) 2359 __asm__ __volatile__( 2360 /* rbp & rbp are a bit tricky, we must not clobber them */ 2361 "movq %%rsp, %%r8\n\t" 2362 "movq %%rbp, %%r9\n\t" 2363 "movq %6, %%rsp\n\t" 2364 "movq %7, %%rbp\n\t" 2365 "\n\t" 2366 "int3\n\t" 2367 "\n\t" 2368 "movq %%r8, %%rsp\n\t" 2369 "movq %%r9, %%rbp\n\t" 2370 : 2371 : "a"(data[0].u64), "b"(data[1].u64), "c"(data[2].u64), 2372 "d"(data[3].u64), "S"(data[4].u64), "D"(data[5].u64), 2373 "r"(data[6].u64), "r"(data[7].u64) 2374 : "%r8", "%r9" 2375 ); 2376 #else 2377 __unreachable(); 2378 #endif 2379 } 2380 2381 static __inline void get_gp64_r8_regs(union x86_test_register out[]) 2382 { 2383 #if defined(__x86_64__) 2384 const uint64_t fill = 0x0F0F0F0F0F0F0F0F; 2385 2386 __asm__ __volatile__( 2387 /* fill registers with clobber pattern */ 2388 "movq %1, %%r8\n\t" 2389 "movq %1, %%r9\n\t" 2390 "movq %1, %%r10\n\t" 2391 "movq %1, %%r11\n\t" 2392 "movq %1, %%r12\n\t" 2393 "movq %1, %%r13\n\t" 2394 "movq %1, %%r14\n\t" 2395 "movq %1, %%r15\n\t" 2396 "\n\t" 2397 "int3\n\t" 2398 "\n\t" 2399 "movq %%r8, 0x00(%0)\n\t" 2400 "movq %%r9, 0x20(%0)\n\t" 2401 "movq %%r10, 0x40(%0)\n\t" 2402 "movq %%r11, 0x60(%0)\n\t" 2403 "movq %%r12, 0x80(%0)\n\t" 2404 "movq %%r13, 0xA0(%0)\n\t" 2405 "movq %%r14, 0xC0(%0)\n\t" 2406 "movq %%r15, 0xE0(%0)\n\t" 2407 : 2408 : "a"(out), "m"(fill) 2409 : "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15" 2410 ); 2411 #else 2412 __unreachable(); 2413 #endif 2414 } 2415 2416 static __inline void set_gp64_r8_regs(const union x86_test_register data[]) 2417 { 2418 #if defined(__x86_64__) 2419 __asm__ __volatile__( 2420 "movq 0x00(%0), %%r8\n\t" 2421 "movq 0x20(%0), %%r9\n\t" 2422 "movq 0x40(%0), %%r10\n\t" 2423 "movq 0x60(%0), %%r11\n\t" 2424 "movq 0x80(%0), %%r12\n\t" 2425 "movq 0xA0(%0), %%r13\n\t" 2426 "movq 0xC0(%0), %%r14\n\t" 2427 "movq 0xE0(%0), %%r15\n\t" 2428 "int3\n\t" 2429 : 2430 : "b"(data) 2431 : "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15" 2432 ); 2433 #else 2434 __unreachable(); 2435 #endif 2436 } 2437 2438 __attribute__((target("mmx"))) 2439 static __inline void get_mm_regs(union x86_test_register out[]) 2440 { 2441 const uint64_t fill = 0x0F0F0F0F0F0F0F0F; 2442 2443 __asm__ __volatile__( 2444 /* fill registers with clobber pattern */ 2445 "movq %1, %%mm0\n\t" 2446 "movq %1, %%mm1\n\t" 2447 "movq %1, %%mm2\n\t" 2448 "movq %1, %%mm3\n\t" 2449 "movq %1, %%mm4\n\t" 2450 "movq %1, %%mm5\n\t" 2451 "movq %1, %%mm6\n\t" 2452 "movq %1, %%mm7\n\t" 2453 "\n\t" 2454 "int3\n\t" 2455 "\n\t" 2456 "movq %%mm0, 0x00(%0)\n\t" 2457 "movq %%mm1, 0x20(%0)\n\t" 2458 "movq %%mm2, 0x40(%0)\n\t" 2459 "movq %%mm3, 0x60(%0)\n\t" 2460 "movq %%mm4, 0x80(%0)\n\t" 2461 "movq %%mm5, 0xA0(%0)\n\t" 2462 "movq %%mm6, 0xC0(%0)\n\t" 2463 "movq %%mm7, 0xE0(%0)\n\t" 2464 : 2465 : "a"(out), "m"(fill) 2466 : "%mm0", "%mm1", "%mm2", "%mm3", "%mm4", "%mm5", "%mm6", "%mm7" 2467 ); 2468 } 2469 2470 __attribute__((target("mmx"))) 2471 static __inline void set_mm_regs(const union x86_test_register data[]) 2472 { 2473 __asm__ __volatile__( 2474 "movq 0x00(%0), %%mm0\n\t" 2475 "movq 0x20(%0), %%mm1\n\t" 2476 "movq 0x40(%0), %%mm2\n\t" 2477 "movq 0x60(%0), %%mm3\n\t" 2478 "movq 0x80(%0), %%mm4\n\t" 2479 "movq 0xA0(%0), %%mm5\n\t" 2480 "movq 0xC0(%0), %%mm6\n\t" 2481 "movq 0xE0(%0), %%mm7\n\t" 2482 "int3\n\t" 2483 : 2484 : "b"(data) 2485 : "%mm0", "%mm1", "%mm2", "%mm3", "%mm4", "%mm5", "%mm6", "%mm7" 2486 ); 2487 } 2488 2489 __attribute__((target("sse"))) 2490 static __inline void get_xmm_regs(union x86_test_register out[]) 2491 { 2492 union x86_test_register fill __aligned(32) = { 2493 .xmm={ 0x0F0F0F0F0F0F0F0F, 0x0F0F0F0F0F0F0F0F } 2494 }; 2495 2496 __asm__ __volatile__( 2497 /* fill registers with clobber pattern */ 2498 "movaps %1, %%xmm0\n\t" 2499 "movaps %1, %%xmm1\n\t" 2500 "movaps %1, %%xmm2\n\t" 2501 "movaps %1, %%xmm3\n\t" 2502 "movaps %1, %%xmm4\n\t" 2503 "movaps %1, %%xmm5\n\t" 2504 "movaps %1, %%xmm6\n\t" 2505 "movaps %1, %%xmm7\n\t" 2506 #if defined(__x86_64__) 2507 "movaps %1, %%xmm8\n\t" 2508 "movaps %1, %%xmm9\n\t" 2509 "movaps %1, %%xmm10\n\t" 2510 "movaps %1, %%xmm11\n\t" 2511 "movaps %1, %%xmm12\n\t" 2512 "movaps %1, %%xmm13\n\t" 2513 "movaps %1, %%xmm14\n\t" 2514 "movaps %1, %%xmm15\n\t" 2515 #endif 2516 "\n\t" 2517 "int3\n\t" 2518 "\n\t" 2519 "movaps %%xmm0, 0x000(%0)\n\t" 2520 "movaps %%xmm1, 0x020(%0)\n\t" 2521 "movaps %%xmm2, 0x040(%0)\n\t" 2522 "movaps %%xmm3, 0x060(%0)\n\t" 2523 "movaps %%xmm4, 0x080(%0)\n\t" 2524 "movaps %%xmm5, 0x0A0(%0)\n\t" 2525 "movaps %%xmm6, 0x0C0(%0)\n\t" 2526 "movaps %%xmm7, 0x0E0(%0)\n\t" 2527 #if defined(__x86_64__) 2528 "movaps %%xmm8, 0x100(%0)\n\t" 2529 "movaps %%xmm9, 0x120(%0)\n\t" 2530 "movaps %%xmm10, 0x140(%0)\n\t" 2531 "movaps %%xmm11, 0x160(%0)\n\t" 2532 "movaps %%xmm12, 0x180(%0)\n\t" 2533 "movaps %%xmm13, 0x1A0(%0)\n\t" 2534 "movaps %%xmm14, 0x1C0(%0)\n\t" 2535 "movaps %%xmm15, 0x1E0(%0)\n\t" 2536 #endif 2537 : 2538 : "a"(out), "m"(fill) 2539 : "%xmm0", "%xmm1", "%xmm2", "%xmm3", "%xmm4", "%xmm5", "%xmm6", "%xmm7" 2540 #if defined(__x86_64__) 2541 , "%xmm8", "%xmm9", "%xmm10", "%xmm11", "%xmm12", "%xmm13", "%xmm14", 2542 "%xmm15" 2543 #endif 2544 ); 2545 } 2546 2547 __attribute__((target("sse"))) 2548 static __inline void set_xmm_regs(const union x86_test_register data[]) 2549 { 2550 __asm__ __volatile__( 2551 "movaps 0x000(%0), %%xmm0\n\t" 2552 "movaps 0x020(%0), %%xmm1\n\t" 2553 "movaps 0x040(%0), %%xmm2\n\t" 2554 "movaps 0x060(%0), %%xmm3\n\t" 2555 "movaps 0x080(%0), %%xmm4\n\t" 2556 "movaps 0x0A0(%0), %%xmm5\n\t" 2557 "movaps 0x0C0(%0), %%xmm6\n\t" 2558 "movaps 0x0E0(%0), %%xmm7\n\t" 2559 #if defined(__x86_64__) 2560 "movaps 0x100(%0), %%xmm8\n\t" 2561 "movaps 0x120(%0), %%xmm9\n\t" 2562 "movaps 0x140(%0), %%xmm10\n\t" 2563 "movaps 0x160(%0), %%xmm11\n\t" 2564 "movaps 0x180(%0), %%xmm12\n\t" 2565 "movaps 0x1A0(%0), %%xmm13\n\t" 2566 "movaps 0x1C0(%0), %%xmm14\n\t" 2567 "movaps 0x1E0(%0), %%xmm15\n\t" 2568 #endif 2569 "int3\n\t" 2570 : 2571 : "b"(data) 2572 : "%xmm0", "%xmm1", "%xmm2", "%xmm3", "%xmm4", "%xmm5", "%xmm6", 2573 "%xmm7" 2574 #if defined(__x86_64__) 2575 , "%xmm8", "%xmm9", "%xmm10", "%xmm11", "%xmm12", "%xmm13", 2576 "%xmm14", "%xmm15" 2577 #endif 2578 ); 2579 } 2580 2581 __attribute__((target("avx"))) 2582 static __inline void get_ymm_regs(union x86_test_register out[]) 2583 { 2584 union x86_test_register fill __aligned(32) = { 2585 { 0x0F0F0F0F0F0F0F0F, 0x0F0F0F0F0F0F0F0F, 2586 0x0F0F0F0F0F0F0F0F, 0x0F0F0F0F0F0F0F0F } 2587 }; 2588 2589 __asm__ __volatile__( 2590 /* fill registers with clobber pattern */ 2591 "vmovaps %1, %%ymm0\n\t" 2592 "vmovaps %1, %%ymm1\n\t" 2593 "vmovaps %1, %%ymm2\n\t" 2594 "vmovaps %1, %%ymm3\n\t" 2595 "vmovaps %1, %%ymm4\n\t" 2596 "vmovaps %1, %%ymm5\n\t" 2597 "vmovaps %1, %%ymm6\n\t" 2598 "vmovaps %1, %%ymm7\n\t" 2599 #if defined(__x86_64__) 2600 "vmovaps %1, %%ymm8\n\t" 2601 "vmovaps %1, %%ymm9\n\t" 2602 "vmovaps %1, %%ymm10\n\t" 2603 "vmovaps %1, %%ymm11\n\t" 2604 "vmovaps %1, %%ymm12\n\t" 2605 "vmovaps %1, %%ymm13\n\t" 2606 "vmovaps %1, %%ymm14\n\t" 2607 "vmovaps %1, %%ymm15\n\t" 2608 #endif 2609 "\n\t" 2610 "int3\n\t" 2611 "\n\t" 2612 "vmovaps %%ymm0, 0x000(%0)\n\t" 2613 "vmovaps %%ymm1, 0x020(%0)\n\t" 2614 "vmovaps %%ymm2, 0x040(%0)\n\t" 2615 "vmovaps %%ymm3, 0x060(%0)\n\t" 2616 "vmovaps %%ymm4, 0x080(%0)\n\t" 2617 "vmovaps %%ymm5, 0x0A0(%0)\n\t" 2618 "vmovaps %%ymm6, 0x0C0(%0)\n\t" 2619 "vmovaps %%ymm7, 0x0E0(%0)\n\t" 2620 #if defined(__x86_64__) 2621 "vmovaps %%ymm8, 0x100(%0)\n\t" 2622 "vmovaps %%ymm9, 0x120(%0)\n\t" 2623 "vmovaps %%ymm10, 0x140(%0)\n\t" 2624 "vmovaps %%ymm11, 0x160(%0)\n\t" 2625 "vmovaps %%ymm12, 0x180(%0)\n\t" 2626 "vmovaps %%ymm13, 0x1A0(%0)\n\t" 2627 "vmovaps %%ymm14, 0x1C0(%0)\n\t" 2628 "vmovaps %%ymm15, 0x1E0(%0)\n\t" 2629 #endif 2630 : 2631 : "a"(out), "m"(fill) 2632 : "%ymm0", "%ymm1", "%ymm2", "%ymm3", "%ymm4", "%ymm5", "%ymm6", "%ymm7" 2633 #if defined(__x86_64__) 2634 , "%ymm8", "%ymm9", "%ymm10", "%ymm11", "%ymm12", "%ymm13", "%ymm14", 2635 "%ymm15" 2636 #endif 2637 ); 2638 } 2639 2640 __attribute__((target("avx"))) 2641 static __inline void set_ymm_regs(const union x86_test_register data[]) 2642 { 2643 __asm__ __volatile__( 2644 "vmovaps 0x000(%0), %%ymm0\n\t" 2645 "vmovaps 0x020(%0), %%ymm1\n\t" 2646 "vmovaps 0x040(%0), %%ymm2\n\t" 2647 "vmovaps 0x060(%0), %%ymm3\n\t" 2648 "vmovaps 0x080(%0), %%ymm4\n\t" 2649 "vmovaps 0x0A0(%0), %%ymm5\n\t" 2650 "vmovaps 0x0C0(%0), %%ymm6\n\t" 2651 "vmovaps 0x0E0(%0), %%ymm7\n\t" 2652 #if defined(__x86_64__) 2653 "vmovaps 0x100(%0), %%ymm8\n\t" 2654 "vmovaps 0x120(%0), %%ymm9\n\t" 2655 "vmovaps 0x140(%0), %%ymm10\n\t" 2656 "vmovaps 0x160(%0), %%ymm11\n\t" 2657 "vmovaps 0x180(%0), %%ymm12\n\t" 2658 "vmovaps 0x1A0(%0), %%ymm13\n\t" 2659 "vmovaps 0x1C0(%0), %%ymm14\n\t" 2660 "vmovaps 0x1E0(%0), %%ymm15\n\t" 2661 #endif 2662 "int3\n\t" 2663 : 2664 : "b"(data) 2665 : "%ymm0", "%ymm1", "%ymm2", "%ymm3", "%ymm4", "%ymm5", "%ymm6", 2666 "%ymm7" 2667 #if defined(__x86_64__) 2668 , "%ymm8", "%ymm9", "%ymm10", "%ymm11", "%ymm12", "%ymm13", 2669 "%ymm14", "%ymm15" 2670 #endif 2671 ); 2672 } 2673 2674 static void 2675 x86_register_test(enum x86_test_regset regset, enum x86_test_registers regs, 2676 enum x86_test_regmode regmode) 2677 { 2678 const int exitval = 5; 2679 pid_t child, wpid; 2680 #if defined(TWAIT_HAVE_STATUS) 2681 const int sigval = SIGTRAP; 2682 int status; 2683 #endif 2684 struct reg gpr; 2685 struct fpreg fpr; 2686 #if defined(__i386__) 2687 struct xmmregs xmm; 2688 #endif 2689 struct xstate xst; 2690 struct iovec iov; 2691 struct fxsave* fxs = NULL; 2692 uint64_t xst_flags = 0; 2693 char core_path[] = "/tmp/core.XXXXXX"; 2694 int core_fd; 2695 2696 const union x86_test_register expected[] __aligned(32) = { 2697 {{ 0x0706050403020100, 0x0F0E0D0C0B0A0908, 2698 0x1716151413121110, 0x1F1E1D1C1B1A1918, }}, 2699 {{ 0x0807060504030201, 0x100F0E0D0C0B0A09, 2700 0x1817161514131211, 0x201F1E1D1C1B1A19, }}, 2701 {{ 0x0908070605040302, 0x11100F0E0D0C0B0A, 2702 0x1918171615141312, 0x21201F1E1D1C1B1A, }}, 2703 {{ 0x0A09080706050403, 0x1211100F0E0D0C0B, 2704 0x1A19181716151413, 0x2221201F1E1D1C1B, }}, 2705 {{ 0x0B0A090807060504, 0x131211100F0E0D0C, 2706 0x1B1A191817161514, 0x232221201F1E1D1C, }}, 2707 {{ 0x0C0B0A0908070605, 0x14131211100F0E0D, 2708 0x1C1B1A1918171615, 0x24232221201F1E1D, }}, 2709 {{ 0x0D0C0B0A09080706, 0x1514131211100F0E, 2710 0x1D1C1B1A19181716, 0x2524232221201F1E, }}, 2711 {{ 0x0E0D0C0B0A090807, 0x161514131211100F, 2712 0x1E1D1C1B1A191817, 0x262524232221201F, }}, 2713 {{ 0x0F0E0D0C0B0A0908, 0x1716151413121110, 2714 0x1F1E1D1C1B1A1918, 0x2726252423222120, }}, 2715 {{ 0x100F0E0D0C0B0A09, 0x1817161514131211, 2716 0x201F1E1D1C1B1A19, 0x2827262524232221, }}, 2717 {{ 0x11100F0E0D0C0B0A, 0x1918171615141312, 2718 0x21201F1E1D1C1B1A, 0x2928272625242322, }}, 2719 {{ 0x1211100F0E0D0C0B, 0x1A19181716151413, 2720 0x2221201F1E1D1C1B, 0x2A29282726252423, }}, 2721 {{ 0x131211100F0E0D0C, 0x1B1A191817161514, 2722 0x232221201F1E1D1C, 0x2B2A292827262524, }}, 2723 {{ 0x14131211100F0E0D, 0x1C1B1A1918171615, 2724 0x24232221201F1E1D, 0x2C2B2A2928272625, }}, 2725 {{ 0x1514131211100F0E, 0x1D1C1B1A19181716, 2726 0x2524232221201F1E, 0x2D2C2B2A29282726, }}, 2727 {{ 0x161514131211100F, 0x1E1D1C1B1A191817, 2728 0x262524232221201F, 0x2E2D2C2B2A292827, }}, 2729 }; 2730 2731 bool need_32 = false, need_64 = false, need_cpuid = false; 2732 2733 switch (regs) { 2734 case GPREGS_32: 2735 case GPREGS_32_EBP_ESP: 2736 need_32 = true; 2737 break; 2738 case GPREGS_64: 2739 case GPREGS_64_R8: 2740 need_64 = true; 2741 break; 2742 case FPREGS_MM: 2743 case FPREGS_XMM: 2744 case FPREGS_YMM: 2745 need_cpuid = true; 2746 break; 2747 } 2748 2749 if (need_32) { 2750 #if defined(__x86_64__) 2751 atf_tc_skip("Test requires 32-bit mode"); 2752 #endif 2753 } 2754 if (need_64) { 2755 #if defined(__i386__) 2756 atf_tc_skip("Test requires 64-bit mode"); 2757 #endif 2758 } 2759 2760 if (need_cpuid) { 2761 /* verify whether needed instruction sets are supported here */ 2762 unsigned int eax, ebx, ecx, edx; 2763 2764 DPRINTF("Before invoking cpuid\n"); 2765 if (!__get_cpuid(1, &eax, &ebx, &ecx, &edx)) 2766 atf_tc_skip("CPUID is not supported by the CPU"); 2767 2768 DPRINTF("cpuid: ECX = %08x, EDX = %08xd\n", ecx, edx); 2769 2770 switch (regs) { 2771 case FPREGS_YMM: 2772 if (!(ecx & bit_AVX)) 2773 atf_tc_skip("AVX is not supported by the CPU"); 2774 /*FALLTHROUGH*/ 2775 case FPREGS_XMM: 2776 if (!(edx & bit_SSE)) 2777 atf_tc_skip("SSE is not supported by the CPU"); 2778 break; 2779 case FPREGS_MM: 2780 if (!(edx & bit_MMX)) 2781 atf_tc_skip("MMX is not supported by the CPU"); 2782 break; 2783 case GPREGS_32: 2784 case GPREGS_32_EBP_ESP: 2785 case GPREGS_64: 2786 case GPREGS_64_R8: 2787 __unreachable(); 2788 } 2789 } 2790 2791 DPRINTF("Before forking process PID=%d\n", getpid()); 2792 SYSCALL_REQUIRE((child = fork()) != -1); 2793 if (child == 0) { 2794 union x86_test_register vals[16] __aligned(32); 2795 2796 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 2797 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 2798 2799 DPRINTF("Before running assembly from child\n"); 2800 switch (regmode) { 2801 case TEST_GETREGS: 2802 case TEST_COREDUMP: 2803 switch (regs) { 2804 case GPREGS_32: 2805 set_gp32_regs(expected); 2806 break; 2807 case GPREGS_32_EBP_ESP: 2808 set_gp32_ebp_esp_regs(expected); 2809 break; 2810 case GPREGS_64: 2811 set_gp64_regs(expected); 2812 break; 2813 case GPREGS_64_R8: 2814 set_gp64_r8_regs(expected); 2815 break; 2816 case FPREGS_MM: 2817 set_mm_regs(expected); 2818 break; 2819 case FPREGS_XMM: 2820 set_xmm_regs(expected); 2821 break; 2822 case FPREGS_YMM: 2823 set_ymm_regs(expected); 2824 break; 2825 } 2826 break; 2827 case TEST_SETREGS: 2828 switch (regs) { 2829 case GPREGS_32: 2830 get_gp32_regs(vals); 2831 break; 2832 case GPREGS_32_EBP_ESP: 2833 get_gp32_ebp_esp_regs(vals); 2834 break; 2835 case GPREGS_64: 2836 get_gp64_regs(vals); 2837 break; 2838 case GPREGS_64_R8: 2839 get_gp64_r8_regs(vals); 2840 break; 2841 case FPREGS_MM: 2842 get_mm_regs(vals); 2843 break; 2844 case FPREGS_XMM: 2845 get_xmm_regs(vals); 2846 break; 2847 case FPREGS_YMM: 2848 get_ymm_regs(vals); 2849 break; 2850 } 2851 2852 DPRINTF("Before comparing results\n"); 2853 switch (regs) { 2854 case GPREGS_32: 2855 FORKEE_ASSERT(!memcmp(&vals[5].u32, 2856 &expected[5].u32, sizeof(vals->u32))); 2857 FORKEE_ASSERT(!memcmp(&vals[4].u32, 2858 &expected[4].u32, sizeof(vals->u32))); 2859 FORKEE_ASSERT(!memcmp(&vals[3].u32, 2860 &expected[3].u32, sizeof(vals->u32))); 2861 FORKEE_ASSERT(!memcmp(&vals[2].u32, 2862 &expected[2].u32, sizeof(vals->u32))); 2863 /*FALLTHROUGH*/ 2864 case GPREGS_32_EBP_ESP: 2865 FORKEE_ASSERT(!memcmp(&vals[1].u32, 2866 &expected[1].u32, sizeof(vals->u32))); 2867 FORKEE_ASSERT(!memcmp(&vals[0].u32, 2868 &expected[0].u32, sizeof(vals->u32))); 2869 break; 2870 case GPREGS_64: 2871 case GPREGS_64_R8: 2872 case FPREGS_MM: 2873 FORKEE_ASSERT(!memcmp(&vals[0].u64, 2874 &expected[0].u64, sizeof(vals->u64))); 2875 FORKEE_ASSERT(!memcmp(&vals[1].u64, 2876 &expected[1].u64, sizeof(vals->u64))); 2877 FORKEE_ASSERT(!memcmp(&vals[2].u64, 2878 &expected[2].u64, sizeof(vals->u64))); 2879 FORKEE_ASSERT(!memcmp(&vals[3].u64, 2880 &expected[3].u64, sizeof(vals->u64))); 2881 FORKEE_ASSERT(!memcmp(&vals[4].u64, 2882 &expected[4].u64, sizeof(vals->u64))); 2883 FORKEE_ASSERT(!memcmp(&vals[5].u64, 2884 &expected[5].u64, sizeof(vals->u64))); 2885 FORKEE_ASSERT(!memcmp(&vals[6].u64, 2886 &expected[6].u64, sizeof(vals->u64))); 2887 FORKEE_ASSERT(!memcmp(&vals[7].u64, 2888 &expected[7].u64, sizeof(vals->u64))); 2889 break; 2890 case FPREGS_XMM: 2891 FORKEE_ASSERT(!memcmp(&vals[0].xmm, 2892 &expected[0].xmm, sizeof(vals->xmm))); 2893 FORKEE_ASSERT(!memcmp(&vals[1].xmm, 2894 &expected[1].xmm, sizeof(vals->xmm))); 2895 FORKEE_ASSERT(!memcmp(&vals[2].xmm, 2896 &expected[2].xmm, sizeof(vals->xmm))); 2897 FORKEE_ASSERT(!memcmp(&vals[3].xmm, 2898 &expected[3].xmm, sizeof(vals->xmm))); 2899 FORKEE_ASSERT(!memcmp(&vals[4].xmm, 2900 &expected[4].xmm, sizeof(vals->xmm))); 2901 FORKEE_ASSERT(!memcmp(&vals[5].xmm, 2902 &expected[5].xmm, sizeof(vals->xmm))); 2903 FORKEE_ASSERT(!memcmp(&vals[6].xmm, 2904 &expected[6].xmm, sizeof(vals->xmm))); 2905 FORKEE_ASSERT(!memcmp(&vals[7].xmm, 2906 &expected[7].xmm, sizeof(vals->xmm))); 2907 #if defined(__x86_64__) 2908 FORKEE_ASSERT(!memcmp(&vals[8].xmm, 2909 &expected[8].xmm, sizeof(vals->xmm))); 2910 FORKEE_ASSERT(!memcmp(&vals[9].xmm, 2911 &expected[9].xmm, sizeof(vals->xmm))); 2912 FORKEE_ASSERT(!memcmp(&vals[10].xmm, 2913 &expected[10].xmm, sizeof(vals->xmm))); 2914 FORKEE_ASSERT(!memcmp(&vals[11].xmm, 2915 &expected[11].xmm, sizeof(vals->xmm))); 2916 FORKEE_ASSERT(!memcmp(&vals[12].xmm, 2917 &expected[12].xmm, sizeof(vals->xmm))); 2918 FORKEE_ASSERT(!memcmp(&vals[13].xmm, 2919 &expected[13].xmm, sizeof(vals->xmm))); 2920 FORKEE_ASSERT(!memcmp(&vals[14].xmm, 2921 &expected[14].xmm, sizeof(vals->xmm))); 2922 FORKEE_ASSERT(!memcmp(&vals[15].xmm, 2923 &expected[15].xmm, sizeof(vals->xmm))); 2924 #endif 2925 break; 2926 case FPREGS_YMM: 2927 FORKEE_ASSERT(!memcmp(&vals[0].ymm, 2928 &expected[0].ymm, sizeof(vals->ymm))); 2929 FORKEE_ASSERT(!memcmp(&vals[1].ymm, 2930 &expected[1].ymm, sizeof(vals->ymm))); 2931 FORKEE_ASSERT(!memcmp(&vals[2].ymm, 2932 &expected[2].ymm, sizeof(vals->ymm))); 2933 FORKEE_ASSERT(!memcmp(&vals[3].ymm, 2934 &expected[3].ymm, sizeof(vals->ymm))); 2935 FORKEE_ASSERT(!memcmp(&vals[4].ymm, 2936 &expected[4].ymm, sizeof(vals->ymm))); 2937 FORKEE_ASSERT(!memcmp(&vals[5].ymm, 2938 &expected[5].ymm, sizeof(vals->ymm))); 2939 FORKEE_ASSERT(!memcmp(&vals[6].ymm, 2940 &expected[6].ymm, sizeof(vals->ymm))); 2941 FORKEE_ASSERT(!memcmp(&vals[7].ymm, 2942 &expected[7].ymm, sizeof(vals->ymm))); 2943 #if defined(__x86_64__) 2944 FORKEE_ASSERT(!memcmp(&vals[8].ymm, 2945 &expected[8].ymm, sizeof(vals->ymm))); 2946 FORKEE_ASSERT(!memcmp(&vals[9].ymm, 2947 &expected[9].ymm, sizeof(vals->ymm))); 2948 FORKEE_ASSERT(!memcmp(&vals[10].ymm, 2949 &expected[10].ymm, sizeof(vals->ymm))); 2950 FORKEE_ASSERT(!memcmp(&vals[11].ymm, 2951 &expected[11].ymm, sizeof(vals->ymm))); 2952 FORKEE_ASSERT(!memcmp(&vals[12].ymm, 2953 &expected[12].ymm, sizeof(vals->ymm))); 2954 FORKEE_ASSERT(!memcmp(&vals[13].ymm, 2955 &expected[13].ymm, sizeof(vals->ymm))); 2956 FORKEE_ASSERT(!memcmp(&vals[14].ymm, 2957 &expected[14].ymm, sizeof(vals->ymm))); 2958 FORKEE_ASSERT(!memcmp(&vals[15].ymm, 2959 &expected[15].ymm, sizeof(vals->ymm))); 2960 #endif 2961 break; 2962 } 2963 break; 2964 } 2965 2966 DPRINTF("Before exiting of the child process\n"); 2967 _exit(exitval); 2968 } 2969 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 2970 2971 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 2972 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 2973 2974 validate_status_stopped(status, sigval); 2975 2976 if (regset == TEST_XSTATE) { 2977 switch (regs) { 2978 case FPREGS_MM: 2979 xst_flags |= XCR0_X87; 2980 break; 2981 case FPREGS_YMM: 2982 xst_flags |= XCR0_YMM_Hi128; 2983 /*FALLTHROUGH*/ 2984 case FPREGS_XMM: 2985 xst_flags |= XCR0_SSE; 2986 break; 2987 case GPREGS_32: 2988 case GPREGS_32_EBP_ESP: 2989 case GPREGS_64: 2990 case GPREGS_64_R8: 2991 __unreachable(); 2992 break; 2993 } 2994 } 2995 2996 switch (regmode) { 2997 case TEST_GETREGS: 2998 case TEST_SETREGS: 2999 switch (regset) { 3000 case TEST_GPREGS: 3001 ATF_REQUIRE(regs < FPREGS_MM); 3002 DPRINTF("Call GETREGS for the child process\n"); 3003 SYSCALL_REQUIRE(ptrace(PT_GETREGS, child, &gpr, 0) 3004 != -1); 3005 break; 3006 case TEST_XMMREGS: 3007 #if defined(__i386__) 3008 ATF_REQUIRE(regs >= FPREGS_MM && regs < FPREGS_YMM); 3009 DPRINTF("Call GETXMMREGS for the child process\n"); 3010 SYSCALL_REQUIRE(ptrace(PT_GETXMMREGS, child, &xmm, 0) 3011 != -1); 3012 fxs = &xmm.fxstate; 3013 break; 3014 #else 3015 /*FALLTHROUGH*/ 3016 #endif 3017 case TEST_FPREGS: 3018 #if defined(__x86_64__) 3019 ATF_REQUIRE(regs >= FPREGS_MM && regs < FPREGS_YMM); 3020 fxs = &fpr.fxstate; 3021 #else 3022 ATF_REQUIRE(regs >= FPREGS_MM && regs < FPREGS_XMM); 3023 #endif 3024 DPRINTF("Call GETFPREGS for the child process\n"); 3025 SYSCALL_REQUIRE(ptrace(PT_GETFPREGS, child, &fpr, 0) 3026 != -1); 3027 break; 3028 case TEST_XSTATE: 3029 ATF_REQUIRE(regs >= FPREGS_MM); 3030 iov.iov_base = &xst; 3031 iov.iov_len = sizeof(xst); 3032 3033 DPRINTF("Call GETXSTATE for the child process\n"); 3034 SYSCALL_REQUIRE(ptrace(PT_GETXSTATE, child, &iov, 0) 3035 != -1); 3036 3037 ATF_REQUIRE((xst.xs_rfbm & xst_flags) == xst_flags); 3038 switch (regmode) { 3039 case TEST_SETREGS: 3040 xst.xs_rfbm = xst_flags; 3041 xst.xs_xstate_bv = xst_flags; 3042 break; 3043 case TEST_GETREGS: 3044 ATF_REQUIRE((xst.xs_xstate_bv & xst_flags) 3045 == xst_flags); 3046 break; 3047 case TEST_COREDUMP: 3048 __unreachable(); 3049 break; 3050 } 3051 3052 fxs = &xst.xs_fxsave; 3053 break; 3054 } 3055 break; 3056 case TEST_COREDUMP: 3057 SYSCALL_REQUIRE((core_fd = mkstemp(core_path)) != -1); 3058 close(core_fd); 3059 3060 DPRINTF("Call DUMPCORE for the child process\n"); 3061 SYSCALL_REQUIRE(ptrace(PT_DUMPCORE, child, core_path, 3062 strlen(core_path)) != -1); 3063 3064 switch (regset) { 3065 case TEST_GPREGS: 3066 ATF_REQUIRE(regs < FPREGS_MM); 3067 DPRINTF("Parse core file for PT_GETREGS\n"); 3068 ATF_REQUIRE_EQ(core_find_note(core_path, 3069 "NetBSD-CORE@1", PT_GETREGS, &gpr, sizeof(gpr)), 3070 sizeof(gpr)); 3071 break; 3072 case TEST_XMMREGS: 3073 #if defined(__i386__) 3074 ATF_REQUIRE(regs >= FPREGS_MM && regs < FPREGS_YMM); 3075 unlink(core_path); 3076 atf_tc_skip("XMMREGS not supported in core dumps"); 3077 break; 3078 #else 3079 /*FALLTHROUGH*/ 3080 #endif 3081 case TEST_FPREGS: 3082 #if defined(__x86_64__) 3083 ATF_REQUIRE(regs >= FPREGS_MM && regs < FPREGS_YMM); 3084 fxs = &fpr.fxstate; 3085 #else 3086 ATF_REQUIRE(regs >= FPREGS_MM && regs < FPREGS_XMM); 3087 #endif 3088 DPRINTF("Parse core file for PT_GETFPREGS\n"); 3089 ATF_REQUIRE_EQ(core_find_note(core_path, 3090 "NetBSD-CORE@1", PT_GETFPREGS, &fpr, sizeof(fpr)), 3091 sizeof(fpr)); 3092 break; 3093 case TEST_XSTATE: 3094 ATF_REQUIRE(regs >= FPREGS_MM); 3095 DPRINTF("Parse core file for PT_GETXSTATE\n"); 3096 ATF_REQUIRE_EQ(core_find_note(core_path, 3097 "NetBSD-CORE@1", PT_GETXSTATE, &xst, sizeof(xst)), 3098 sizeof(xst)); 3099 ATF_REQUIRE((xst.xs_xstate_bv & xst_flags) 3100 == xst_flags); 3101 fxs = &xst.xs_fxsave; 3102 break; 3103 } 3104 unlink(core_path); 3105 } 3106 3107 #if defined(__x86_64__) 3108 #define MM_REG(n) fpr.fxstate.fx_87_ac[n].r.f87_mantissa 3109 #else 3110 #define MM_REG(n) fpr.fstate.s87_ac[n].f87_mantissa 3111 #endif 3112 3113 switch (regmode) { 3114 case TEST_GETREGS: 3115 case TEST_COREDUMP: 3116 switch (regs) { 3117 case GPREGS_32: 3118 #if defined(__i386__) 3119 ATF_CHECK_EQ((uint32_t)gpr.r_eax, expected[0].u32); 3120 ATF_CHECK_EQ((uint32_t)gpr.r_ebx, expected[1].u32); 3121 ATF_CHECK_EQ((uint32_t)gpr.r_ecx, expected[2].u32); 3122 ATF_CHECK_EQ((uint32_t)gpr.r_edx, expected[3].u32); 3123 ATF_CHECK_EQ((uint32_t)gpr.r_esi, expected[4].u32); 3124 ATF_CHECK_EQ((uint32_t)gpr.r_edi, expected[5].u32); 3125 #endif 3126 break; 3127 case GPREGS_32_EBP_ESP: 3128 #if defined(__i386__) 3129 ATF_CHECK_EQ((uint32_t)gpr.r_esp, expected[0].u32); 3130 ATF_CHECK_EQ((uint32_t)gpr.r_ebp, expected[1].u32); 3131 #endif 3132 break; 3133 case GPREGS_64: 3134 #if defined(__x86_64__) 3135 ATF_CHECK_EQ((uint64_t)gpr.regs[_REG_RAX], 3136 expected[0].u64); 3137 ATF_CHECK_EQ((uint64_t)gpr.regs[_REG_RBX], 3138 expected[1].u64); 3139 ATF_CHECK_EQ((uint64_t)gpr.regs[_REG_RCX], 3140 expected[2].u64); 3141 ATF_CHECK_EQ((uint64_t)gpr.regs[_REG_RDX], 3142 expected[3].u64); 3143 ATF_CHECK_EQ((uint64_t)gpr.regs[_REG_RSI], 3144 expected[4].u64); 3145 ATF_CHECK_EQ((uint64_t)gpr.regs[_REG_RDI], 3146 expected[5].u64); 3147 ATF_CHECK_EQ((uint64_t)gpr.regs[_REG_RSP], 3148 expected[6].u64); 3149 ATF_CHECK_EQ((uint64_t)gpr.regs[_REG_RBP], 3150 expected[7].u64); 3151 #endif 3152 break; 3153 case GPREGS_64_R8: 3154 #if defined(__x86_64__) 3155 ATF_CHECK_EQ((uint64_t)gpr.regs[_REG_R8], 3156 expected[0].u64); 3157 ATF_CHECK_EQ((uint64_t)gpr.regs[_REG_R9], 3158 expected[1].u64); 3159 ATF_CHECK_EQ((uint64_t)gpr.regs[_REG_R10], 3160 expected[2].u64); 3161 ATF_CHECK_EQ((uint64_t)gpr.regs[_REG_R11], 3162 expected[3].u64); 3163 ATF_CHECK_EQ((uint64_t)gpr.regs[_REG_R12], 3164 expected[4].u64); 3165 ATF_CHECK_EQ((uint64_t)gpr.regs[_REG_R13], 3166 expected[5].u64); 3167 ATF_CHECK_EQ((uint64_t)gpr.regs[_REG_R14], 3168 expected[6].u64); 3169 ATF_CHECK_EQ((uint64_t)gpr.regs[_REG_R15], 3170 expected[7].u64); 3171 #endif 3172 break; 3173 case FPREGS_MM: 3174 if (regset == TEST_FPREGS) { 3175 ATF_CHECK_EQ(MM_REG(0), expected[0].u64); 3176 ATF_CHECK_EQ(MM_REG(1), expected[1].u64); 3177 ATF_CHECK_EQ(MM_REG(2), expected[2].u64); 3178 ATF_CHECK_EQ(MM_REG(3), expected[3].u64); 3179 ATF_CHECK_EQ(MM_REG(4), expected[4].u64); 3180 ATF_CHECK_EQ(MM_REG(5), expected[5].u64); 3181 ATF_CHECK_EQ(MM_REG(6), expected[6].u64); 3182 ATF_CHECK_EQ(MM_REG(7), expected[7].u64); 3183 } else { 3184 ATF_CHECK_EQ(fxs->fx_87_ac[0].r.f87_mantissa, 3185 expected[0].u64); 3186 ATF_CHECK_EQ(fxs->fx_87_ac[1].r.f87_mantissa, 3187 expected[1].u64); 3188 ATF_CHECK_EQ(fxs->fx_87_ac[2].r.f87_mantissa, 3189 expected[2].u64); 3190 ATF_CHECK_EQ(fxs->fx_87_ac[3].r.f87_mantissa, 3191 expected[3].u64); 3192 ATF_CHECK_EQ(fxs->fx_87_ac[4].r.f87_mantissa, 3193 expected[4].u64); 3194 ATF_CHECK_EQ(fxs->fx_87_ac[5].r.f87_mantissa, 3195 expected[5].u64); 3196 ATF_CHECK_EQ(fxs->fx_87_ac[6].r.f87_mantissa, 3197 expected[6].u64); 3198 ATF_CHECK_EQ(fxs->fx_87_ac[7].r.f87_mantissa, 3199 expected[7].u64); 3200 } 3201 break; 3202 case FPREGS_YMM: 3203 ATF_CHECK(!memcmp(&xst.xs_ymm_hi128.xs_ymm[0], 3204 &expected[0].ymm.c, sizeof(expected->ymm)/2)); 3205 ATF_CHECK(!memcmp(&xst.xs_ymm_hi128.xs_ymm[1], 3206 &expected[1].ymm.c, sizeof(expected->ymm)/2)); 3207 ATF_CHECK(!memcmp(&xst.xs_ymm_hi128.xs_ymm[2], 3208 &expected[2].ymm.c, sizeof(expected->ymm)/2)); 3209 ATF_CHECK(!memcmp(&xst.xs_ymm_hi128.xs_ymm[3], 3210 &expected[3].ymm.c, sizeof(expected->ymm)/2)); 3211 ATF_CHECK(!memcmp(&xst.xs_ymm_hi128.xs_ymm[4], 3212 &expected[4].ymm.c, sizeof(expected->ymm)/2)); 3213 ATF_CHECK(!memcmp(&xst.xs_ymm_hi128.xs_ymm[5], 3214 &expected[5].ymm.c, sizeof(expected->ymm)/2)); 3215 ATF_CHECK(!memcmp(&xst.xs_ymm_hi128.xs_ymm[6], 3216 &expected[6].ymm.c, sizeof(expected->ymm)/2)); 3217 ATF_CHECK(!memcmp(&xst.xs_ymm_hi128.xs_ymm[7], 3218 &expected[7].ymm.c, sizeof(expected->ymm)/2)); 3219 #if defined(__x86_64__) 3220 ATF_CHECK(!memcmp(&xst.xs_ymm_hi128.xs_ymm[8], 3221 &expected[8].ymm.c, sizeof(expected->ymm)/2)); 3222 ATF_CHECK(!memcmp(&xst.xs_ymm_hi128.xs_ymm[9], 3223 &expected[9].ymm.c, sizeof(expected->ymm)/2)); 3224 ATF_CHECK(!memcmp(&xst.xs_ymm_hi128.xs_ymm[10], 3225 &expected[10].ymm.c, sizeof(expected->ymm)/2)); 3226 ATF_CHECK(!memcmp(&xst.xs_ymm_hi128.xs_ymm[11], 3227 &expected[11].ymm.c, sizeof(expected->ymm)/2)); 3228 ATF_CHECK(!memcmp(&xst.xs_ymm_hi128.xs_ymm[12], 3229 &expected[12].ymm.c, sizeof(expected->ymm)/2)); 3230 ATF_CHECK(!memcmp(&xst.xs_ymm_hi128.xs_ymm[13], 3231 &expected[13].ymm.c, sizeof(expected->ymm)/2)); 3232 ATF_CHECK(!memcmp(&xst.xs_ymm_hi128.xs_ymm[14], 3233 &expected[14].ymm.c, sizeof(expected->ymm)/2)); 3234 ATF_CHECK(!memcmp(&xst.xs_ymm_hi128.xs_ymm[15], 3235 &expected[15].ymm.c, sizeof(expected->ymm)/2)); 3236 #endif 3237 /*FALLTHROUGH*/ 3238 case FPREGS_XMM: 3239 ATF_CHECK(!memcmp(&fxs->fx_xmm[0], &expected[0].ymm.a, 3240 sizeof(expected->ymm)/2)); 3241 ATF_CHECK(!memcmp(&fxs->fx_xmm[1], &expected[1].ymm.a, 3242 sizeof(expected->ymm)/2)); 3243 ATF_CHECK(!memcmp(&fxs->fx_xmm[2], &expected[2].ymm.a, 3244 sizeof(expected->ymm)/2)); 3245 ATF_CHECK(!memcmp(&fxs->fx_xmm[3], &expected[3].ymm.a, 3246 sizeof(expected->ymm)/2)); 3247 ATF_CHECK(!memcmp(&fxs->fx_xmm[4], &expected[4].ymm.a, 3248 sizeof(expected->ymm)/2)); 3249 ATF_CHECK(!memcmp(&fxs->fx_xmm[5], &expected[5].ymm.a, 3250 sizeof(expected->ymm)/2)); 3251 ATF_CHECK(!memcmp(&fxs->fx_xmm[6], &expected[6].ymm.a, 3252 sizeof(expected->ymm)/2)); 3253 ATF_CHECK(!memcmp(&fxs->fx_xmm[7], &expected[7].ymm.a, 3254 sizeof(expected->ymm)/2)); 3255 #if defined(__x86_64__) 3256 ATF_CHECK(!memcmp(&fxs->fx_xmm[8], &expected[8].ymm.a, 3257 sizeof(expected->ymm)/2)); 3258 ATF_CHECK(!memcmp(&fxs->fx_xmm[9], &expected[9].ymm.a, 3259 sizeof(expected->ymm)/2)); 3260 ATF_CHECK(!memcmp(&fxs->fx_xmm[10], &expected[10].ymm.a, 3261 sizeof(expected->ymm)/2)); 3262 ATF_CHECK(!memcmp(&fxs->fx_xmm[11], &expected[11].ymm.a, 3263 sizeof(expected->ymm)/2)); 3264 ATF_CHECK(!memcmp(&fxs->fx_xmm[12], &expected[12].ymm.a, 3265 sizeof(expected->ymm)/2)); 3266 ATF_CHECK(!memcmp(&fxs->fx_xmm[13], &expected[13].ymm.a, 3267 sizeof(expected->ymm)/2)); 3268 ATF_CHECK(!memcmp(&fxs->fx_xmm[14], &expected[14].ymm.a, 3269 sizeof(expected->ymm)/2)); 3270 ATF_CHECK(!memcmp(&fxs->fx_xmm[15], &expected[15].ymm.a, 3271 sizeof(expected->ymm)/2)); 3272 #endif 3273 break; 3274 } 3275 break; 3276 case TEST_SETREGS: 3277 switch (regs) { 3278 case GPREGS_32: 3279 #if defined(__i386__) 3280 gpr.r_eax = expected[0].u32; 3281 gpr.r_ebx = expected[1].u32; 3282 gpr.r_ecx = expected[2].u32; 3283 gpr.r_edx = expected[3].u32; 3284 gpr.r_esi = expected[4].u32; 3285 gpr.r_edi = expected[5].u32; 3286 #endif 3287 break; 3288 case GPREGS_32_EBP_ESP: 3289 #if defined(__i386__) 3290 gpr.r_esp = expected[0].u32; 3291 gpr.r_ebp = expected[1].u32; 3292 #endif 3293 break; 3294 case GPREGS_64: 3295 #if defined(__x86_64__) 3296 gpr.regs[_REG_RAX] = expected[0].u64; 3297 gpr.regs[_REG_RBX] = expected[1].u64; 3298 gpr.regs[_REG_RCX] = expected[2].u64; 3299 gpr.regs[_REG_RDX] = expected[3].u64; 3300 gpr.regs[_REG_RSI] = expected[4].u64; 3301 gpr.regs[_REG_RDI] = expected[5].u64; 3302 gpr.regs[_REG_RSP] = expected[6].u64; 3303 gpr.regs[_REG_RBP] = expected[7].u64; 3304 #endif 3305 break; 3306 case GPREGS_64_R8: 3307 #if defined(__x86_64__) 3308 gpr.regs[_REG_R8] = expected[0].u64; 3309 gpr.regs[_REG_R9] = expected[1].u64; 3310 gpr.regs[_REG_R10] = expected[2].u64; 3311 gpr.regs[_REG_R11] = expected[3].u64; 3312 gpr.regs[_REG_R12] = expected[4].u64; 3313 gpr.regs[_REG_R13] = expected[5].u64; 3314 gpr.regs[_REG_R14] = expected[6].u64; 3315 gpr.regs[_REG_R15] = expected[7].u64; 3316 #endif 3317 break; 3318 case FPREGS_MM: 3319 if (regset == TEST_FPREGS) { 3320 MM_REG(0) = expected[0].u64; 3321 MM_REG(1) = expected[1].u64; 3322 MM_REG(2) = expected[2].u64; 3323 MM_REG(3) = expected[3].u64; 3324 MM_REG(4) = expected[4].u64; 3325 MM_REG(5) = expected[5].u64; 3326 MM_REG(6) = expected[6].u64; 3327 MM_REG(7) = expected[7].u64; 3328 } else { 3329 fxs->fx_87_ac[0].r.f87_mantissa = 3330 expected[0].u64; 3331 fxs->fx_87_ac[1].r.f87_mantissa = 3332 expected[1].u64; 3333 fxs->fx_87_ac[2].r.f87_mantissa = 3334 expected[2].u64; 3335 fxs->fx_87_ac[3].r.f87_mantissa = 3336 expected[3].u64; 3337 fxs->fx_87_ac[4].r.f87_mantissa = 3338 expected[4].u64; 3339 fxs->fx_87_ac[5].r.f87_mantissa = 3340 expected[5].u64; 3341 fxs->fx_87_ac[6].r.f87_mantissa = 3342 expected[6].u64; 3343 fxs->fx_87_ac[7].r.f87_mantissa = 3344 expected[7].u64; 3345 } 3346 break; 3347 case FPREGS_YMM: 3348 memcpy(&xst.xs_ymm_hi128.xs_ymm[0], 3349 &expected[0].ymm.c, sizeof(expected->ymm)/2); 3350 memcpy(&xst.xs_ymm_hi128.xs_ymm[1], 3351 &expected[1].ymm.c, sizeof(expected->ymm)/2); 3352 memcpy(&xst.xs_ymm_hi128.xs_ymm[2], 3353 &expected[2].ymm.c, sizeof(expected->ymm)/2); 3354 memcpy(&xst.xs_ymm_hi128.xs_ymm[3], 3355 &expected[3].ymm.c, sizeof(expected->ymm)/2); 3356 memcpy(&xst.xs_ymm_hi128.xs_ymm[4], 3357 &expected[4].ymm.c, sizeof(expected->ymm)/2); 3358 memcpy(&xst.xs_ymm_hi128.xs_ymm[5], 3359 &expected[5].ymm.c, sizeof(expected->ymm)/2); 3360 memcpy(&xst.xs_ymm_hi128.xs_ymm[6], 3361 &expected[6].ymm.c, sizeof(expected->ymm)/2); 3362 memcpy(&xst.xs_ymm_hi128.xs_ymm[7], 3363 &expected[7].ymm.c, sizeof(expected->ymm)/2); 3364 #if defined(__x86_64__) 3365 memcpy(&xst.xs_ymm_hi128.xs_ymm[8], 3366 &expected[8].ymm.c, sizeof(expected->ymm)/2); 3367 memcpy(&xst.xs_ymm_hi128.xs_ymm[9], 3368 &expected[9].ymm.c, sizeof(expected->ymm)/2); 3369 memcpy(&xst.xs_ymm_hi128.xs_ymm[10], 3370 &expected[10].ymm.c, sizeof(expected->ymm)/2); 3371 memcpy(&xst.xs_ymm_hi128.xs_ymm[11], 3372 &expected[11].ymm.c, sizeof(expected->ymm)/2); 3373 memcpy(&xst.xs_ymm_hi128.xs_ymm[12], 3374 &expected[12].ymm.c, sizeof(expected->ymm)/2); 3375 memcpy(&xst.xs_ymm_hi128.xs_ymm[13], 3376 &expected[13].ymm.c, sizeof(expected->ymm)/2); 3377 memcpy(&xst.xs_ymm_hi128.xs_ymm[14], 3378 &expected[14].ymm.c, sizeof(expected->ymm)/2); 3379 memcpy(&xst.xs_ymm_hi128.xs_ymm[15], 3380 &expected[15].ymm.c, sizeof(expected->ymm)/2); 3381 #endif 3382 /*FALLTHROUGH*/ 3383 case FPREGS_XMM: 3384 memcpy(&fxs->fx_xmm[0], &expected[0].ymm.a, 3385 sizeof(expected->ymm)/2); 3386 memcpy(&fxs->fx_xmm[1], &expected[1].ymm.a, 3387 sizeof(expected->ymm)/2); 3388 memcpy(&fxs->fx_xmm[2], &expected[2].ymm.a, 3389 sizeof(expected->ymm)/2); 3390 memcpy(&fxs->fx_xmm[3], &expected[3].ymm.a, 3391 sizeof(expected->ymm)/2); 3392 memcpy(&fxs->fx_xmm[4], &expected[4].ymm.a, 3393 sizeof(expected->ymm)/2); 3394 memcpy(&fxs->fx_xmm[5], &expected[5].ymm.a, 3395 sizeof(expected->ymm)/2); 3396 memcpy(&fxs->fx_xmm[6], &expected[6].ymm.a, 3397 sizeof(expected->ymm)/2); 3398 memcpy(&fxs->fx_xmm[7], &expected[7].ymm.a, 3399 sizeof(expected->ymm)/2); 3400 #if defined(__x86_64__) 3401 memcpy(&fxs->fx_xmm[8], &expected[8].ymm.a, 3402 sizeof(expected->ymm)/2); 3403 memcpy(&fxs->fx_xmm[9], &expected[9].ymm.a, 3404 sizeof(expected->ymm)/2); 3405 memcpy(&fxs->fx_xmm[10], &expected[10].ymm.a, 3406 sizeof(expected->ymm)/2); 3407 memcpy(&fxs->fx_xmm[11], &expected[11].ymm.a, 3408 sizeof(expected->ymm)/2); 3409 memcpy(&fxs->fx_xmm[12], &expected[12].ymm.a, 3410 sizeof(expected->ymm)/2); 3411 memcpy(&fxs->fx_xmm[13], &expected[13].ymm.a, 3412 sizeof(expected->ymm)/2); 3413 memcpy(&fxs->fx_xmm[14], &expected[14].ymm.a, 3414 sizeof(expected->ymm)/2); 3415 memcpy(&fxs->fx_xmm[15], &expected[15].ymm.a, 3416 sizeof(expected->ymm)/2); 3417 #endif 3418 break; 3419 } 3420 3421 switch (regset) { 3422 case TEST_GPREGS: 3423 DPRINTF("Call SETREGS for the child process\n"); 3424 SYSCALL_REQUIRE(ptrace(PT_SETREGS, child, &gpr, 0) 3425 != -1); 3426 break; 3427 case TEST_XMMREGS: 3428 #if defined(__i386__) 3429 DPRINTF("Call SETXMMREGS for the child process\n"); 3430 SYSCALL_REQUIRE(ptrace(PT_SETXMMREGS, child, &xmm, 0) 3431 != -1); 3432 break; 3433 #else 3434 /*FALLTHROUGH*/ 3435 #endif 3436 case TEST_FPREGS: 3437 DPRINTF("Call SETFPREGS for the child process\n"); 3438 SYSCALL_REQUIRE(ptrace(PT_SETFPREGS, child, &fpr, 0) 3439 != -1); 3440 break; 3441 case TEST_XSTATE: 3442 DPRINTF("Call SETXSTATE for the child process\n"); 3443 SYSCALL_REQUIRE(ptrace(PT_SETXSTATE, child, &iov, 0) 3444 != -1); 3445 break; 3446 } 3447 break; 3448 } 3449 3450 #undef MM_REG 3451 3452 DPRINTF("Before resuming the child process where it left off and " 3453 "without signal to be sent\n"); 3454 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 3455 3456 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 3457 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 3458 3459 validate_status_exited(status, exitval); 3460 3461 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 3462 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 3463 } 3464 3465 #define X86_REGISTER_TEST(test, regset, regs, regmode, descr) \ 3466 ATF_TC(test); \ 3467 ATF_TC_HEAD(test, tc) \ 3468 { \ 3469 atf_tc_set_md_var(tc, "descr", descr); \ 3470 } \ 3471 \ 3472 ATF_TC_BODY(test, tc) \ 3473 { \ 3474 x86_register_test(regset, regs, regmode); \ 3475 } 3476 3477 X86_REGISTER_TEST(x86_gpregs32_read, TEST_GPREGS, GPREGS_32, TEST_GETREGS, 3478 "Test reading basic 32-bit gp registers from debugged program " 3479 "via PT_GETREGS."); 3480 X86_REGISTER_TEST(x86_gpregs32_write, TEST_GPREGS, GPREGS_32, TEST_SETREGS, 3481 "Test writing basic 32-bit gp registers into debugged program " 3482 "via PT_SETREGS."); 3483 X86_REGISTER_TEST(x86_gpregs32_core, TEST_GPREGS, GPREGS_32, TEST_COREDUMP, 3484 "Test reading basic 32-bit gp registers from core dump."); 3485 X86_REGISTER_TEST(x86_gpregs32_ebp_esp_read, TEST_GPREGS, GPREGS_32_EBP_ESP, 3486 TEST_GETREGS, "Test reading ebp & esp registers from debugged program " 3487 "via PT_GETREGS."); 3488 X86_REGISTER_TEST(x86_gpregs32_ebp_esp_write, TEST_GPREGS, GPREGS_32_EBP_ESP, 3489 TEST_SETREGS, "Test writing ebp & esp registers into debugged program " 3490 "via PT_SETREGS."); 3491 X86_REGISTER_TEST(x86_gpregs32_ebp_esp_core, TEST_GPREGS, GPREGS_32_EBP_ESP, 3492 TEST_COREDUMP, "Test reading ebp & esp registers from core dump."); 3493 3494 X86_REGISTER_TEST(x86_gpregs64_read, TEST_GPREGS, GPREGS_64, TEST_GETREGS, 3495 "Test reading basic 64-bit gp registers from debugged program " 3496 "via PT_GETREGS."); 3497 X86_REGISTER_TEST(x86_gpregs64_write, TEST_GPREGS, GPREGS_64, TEST_SETREGS, 3498 "Test writing basic 64-bit gp registers into debugged program " 3499 "via PT_SETREGS."); 3500 X86_REGISTER_TEST(x86_gpregs64_core, TEST_GPREGS, GPREGS_64, TEST_COREDUMP, 3501 "Test reading basic 64-bit gp registers from core dump."); 3502 X86_REGISTER_TEST(x86_gpregs64_r8_read, TEST_GPREGS, GPREGS_64_R8, TEST_GETREGS, 3503 "Test reading r8..r15 registers from debugged program via PT_GETREGS."); 3504 X86_REGISTER_TEST(x86_gpregs64_r8_write, TEST_GPREGS, GPREGS_64_R8, 3505 TEST_SETREGS, "Test writing r8..r15 registers into debugged program " 3506 "via PT_SETREGS."); 3507 X86_REGISTER_TEST(x86_gpregs64_r8_core, TEST_GPREGS, GPREGS_64_R8, 3508 TEST_COREDUMP, "Test reading r8..r15 registers from core dump."); 3509 3510 X86_REGISTER_TEST(x86_fpregs_mm_read, TEST_FPREGS, FPREGS_MM, TEST_GETREGS, 3511 "Test reading mm0..mm7 registers from debugged program " 3512 "via PT_GETFPREGS."); 3513 X86_REGISTER_TEST(x86_fpregs_mm_write, TEST_FPREGS, FPREGS_MM, TEST_SETREGS, 3514 "Test writing mm0..mm7 registers into debugged program " 3515 "via PT_SETFPREGS."); 3516 X86_REGISTER_TEST(x86_fpregs_mm_core, TEST_FPREGS, FPREGS_MM, TEST_COREDUMP, 3517 "Test reading mm0..mm7 registers from coredump."); 3518 X86_REGISTER_TEST(x86_fpregs_xmm_read, TEST_XMMREGS, FPREGS_XMM, TEST_GETREGS, 3519 "Test reading xmm0..xmm15 (..xmm7 on i386) from debugged program " 3520 "via PT_GETFPREGS (PT_GETXMMREGS on i386)."); 3521 X86_REGISTER_TEST(x86_fpregs_xmm_write, TEST_XMMREGS, FPREGS_XMM, TEST_SETREGS, 3522 "Test writing xmm0..xmm15 (..xmm7 on i386) into debugged program " 3523 "via PT_SETFPREGS (PT_SETXMMREGS on i386)."); 3524 X86_REGISTER_TEST(x86_fpregs_xmm_core, TEST_XMMREGS, FPREGS_XMM, TEST_COREDUMP, 3525 "Test reading xmm0..xmm15 (..xmm7 on i386) from coredump."); 3526 3527 X86_REGISTER_TEST(x86_xstate_mm_read, TEST_XSTATE, FPREGS_MM, TEST_GETREGS, 3528 "Test reading mm0..mm7 registers from debugged program " 3529 "via PT_GETXSTATE."); 3530 X86_REGISTER_TEST(x86_xstate_mm_write, TEST_XSTATE, FPREGS_MM, TEST_SETREGS, 3531 "Test writing mm0..mm7 registers into debugged program " 3532 "via PT_SETXSTATE."); 3533 X86_REGISTER_TEST(x86_xstate_mm_core, TEST_XSTATE, FPREGS_MM, TEST_COREDUMP, 3534 "Test reading mm0..mm7 registers from core dump via XSTATE note."); 3535 X86_REGISTER_TEST(x86_xstate_xmm_read, TEST_XSTATE, FPREGS_XMM, TEST_GETREGS, 3536 "Test reading xmm0..xmm15 (..xmm7 on i386) from debugged program " 3537 "via PT_GETXSTATE."); 3538 X86_REGISTER_TEST(x86_xstate_xmm_write, TEST_XSTATE, FPREGS_XMM, TEST_SETREGS, 3539 "Test writing xmm0..xmm15 (..xmm7 on i386) into debugged program " 3540 "via PT_SETXSTATE."); 3541 X86_REGISTER_TEST(x86_xstate_xmm_core, TEST_XSTATE, FPREGS_XMM, TEST_COREDUMP, 3542 "Test reading xmm0..xmm15 (..xmm7 on i386) from coredump via XSTATE note."); 3543 X86_REGISTER_TEST(x86_xstate_ymm_read, TEST_XSTATE, FPREGS_YMM, TEST_GETREGS, 3544 "Test reading ymm0..ymm15 (..ymm7 on i386) from debugged program " 3545 "via PT_GETXSTATE."); 3546 X86_REGISTER_TEST(x86_xstate_ymm_write, TEST_XSTATE, FPREGS_YMM, TEST_SETREGS, 3547 "Test writing ymm0..ymm15 (..ymm7 on i386) into debugged program " 3548 "via PT_SETXSTATE."); 3549 X86_REGISTER_TEST(x86_xstate_ymm_core, TEST_XSTATE, FPREGS_YMM, TEST_COREDUMP, 3550 "Test reading ymm0..ymm15 (..ymm7 on i386) from coredump via XSTATE note."); 3551 3552 /// ---------------------------------------------------------------------------- 3553 3554 #if defined(TWAIT_HAVE_STATUS) 3555 3556 static void 3557 thread_concurrent_lwp_setup(pid_t child, lwpid_t lwpid) 3558 { 3559 struct dbreg r; 3560 union u dr7; 3561 3562 /* We need to set debug registers for every child */ 3563 DPRINTF("Call GETDBREGS for LWP %d\n", lwpid); 3564 SYSCALL_REQUIRE(ptrace(PT_GETDBREGS, child, &r, lwpid) != -1); 3565 3566 dr7.raw = 0; 3567 /* should be set to 1 according to Intel manual, 17.2 */ 3568 dr7.bits.reserved_10 = 1; 3569 dr7.bits.local_exact_breakpt = 1; 3570 dr7.bits.global_exact_breakpt = 1; 3571 /* use DR0 for breakpoints */ 3572 dr7.bits.global_dr0_breakpoint = 1; 3573 dr7.bits.condition_dr0 = 0; /* exec */ 3574 dr7.bits.len_dr0 = 0; 3575 /* use DR1 for watchpoints */ 3576 dr7.bits.global_dr1_breakpoint = 1; 3577 dr7.bits.condition_dr1 = 1; /* write */ 3578 dr7.bits.len_dr1 = 3; /* 4 bytes */ 3579 r.dr[7] = dr7.raw; 3580 r.dr[0] = (long)(intptr_t)check_happy; 3581 r.dr[1] = (long)(intptr_t)&thread_concurrent_watchpoint_var; 3582 DPRINTF("dr0=%" PRIxREGISTER "\n", r.dr[0]); 3583 DPRINTF("dr1=%" PRIxREGISTER "\n", r.dr[1]); 3584 DPRINTF("dr7=%" PRIxREGISTER "\n", r.dr[7]); 3585 3586 DPRINTF("Call SETDBREGS for LWP %d\n", lwpid); 3587 SYSCALL_REQUIRE(ptrace(PT_SETDBREGS, child, &r, lwpid) != -1); 3588 } 3589 3590 static enum thread_concurrent_sigtrap_event 3591 thread_concurrent_handle_sigtrap(pid_t child, ptrace_siginfo_t *info) 3592 { 3593 enum thread_concurrent_sigtrap_event ret = TCSE_UNKNOWN; 3594 struct dbreg r; 3595 union u dr7; 3596 3597 ATF_CHECK_EQ_MSG(info->psi_siginfo.si_code, TRAP_DBREG, 3598 "lwp=%d, expected TRAP_DBREG (%d), got %d", info->psi_lwpid, 3599 TRAP_DBREG, info->psi_siginfo.si_code); 3600 3601 DPRINTF("Call GETDBREGS for LWP %d\n", info->psi_lwpid); 3602 SYSCALL_REQUIRE(ptrace(PT_GETDBREGS, child, &r, info->psi_lwpid) != -1); 3603 DPRINTF("dr6=%" PRIxREGISTER ", dr7=%" PRIxREGISTER "\n", 3604 r.dr[6], r.dr[7]); 3605 3606 ATF_CHECK_MSG(r.dr[6] & 3, "lwp=%d, got DR6=%" PRIxREGISTER, 3607 info->psi_lwpid, r.dr[6]); 3608 3609 /* Handle only one event at a time, we should get 3610 * a separate SIGTRAP for the other one. 3611 */ 3612 if (r.dr[6] & 1) { 3613 r.dr[6] &= ~1; 3614 3615 /* We need to disable the breakpoint to move 3616 * past it. 3617 * 3618 * TODO: single-step and reenable it? 3619 */ 3620 dr7.raw = r.dr[7]; 3621 dr7.bits.global_dr0_breakpoint = 0; 3622 r.dr[7] = dr7.raw; 3623 3624 ret = TCSE_BREAKPOINT; 3625 } else if (r.dr[6] & 2) { 3626 r.dr[6] &= ~2; 3627 ret = TCSE_WATCHPOINT; 3628 } 3629 3630 DPRINTF("Call SETDBREGS for LWP %d\n", info->psi_lwpid); 3631 DPRINTF("dr6=%" PRIxREGISTER ", dr7=%" PRIxREGISTER "\n", 3632 r.dr[6], r.dr[7]); 3633 SYSCALL_REQUIRE(ptrace(PT_SETDBREGS, child, &r, info->psi_lwpid) != -1); 3634 3635 return ret; 3636 } 3637 3638 #endif /*defined(TWAIT_HAVE_STATUS)*/ 3639 3640 /// ---------------------------------------------------------------------------- 3641 3642 #define ATF_TP_ADD_TCS_PTRACE_WAIT_X86() \ 3643 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_print); \ 3644 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_preserve_dr0); \ 3645 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_preserve_dr1); \ 3646 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_preserve_dr2); \ 3647 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_preserve_dr3); \ 3648 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_preserve_dr0_yield); \ 3649 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_preserve_dr1_yield); \ 3650 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_preserve_dr2_yield); \ 3651 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_preserve_dr3_yield); \ 3652 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_preserve_dr0_continued); \ 3653 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_preserve_dr1_continued); \ 3654 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_preserve_dr2_continued); \ 3655 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_preserve_dr3_continued); \ 3656 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr0_trap_variable_writeonly_byte); \ 3657 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr1_trap_variable_writeonly_byte); \ 3658 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr2_trap_variable_writeonly_byte); \ 3659 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr3_trap_variable_writeonly_byte); \ 3660 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr0_trap_variable_writeonly_2bytes); \ 3661 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr1_trap_variable_writeonly_2bytes); \ 3662 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr2_trap_variable_writeonly_2bytes); \ 3663 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr3_trap_variable_writeonly_2bytes); \ 3664 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr0_trap_variable_writeonly_4bytes); \ 3665 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr1_trap_variable_writeonly_4bytes); \ 3666 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr2_trap_variable_writeonly_4bytes); \ 3667 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr3_trap_variable_writeonly_4bytes); \ 3668 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr0_trap_variable_readwrite_write_byte); \ 3669 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr1_trap_variable_readwrite_write_byte); \ 3670 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr2_trap_variable_readwrite_write_byte); \ 3671 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr3_trap_variable_readwrite_write_byte); \ 3672 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr0_trap_variable_readwrite_write_2bytes); \ 3673 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr1_trap_variable_readwrite_write_2bytes); \ 3674 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr2_trap_variable_readwrite_write_2bytes); \ 3675 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr3_trap_variable_readwrite_write_2bytes); \ 3676 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr0_trap_variable_readwrite_write_4bytes); \ 3677 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr1_trap_variable_readwrite_write_4bytes); \ 3678 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr2_trap_variable_readwrite_write_4bytes); \ 3679 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr3_trap_variable_readwrite_write_4bytes); \ 3680 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr0_trap_variable_readwrite_read_byte); \ 3681 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr1_trap_variable_readwrite_read_byte); \ 3682 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr2_trap_variable_readwrite_read_byte); \ 3683 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr3_trap_variable_readwrite_read_byte); \ 3684 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr0_trap_variable_readwrite_read_2bytes); \ 3685 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr1_trap_variable_readwrite_read_2bytes); \ 3686 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr2_trap_variable_readwrite_read_2bytes); \ 3687 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr3_trap_variable_readwrite_read_2bytes); \ 3688 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr0_trap_variable_readwrite_read_4bytes); \ 3689 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr1_trap_variable_readwrite_read_4bytes); \ 3690 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr2_trap_variable_readwrite_read_4bytes); \ 3691 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr3_trap_variable_readwrite_read_4bytes); \ 3692 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr0_trap_code); \ 3693 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr1_trap_code); \ 3694 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr2_trap_code); \ 3695 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr3_trap_code); \ 3696 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr0_dont_inherit_lwp); \ 3697 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr1_dont_inherit_lwp); \ 3698 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr2_dont_inherit_lwp); \ 3699 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr3_dont_inherit_lwp); \ 3700 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr0_dont_inherit_execve); \ 3701 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr1_dont_inherit_execve); \ 3702 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr2_dont_inherit_execve); \ 3703 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr3_dont_inherit_execve); \ 3704 ATF_TP_ADD_TC_HAVE_DBREGS(tp, x86_cve_2018_8897); \ 3705 ATF_TP_ADD_TC(tp, x86_gpregs32_read); \ 3706 ATF_TP_ADD_TC(tp, x86_gpregs32_write); \ 3707 ATF_TP_ADD_TC(tp, x86_gpregs32_core); \ 3708 ATF_TP_ADD_TC(tp, x86_gpregs32_ebp_esp_read); \ 3709 ATF_TP_ADD_TC(tp, x86_gpregs32_ebp_esp_write); \ 3710 ATF_TP_ADD_TC(tp, x86_gpregs32_ebp_esp_core); \ 3711 ATF_TP_ADD_TC(tp, x86_gpregs64_read); \ 3712 ATF_TP_ADD_TC(tp, x86_gpregs64_write); \ 3713 ATF_TP_ADD_TC(tp, x86_gpregs64_core); \ 3714 ATF_TP_ADD_TC(tp, x86_gpregs64_r8_read); \ 3715 ATF_TP_ADD_TC(tp, x86_gpregs64_r8_write); \ 3716 ATF_TP_ADD_TC(tp, x86_gpregs64_r8_core); \ 3717 ATF_TP_ADD_TC(tp, x86_fpregs_mm_read); \ 3718 ATF_TP_ADD_TC(tp, x86_fpregs_mm_write); \ 3719 ATF_TP_ADD_TC(tp, x86_fpregs_mm_core); \ 3720 ATF_TP_ADD_TC(tp, x86_fpregs_xmm_read); \ 3721 ATF_TP_ADD_TC(tp, x86_fpregs_xmm_write); \ 3722 ATF_TP_ADD_TC(tp, x86_fpregs_xmm_core); \ 3723 ATF_TP_ADD_TC(tp, x86_xstate_mm_read); \ 3724 ATF_TP_ADD_TC(tp, x86_xstate_mm_write); \ 3725 ATF_TP_ADD_TC(tp, x86_xstate_mm_core); \ 3726 ATF_TP_ADD_TC(tp, x86_xstate_xmm_read); \ 3727 ATF_TP_ADD_TC(tp, x86_xstate_xmm_write); \ 3728 ATF_TP_ADD_TC(tp, x86_xstate_xmm_core); \ 3729 ATF_TP_ADD_TC(tp, x86_xstate_ymm_read); \ 3730 ATF_TP_ADD_TC(tp, x86_xstate_ymm_write); \ 3731 ATF_TP_ADD_TC(tp, x86_xstate_ymm_core); 3732 #else 3733 #define ATF_TP_ADD_TCS_PTRACE_WAIT_X86() 3734 #endif 3735