1 /* $NetBSD: t_ptrace_clone_wait.h,v 1.3 2020/05/11 21:18:11 kamil Exp $ */ 2 3 /*- 4 * Copyright (c) 2016, 2017, 2018, 2019, 2020 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 30 static void 31 clone_body(int flags, bool trackfork, bool trackvfork, 32 bool trackvforkdone) 33 { 34 const int exitval = 5; 35 const int exitval2 = 15; 36 const int sigval = SIGSTOP; 37 pid_t child, child2 = 0, wpid; 38 #if defined(TWAIT_HAVE_STATUS) 39 int status; 40 #endif 41 ptrace_state_t state; 42 const int slen = sizeof(state); 43 ptrace_event_t event; 44 const int elen = sizeof(event); 45 46 const size_t stack_size = 1024 * 1024; 47 void *stack, *stack_base; 48 49 stack = malloc(stack_size); 50 ATF_REQUIRE(stack != NULL); 51 52 #ifdef __MACHINE_STACK_GROWS_UP 53 stack_base = stack; 54 #else 55 stack_base = (char *)stack + stack_size; 56 #endif 57 58 DPRINTF("Before forking process PID=%d\n", getpid()); 59 SYSCALL_REQUIRE((child = fork()) != -1); 60 if (child == 0) { 61 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 62 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 63 64 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 65 FORKEE_ASSERT(raise(sigval) == 0); 66 67 SYSCALL_REQUIRE((child2 = __clone(clone_func, stack_base, 68 flags|SIGCHLD, (void *)(intptr_t)exitval2)) != -1); 69 70 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), 71 child2); 72 73 // XXX WALLSIG? 74 FORKEE_REQUIRE_SUCCESS 75 (wpid = TWAIT_GENERIC(child2, &status, WALLSIG), child2); 76 77 forkee_status_exited(status, exitval2); 78 79 DPRINTF("Before exiting of the child process\n"); 80 _exit(exitval); 81 } 82 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 83 84 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 85 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 86 87 validate_status_stopped(status, sigval); 88 89 DPRINTF("Set 0%s%s%s in EVENT_MASK for the child %d\n", 90 trackfork ? "|PTRACE_FORK" : "", 91 trackvfork ? "|PTRACE_VFORK" : "", 92 trackvforkdone ? "|PTRACE_VFORK_DONE" : "", child); 93 event.pe_set_event = 0; 94 if (trackfork) 95 event.pe_set_event |= PTRACE_FORK; 96 if (trackvfork) 97 event.pe_set_event |= PTRACE_VFORK; 98 if (trackvforkdone) 99 event.pe_set_event |= PTRACE_VFORK_DONE; 100 SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); 101 102 DPRINTF("Before resuming the child process where it left off and " 103 "without signal to be sent\n"); 104 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 105 106 #if defined(TWAIT_HAVE_PID) 107 if ((trackfork && !(flags & CLONE_VFORK)) || 108 (trackvfork && (flags & CLONE_VFORK))) { 109 DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME, 110 child); 111 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), 112 child); 113 114 validate_status_stopped(status, SIGTRAP); 115 116 SYSCALL_REQUIRE( 117 ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 118 if (trackfork && !(flags & CLONE_VFORK)) { 119 ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK, 120 PTRACE_FORK); 121 } 122 if (trackvfork && (flags & CLONE_VFORK)) { 123 ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK, 124 PTRACE_VFORK); 125 } 126 127 child2 = state.pe_other_pid; 128 DPRINTF("Reported ptrace event with forkee %d\n", child2); 129 130 DPRINTF("Before calling %s() for the forkee %d of the child " 131 "%d\n", TWAIT_FNAME, child2, child); 132 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0), 133 child2); 134 135 validate_status_stopped(status, SIGTRAP); 136 137 SYSCALL_REQUIRE( 138 ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1); 139 if (trackfork && !(flags & CLONE_VFORK)) { 140 ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK, 141 PTRACE_FORK); 142 } 143 if (trackvfork && (flags & CLONE_VFORK)) { 144 ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK, 145 PTRACE_VFORK); 146 } 147 148 ATF_REQUIRE_EQ(state.pe_other_pid, child); 149 150 DPRINTF("Before resuming the forkee process where it left off " 151 "and without signal to be sent\n"); 152 SYSCALL_REQUIRE( 153 ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1); 154 155 DPRINTF("Before resuming the child process where it left off " 156 "and without signal to be sent\n"); 157 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 158 } 159 #endif 160 161 if (trackvforkdone && (flags & CLONE_VFORK)) { 162 DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME, 163 child); 164 TWAIT_REQUIRE_SUCCESS( 165 wpid = TWAIT_GENERIC(child, &status, 0), child); 166 167 validate_status_stopped(status, SIGTRAP); 168 169 SYSCALL_REQUIRE( 170 ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 171 ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK_DONE); 172 173 child2 = state.pe_other_pid; 174 DPRINTF("Reported PTRACE_VFORK_DONE event with forkee %d\n", 175 child2); 176 177 DPRINTF("Before resuming the child process where it left off " 178 "and without signal to be sent\n"); 179 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 180 } 181 182 #if defined(TWAIT_HAVE_PID) 183 if ((trackfork && !(flags & CLONE_VFORK)) || 184 (trackvfork && (flags & CLONE_VFORK))) { 185 DPRINTF("Before calling %s() for the forkee - expected exited" 186 "\n", TWAIT_FNAME); 187 TWAIT_REQUIRE_SUCCESS( 188 wpid = TWAIT_GENERIC(child2, &status, 0), child2); 189 190 validate_status_exited(status, exitval2); 191 192 DPRINTF("Before calling %s() for the forkee - expected no " 193 "process\n", TWAIT_FNAME); 194 TWAIT_REQUIRE_FAILURE(ECHILD, 195 wpid = TWAIT_GENERIC(child2, &status, 0)); 196 } 197 #endif 198 199 DPRINTF("Before calling %s() for the child - expected stopped " 200 "SIGCHLD\n", TWAIT_FNAME); 201 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 202 203 validate_status_stopped(status, SIGCHLD); 204 205 DPRINTF("Before resuming the child process where it left off and " 206 "without signal to be sent\n"); 207 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 208 209 DPRINTF("Before calling %s() for the child - expected exited\n", 210 TWAIT_FNAME); 211 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 212 213 validate_status_exited(status, exitval); 214 215 DPRINTF("Before calling %s() for the child - expected no process\n", 216 TWAIT_FNAME); 217 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 218 } 219 220 #define CLONE_TEST(name,flags,tfork,tvfork,tvforkdone) \ 221 ATF_TC(name); \ 222 ATF_TC_HEAD(name, tc) \ 223 { \ 224 atf_tc_set_md_var(tc, "descr", "Verify clone(%s) " \ 225 "called with 0%s%s%s in EVENT_MASK", \ 226 #flags, \ 227 tfork ? "|PTRACE_FORK" : "", \ 228 tvfork ? "|PTRACE_VFORK" : "", \ 229 tvforkdone ? "|PTRACE_VFORK_DONE" : ""); \ 230 } \ 231 \ 232 ATF_TC_BODY(name, tc) \ 233 { \ 234 \ 235 clone_body(flags, tfork, tvfork, tvforkdone); \ 236 } 237 238 CLONE_TEST(clone1, 0, false, false, false) 239 #if defined(TWAIT_HAVE_PID) 240 CLONE_TEST(clone2, 0, true, false, false) 241 CLONE_TEST(clone3, 0, false, true, false) 242 CLONE_TEST(clone4, 0, true, true, false) 243 #endif 244 CLONE_TEST(clone5, 0, false, false, true) 245 #if defined(TWAIT_HAVE_PID) 246 CLONE_TEST(clone6, 0, true, false, true) 247 CLONE_TEST(clone7, 0, false, true, true) 248 CLONE_TEST(clone8, 0, true, true, true) 249 #endif 250 251 CLONE_TEST(clone_vm1, CLONE_VM, false, false, false) 252 #if defined(TWAIT_HAVE_PID) 253 CLONE_TEST(clone_vm2, CLONE_VM, true, false, false) 254 CLONE_TEST(clone_vm3, CLONE_VM, false, true, false) 255 CLONE_TEST(clone_vm4, CLONE_VM, true, true, false) 256 #endif 257 CLONE_TEST(clone_vm5, CLONE_VM, false, false, true) 258 #if defined(TWAIT_HAVE_PID) 259 CLONE_TEST(clone_vm6, CLONE_VM, true, false, true) 260 CLONE_TEST(clone_vm7, CLONE_VM, false, true, true) 261 CLONE_TEST(clone_vm8, CLONE_VM, true, true, true) 262 #endif 263 264 CLONE_TEST(clone_fs1, CLONE_FS, false, false, false) 265 #if defined(TWAIT_HAVE_PID) 266 CLONE_TEST(clone_fs2, CLONE_FS, true, false, false) 267 CLONE_TEST(clone_fs3, CLONE_FS, false, true, false) 268 CLONE_TEST(clone_fs4, CLONE_FS, true, true, false) 269 #endif 270 CLONE_TEST(clone_fs5, CLONE_FS, false, false, true) 271 #if defined(TWAIT_HAVE_PID) 272 CLONE_TEST(clone_fs6, CLONE_FS, true, false, true) 273 CLONE_TEST(clone_fs7, CLONE_FS, false, true, true) 274 CLONE_TEST(clone_fs8, CLONE_FS, true, true, true) 275 #endif 276 277 CLONE_TEST(clone_files1, CLONE_FILES, false, false, false) 278 #if defined(TWAIT_HAVE_PID) 279 CLONE_TEST(clone_files2, CLONE_FILES, true, false, false) 280 CLONE_TEST(clone_files3, CLONE_FILES, false, true, false) 281 CLONE_TEST(clone_files4, CLONE_FILES, true, true, false) 282 #endif 283 CLONE_TEST(clone_files5, CLONE_FILES, false, false, true) 284 #if defined(TWAIT_HAVE_PID) 285 CLONE_TEST(clone_files6, CLONE_FILES, true, false, true) 286 CLONE_TEST(clone_files7, CLONE_FILES, false, true, true) 287 CLONE_TEST(clone_files8, CLONE_FILES, true, true, true) 288 #endif 289 290 //CLONE_TEST(clone_sighand1, CLONE_SIGHAND, false, false, false) 291 #if defined(TWAIT_HAVE_PID) 292 //CLONE_TEST(clone_sighand2, CLONE_SIGHAND, true, false, false) 293 //CLONE_TEST(clone_sighand3, CLONE_SIGHAND, false, true, false) 294 //CLONE_TEST(clone_sighand4, CLONE_SIGHAND, true, true, false) 295 #endif 296 //CLONE_TEST(clone_sighand5, CLONE_SIGHAND, false, false, true) 297 #if defined(TWAIT_HAVE_PID) 298 //CLONE_TEST(clone_sighand6, CLONE_SIGHAND, true, false, true) 299 //CLONE_TEST(clone_sighand7, CLONE_SIGHAND, false, true, true) 300 //CLONE_TEST(clone_sighand8, CLONE_SIGHAND, true, true, true) 301 #endif 302 303 CLONE_TEST(clone_vfork1, CLONE_VFORK, false, false, false) 304 #if defined(TWAIT_HAVE_PID) 305 CLONE_TEST(clone_vfork2, CLONE_VFORK, true, false, false) 306 CLONE_TEST(clone_vfork3, CLONE_VFORK, false, true, false) 307 CLONE_TEST(clone_vfork4, CLONE_VFORK, true, true, false) 308 #endif 309 CLONE_TEST(clone_vfork5, CLONE_VFORK, false, false, true) 310 #if defined(TWAIT_HAVE_PID) 311 CLONE_TEST(clone_vfork6, CLONE_VFORK, true, false, true) 312 CLONE_TEST(clone_vfork7, CLONE_VFORK, false, true, true) 313 CLONE_TEST(clone_vfork8, CLONE_VFORK, true, true, true) 314 #endif 315 316 /// ---------------------------------------------------------------------------- 317 318 #if defined(TWAIT_HAVE_PID) 319 static void 320 clone_body2(int flags, bool masked, bool ignored) 321 { 322 const int exitval = 5; 323 const int exitval2 = 15; 324 const int sigval = SIGSTOP; 325 pid_t child, child2 = 0, wpid; 326 #if defined(TWAIT_HAVE_STATUS) 327 int status; 328 #endif 329 ptrace_state_t state; 330 const int slen = sizeof(state); 331 ptrace_event_t event; 332 const int elen = sizeof(event); 333 struct sigaction sa; 334 struct ptrace_siginfo info; 335 sigset_t intmask; 336 struct kinfo_proc2 kp; 337 size_t len = sizeof(kp); 338 339 int name[6]; 340 const size_t namelen = __arraycount(name); 341 ki_sigset_t kp_sigmask; 342 ki_sigset_t kp_sigignore; 343 344 const size_t stack_size = 1024 * 1024; 345 void *stack, *stack_base; 346 347 stack = malloc(stack_size); 348 ATF_REQUIRE(stack != NULL); 349 350 #ifdef __MACHINE_STACK_GROWS_UP 351 stack_base = stack; 352 #else 353 stack_base = (char *)stack + stack_size; 354 #endif 355 356 SYSCALL_REQUIRE((child = fork()) != -1); 357 if (child == 0) { 358 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 359 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 360 361 if (masked) { 362 sigemptyset(&intmask); 363 sigaddset(&intmask, SIGTRAP); 364 sigprocmask(SIG_BLOCK, &intmask, NULL); 365 } 366 367 if (ignored) { 368 memset(&sa, 0, sizeof(sa)); 369 sa.sa_handler = SIG_IGN; 370 sigemptyset(&sa.sa_mask); 371 FORKEE_ASSERT(sigaction(SIGTRAP, &sa, NULL) != -1); 372 } 373 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 374 FORKEE_ASSERT(raise(sigval) == 0); 375 376 DPRINTF("Before forking process PID=%d flags=%#x\n", getpid(), 377 flags); 378 SYSCALL_REQUIRE((child2 = __clone(clone_func, stack_base, 379 flags|SIGCHLD, (void *)(intptr_t)exitval2)) != -1); 380 381 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), 382 child2); 383 384 // XXX WALLSIG? 385 FORKEE_REQUIRE_SUCCESS 386 (wpid = TWAIT_GENERIC(child2, &status, WALLSIG), child2); 387 388 forkee_status_exited(status, exitval2); 389 390 DPRINTF("Before exiting of the child process\n"); 391 _exit(exitval); 392 } 393 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 394 395 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 396 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 397 398 validate_status_stopped(status, sigval); 399 400 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 401 SYSCALL_REQUIRE( 402 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 403 404 DPRINTF("Before checking siginfo_t\n"); 405 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 406 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 407 408 name[0] = CTL_KERN, 409 name[1] = KERN_PROC2, 410 name[2] = KERN_PROC_PID; 411 name[3] = child; 412 name[4] = sizeof(kp); 413 name[5] = 1; 414 415 FORKEE_ASSERT_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0); 416 417 kp_sigmask = kp.p_sigmask; 418 kp_sigignore = kp.p_sigignore; 419 420 DPRINTF("Set PTRACE_FORK | PTRACE_VFORK | PTRACE_VFORK_DONE in " 421 "EVENT_MASK for the child %d\n", child); 422 event.pe_set_event = PTRACE_FORK | PTRACE_VFORK | PTRACE_VFORK_DONE; 423 SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); 424 425 DPRINTF("Before resuming the child process where it left off and " 426 "without signal to be sent\n"); 427 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 428 429 DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME, 430 child); 431 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), 432 child); 433 434 validate_status_stopped(status, SIGTRAP); 435 436 ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0); 437 438 if (masked) { 439 DPRINTF("kp_sigmask=" 440 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 441 PRIx32 "\n", 442 kp_sigmask.__bits[0], kp_sigmask.__bits[1], 443 kp_sigmask.__bits[2], kp_sigmask.__bits[3]); 444 445 DPRINTF("kp.p_sigmask=" 446 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 447 PRIx32 "\n", 448 kp.p_sigmask.__bits[0], kp.p_sigmask.__bits[1], 449 kp.p_sigmask.__bits[2], kp.p_sigmask.__bits[3]); 450 451 ATF_REQUIRE(sigismember((sigset_t *)&kp.p_sigmask, 452 SIGTRAP)); 453 } 454 455 if (ignored) { 456 DPRINTF("kp_sigignore=" 457 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 458 PRIx32 "\n", 459 kp_sigignore.__bits[0], kp_sigignore.__bits[1], 460 kp_sigignore.__bits[2], kp_sigignore.__bits[3]); 461 462 DPRINTF("kp.p_sigignore=" 463 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 464 PRIx32 "\n", 465 kp.p_sigignore.__bits[0], kp.p_sigignore.__bits[1], 466 kp.p_sigignore.__bits[2], kp.p_sigignore.__bits[3]); 467 468 ATF_REQUIRE(sigismember((sigset_t *)&kp.p_sigignore, 469 SIGTRAP)); 470 } 471 472 SYSCALL_REQUIRE( 473 ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 474 DPRINTF("state.pe_report_event=%#x pid=%d\n", state.pe_report_event, 475 child2); 476 if (!(flags & CLONE_VFORK)) { 477 ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK, 478 PTRACE_FORK); 479 } else { 480 ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK, 481 PTRACE_VFORK); 482 } 483 484 child2 = state.pe_other_pid; 485 DPRINTF("Reported ptrace event with forkee %d\n", child2); 486 487 DPRINTF("Before calling %s() for the forkee %d of the child " 488 "%d\n", TWAIT_FNAME, child2, child); 489 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0), 490 child2); 491 492 validate_status_stopped(status, SIGTRAP); 493 494 name[3] = child2; 495 ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0); 496 497 if (masked) { 498 DPRINTF("kp_sigmask=" 499 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 500 PRIx32 "\n", 501 kp_sigmask.__bits[0], kp_sigmask.__bits[1], 502 kp_sigmask.__bits[2], kp_sigmask.__bits[3]); 503 504 DPRINTF("kp.p_sigmask=" 505 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 506 PRIx32 "\n", 507 kp.p_sigmask.__bits[0], kp.p_sigmask.__bits[1], 508 kp.p_sigmask.__bits[2], kp.p_sigmask.__bits[3]); 509 510 ATF_REQUIRE(sigismember((sigset_t *)&kp.p_sigmask, 511 SIGTRAP)); 512 } 513 514 if (ignored) { 515 DPRINTF("kp_sigignore=" 516 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 517 PRIx32 "\n", 518 kp_sigignore.__bits[0], kp_sigignore.__bits[1], 519 kp_sigignore.__bits[2], kp_sigignore.__bits[3]); 520 521 DPRINTF("kp.p_sigignore=" 522 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 523 PRIx32 "\n", 524 kp.p_sigignore.__bits[0], kp.p_sigignore.__bits[1], 525 kp.p_sigignore.__bits[2], kp.p_sigignore.__bits[3]); 526 527 ATF_REQUIRE(sigismember((sigset_t *)&kp.p_sigignore, 528 SIGTRAP)); 529 } 530 531 SYSCALL_REQUIRE( 532 ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1); 533 if (!(flags & CLONE_VFORK)) { 534 ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK, 535 PTRACE_FORK); 536 } else { 537 ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK, 538 PTRACE_VFORK); 539 } 540 541 ATF_REQUIRE_EQ(state.pe_other_pid, child); 542 543 DPRINTF("Before resuming the forkee process where it left off " 544 "and without signal to be sent\n"); 545 SYSCALL_REQUIRE( 546 ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1); 547 548 DPRINTF("Before resuming the child process where it left off " 549 "and without signal to be sent\n"); 550 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 551 552 if (flags & CLONE_VFORK) { 553 DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME, 554 child); 555 TWAIT_REQUIRE_SUCCESS( 556 wpid = TWAIT_GENERIC(child, &status, 0), child); 557 558 validate_status_stopped(status, SIGTRAP); 559 560 name[3] = child; 561 ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0); 562 563 /* 564 * SIGCHLD is now pending in the signal queue and 565 * the kernel presents it to userland as a masked signal. 566 */ 567 sigdelset((sigset_t *)&kp.p_sigmask, SIGCHLD); 568 569 if (masked) { 570 DPRINTF("kp_sigmask=" 571 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 572 PRIx32 "\n", 573 kp_sigmask.__bits[0], kp_sigmask.__bits[1], 574 kp_sigmask.__bits[2], kp_sigmask.__bits[3]); 575 576 DPRINTF("kp.p_sigmask=" 577 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 578 PRIx32 "\n", 579 kp.p_sigmask.__bits[0], kp.p_sigmask.__bits[1], 580 kp.p_sigmask.__bits[2], kp.p_sigmask.__bits[3]); 581 582 ATF_REQUIRE(!memcmp(&kp_sigmask, &kp.p_sigmask, 583 sizeof(kp_sigmask))); 584 } 585 586 if (ignored) { 587 DPRINTF("kp_sigignore=" 588 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 589 PRIx32 "\n", 590 kp_sigignore.__bits[0], kp_sigignore.__bits[1], 591 kp_sigignore.__bits[2], kp_sigignore.__bits[3]); 592 593 DPRINTF("kp.p_sigignore=" 594 "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" 595 PRIx32 "\n", 596 kp.p_sigignore.__bits[0], kp.p_sigignore.__bits[1], 597 kp.p_sigignore.__bits[2], kp.p_sigignore.__bits[3]); 598 599 ATF_REQUIRE(!memcmp(&kp_sigignore, &kp.p_sigignore, 600 sizeof(kp_sigignore))); 601 } 602 603 SYSCALL_REQUIRE( 604 ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 605 ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK_DONE); 606 607 child2 = state.pe_other_pid; 608 DPRINTF("Reported PTRACE_VFORK_DONE event with forkee %d\n", 609 child2); 610 611 DPRINTF("Before resuming the child process where it left off " 612 "and without signal to be sent\n"); 613 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 614 } 615 616 DPRINTF("Before calling %s() for the forkee - expected exited" 617 "\n", TWAIT_FNAME); 618 TWAIT_REQUIRE_SUCCESS( 619 wpid = TWAIT_GENERIC(child2, &status, 0), child2); 620 621 validate_status_exited(status, exitval2); 622 623 DPRINTF("Before calling %s() for the forkee - expected no " 624 "process\n", TWAIT_FNAME); 625 TWAIT_REQUIRE_FAILURE(ECHILD, 626 wpid = TWAIT_GENERIC(child2, &status, 0)); 627 628 DPRINTF("Before calling %s() for the child - expected stopped " 629 "SIGCHLD\n", TWAIT_FNAME); 630 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 631 632 validate_status_stopped(status, SIGCHLD); 633 634 DPRINTF("Before resuming the child process where it left off and " 635 "without signal to be sent\n"); 636 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 637 638 DPRINTF("Before calling %s() for the child - expected exited\n", 639 TWAIT_FNAME); 640 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 641 642 validate_status_exited(status, exitval); 643 644 DPRINTF("Before calling %s() for the child - expected no process\n", 645 TWAIT_FNAME); 646 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 647 } 648 649 #define CLONE_TEST2(name,flags,masked,ignored) \ 650 ATF_TC(name); \ 651 ATF_TC_HEAD(name, tc) \ 652 { \ 653 atf_tc_set_md_var(tc, "descr", "Verify that clone(%s) is caught"\ 654 " regardless of signal %s%s", \ 655 #flags, masked ? "masked" : "", ignored ? "ignored" : ""); \ 656 } \ 657 \ 658 ATF_TC_BODY(name, tc) \ 659 { \ 660 \ 661 clone_body2(flags, masked, ignored); \ 662 } 663 664 CLONE_TEST2(clone_signalignored, 0, true, false) 665 CLONE_TEST2(clone_signalmasked, 0, false, true) 666 CLONE_TEST2(clone_vm_signalignored, CLONE_VM, true, false) 667 CLONE_TEST2(clone_vm_signalmasked, CLONE_VM, false, true) 668 CLONE_TEST2(clone_fs_signalignored, CLONE_FS, true, false) 669 CLONE_TEST2(clone_fs_signalmasked, CLONE_FS, false, true) 670 CLONE_TEST2(clone_files_signalignored, CLONE_FILES, true, false) 671 CLONE_TEST2(clone_files_signalmasked, CLONE_FILES, false, true) 672 //CLONE_TEST2(clone_sighand_signalignored, CLONE_SIGHAND, true, false) // XXX 673 //CLONE_TEST2(clone_sighand_signalmasked, CLONE_SIGHAND, false, true) // XXX 674 CLONE_TEST2(clone_vfork_signalignored, CLONE_VFORK, true, false) 675 CLONE_TEST2(clone_vfork_signalmasked, CLONE_VFORK, false, true) 676 #endif 677 678 /// ---------------------------------------------------------------------------- 679 680 #if defined(TWAIT_HAVE_PID) 681 static void 682 traceme_vfork_clone_body(int flags) 683 { 684 const int exitval = 5; 685 const int exitval2 = 15; 686 pid_t child, child2 = 0, wpid; 687 #if defined(TWAIT_HAVE_STATUS) 688 int status; 689 #endif 690 691 const size_t stack_size = 1024 * 1024; 692 void *stack, *stack_base; 693 694 stack = malloc(stack_size); 695 ATF_REQUIRE(stack != NULL); 696 697 #ifdef __MACHINE_STACK_GROWS_UP 698 stack_base = stack; 699 #else 700 stack_base = (char *)stack + stack_size; 701 #endif 702 703 SYSCALL_REQUIRE((child = vfork()) != -1); 704 if (child == 0) { 705 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 706 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 707 708 DPRINTF("Before forking process PID=%d flags=%#x\n", getpid(), 709 flags); 710 SYSCALL_REQUIRE((child2 = __clone(clone_func, stack_base, 711 flags|SIGCHLD, (void *)(intptr_t)exitval2)) != -1); 712 713 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), 714 child2); 715 716 // XXX WALLSIG? 717 FORKEE_REQUIRE_SUCCESS 718 (wpid = TWAIT_GENERIC(child2, &status, WALLSIG), child2); 719 720 forkee_status_exited(status, exitval2); 721 722 DPRINTF("Before exiting of the child process\n"); 723 _exit(exitval); 724 } 725 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 726 727 DPRINTF("Before calling %s() for the child - expected exited\n", 728 TWAIT_FNAME); 729 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 730 731 validate_status_exited(status, exitval); 732 733 DPRINTF("Before calling %s() for the child - expected no process\n", 734 TWAIT_FNAME); 735 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 736 } 737 738 #define TRACEME_VFORK_CLONE_TEST(name,flags) \ 739 ATF_TC(name); \ 740 ATF_TC_HEAD(name, tc) \ 741 { \ 742 atf_tc_set_md_var(tc, "descr", "Verify that clone(%s) is " \ 743 "handled correctly with vfork(2)ed tracer", \ 744 #flags); \ 745 } \ 746 \ 747 ATF_TC_BODY(name, tc) \ 748 { \ 749 \ 750 traceme_vfork_clone_body(flags); \ 751 } 752 753 TRACEME_VFORK_CLONE_TEST(traceme_vfork_clone, 0) 754 TRACEME_VFORK_CLONE_TEST(traceme_vfork_clone_vm, CLONE_VM) 755 TRACEME_VFORK_CLONE_TEST(traceme_vfork_clone_fs, CLONE_FS) 756 TRACEME_VFORK_CLONE_TEST(traceme_vfork_clone_files, CLONE_FILES) 757 //TRACEME_VFORK_CLONE_TEST(traceme_vfork_clone_sighand, CLONE_SIGHAND) // XXX 758 TRACEME_VFORK_CLONE_TEST(traceme_vfork_clone_vfork, CLONE_VFORK) 759 #endif 760 761 #define ATF_TP_ADD_TCS_PTRACE_WAIT_CLONE() \ 762 ATF_TP_ADD_TC(tp, clone1); \ 763 ATF_TP_ADD_TC_HAVE_PID(tp, clone2); \ 764 ATF_TP_ADD_TC_HAVE_PID(tp, clone3); \ 765 ATF_TP_ADD_TC_HAVE_PID(tp, clone4); \ 766 ATF_TP_ADD_TC(tp, clone5); \ 767 ATF_TP_ADD_TC_HAVE_PID(tp, clone6); \ 768 ATF_TP_ADD_TC_HAVE_PID(tp, clone7); \ 769 ATF_TP_ADD_TC_HAVE_PID(tp, clone8); \ 770 ATF_TP_ADD_TC(tp, clone_vm1); \ 771 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vm2); \ 772 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vm3); \ 773 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vm4); \ 774 ATF_TP_ADD_TC(tp, clone_vm5); \ 775 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vm6); \ 776 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vm7); \ 777 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vm8); \ 778 ATF_TP_ADD_TC(tp, clone_fs1); \ 779 ATF_TP_ADD_TC_HAVE_PID(tp, clone_fs2); \ 780 ATF_TP_ADD_TC_HAVE_PID(tp, clone_fs3); \ 781 ATF_TP_ADD_TC_HAVE_PID(tp, clone_fs4); \ 782 ATF_TP_ADD_TC(tp, clone_fs5); \ 783 ATF_TP_ADD_TC_HAVE_PID(tp, clone_fs6); \ 784 ATF_TP_ADD_TC_HAVE_PID(tp, clone_fs7); \ 785 ATF_TP_ADD_TC_HAVE_PID(tp, clone_fs8); \ 786 ATF_TP_ADD_TC(tp, clone_files1); \ 787 ATF_TP_ADD_TC_HAVE_PID(tp, clone_files2); \ 788 ATF_TP_ADD_TC_HAVE_PID(tp, clone_files3); \ 789 ATF_TP_ADD_TC_HAVE_PID(tp, clone_files4); \ 790 ATF_TP_ADD_TC(tp, clone_files5); \ 791 ATF_TP_ADD_TC_HAVE_PID(tp, clone_files6); \ 792 ATF_TP_ADD_TC_HAVE_PID(tp, clone_files7); \ 793 ATF_TP_ADD_TC_HAVE_PID(tp, clone_files8); \ 794 ATF_TP_ADD_TC(tp, clone_vfork1); \ 795 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vfork2); \ 796 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vfork3); \ 797 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vfork4); \ 798 ATF_TP_ADD_TC(tp, clone_vfork5); \ 799 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vfork6); \ 800 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vfork7); \ 801 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vfork8); \ 802 ATF_TP_ADD_TC_HAVE_PID(tp, clone_signalignored); \ 803 ATF_TP_ADD_TC_HAVE_PID(tp, clone_signalmasked); \ 804 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vm_signalignored); \ 805 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vm_signalmasked); \ 806 ATF_TP_ADD_TC_HAVE_PID(tp, clone_fs_signalignored); \ 807 ATF_TP_ADD_TC_HAVE_PID(tp, clone_fs_signalmasked); \ 808 ATF_TP_ADD_TC_HAVE_PID(tp, clone_files_signalignored); \ 809 ATF_TP_ADD_TC_HAVE_PID(tp, clone_files_signalmasked); \ 810 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vfork_signalignored); \ 811 ATF_TP_ADD_TC_HAVE_PID(tp, clone_vfork_signalmasked); \ 812 ATF_TP_ADD_TC_HAVE_PID(tp, traceme_vfork_clone); \ 813 ATF_TP_ADD_TC_HAVE_PID(tp, traceme_vfork_clone_vm); \ 814 ATF_TP_ADD_TC_HAVE_PID(tp, traceme_vfork_clone_fs); \ 815 ATF_TP_ADD_TC_HAVE_PID(tp, traceme_vfork_clone_files); \ 816 ATF_TP_ADD_TC_HAVE_PID(tp, traceme_vfork_clone_vfork); 817 818 // ATF_TP_ADD_TC(tp, clone_sighand1); // XXX 819 // ATF_TP_ADD_TC_HAVE_PID(tp, clone_sighand2); // XXX 820 // ATF_TP_ADD_TC_HAVE_PID(tp, clone_sighand3); // XXX 821 // ATF_TP_ADD_TC_HAVE_PID(tp, clone_sighand4); // XXX 822 // ATF_TP_ADD_TC(tp, clone_sighand5); // XXX 823 // ATF_TP_ADD_TC_HAVE_PID(tp, clone_sighand6); // XXX 824 // ATF_TP_ADD_TC_HAVE_PID(tp, clone_sighand7); // XXX 825 // ATF_TP_ADD_TC_HAVE_PID(tp, clone_sighand8); // XXX 826 827 // ATF_TP_ADD_TC_HAVE_PID(tp, clone_sighand_signalignored); // XXX 828 // ATF_TP_ADD_TC_HAVE_PID(tp, clone_sighand_signalmasked); // XXX 829 830 // ATF_TP_ADD_TC_HAVE_PID(tp, traceme_vfork_clone_sighand); // XXX 831