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