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