Module Name: src Committed By: kamil Date: Wed Jun 12 17:07:11 UTC 2019
Modified Files: src/tests/lib/libc/sys: t_ptrace_wait.c Log Message: Add new ATF ptrace(2) tests for posix_spawn, reusing tests for fork/vfork New tests: - posix_spawn_detach_spawner - posix_spawn_kill_spawner - posix_spawn_singalmasked - posix_spawn_singalignored All test pass. To generate a diff of this commit: cvs rdiff -u -r1.125 -r1.126 src/tests/lib/libc/sys/t_ptrace_wait.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/tests/lib/libc/sys/t_ptrace_wait.c diff -u src/tests/lib/libc/sys/t_ptrace_wait.c:1.125 src/tests/lib/libc/sys/t_ptrace_wait.c:1.126 --- src/tests/lib/libc/sys/t_ptrace_wait.c:1.125 Tue Jun 11 23:30:05 2019 +++ src/tests/lib/libc/sys/t_ptrace_wait.c Wed Jun 12 17:07:11 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: t_ptrace_wait.c,v 1.125 2019/06/11 23:30:05 kamil Exp $ */ +/* $NetBSD: t_ptrace_wait.c,v 1.126 2019/06/12 17:07:11 kamil Exp $ */ /*- * Copyright (c) 2016, 2017, 2018, 2019 The NetBSD Foundation, Inc. @@ -27,7 +27,7 @@ */ #include <sys/cdefs.h> -__RCSID("$NetBSD: t_ptrace_wait.c,v 1.125 2019/06/11 23:30:05 kamil Exp $"); +__RCSID("$NetBSD: t_ptrace_wait.c,v 1.126 2019/06/12 17:07:11 kamil Exp $"); #include <sys/param.h> #include <sys/types.h> @@ -3195,7 +3195,7 @@ ATF_TC_HEAD(name, tc) \ { \ atf_tc_set_md_var(tc, "descr", "Verify " fun "() " \ "called with 0%s%s%s%s in EVENT_MASK", \ - tspawn ? "|PTRACE_FORK" : "", \ + tspawn ? "|PTRACE_POSIX_SPAWN" : "", \ tfork ? "|PTRACE_FORK" : "", \ tvfork ? "|PTRACE_VFORK" : "", \ tvforkdone ? "|PTRACE_VFORK_DONE" : ""); \ @@ -3282,11 +3282,10 @@ FORK_TEST(posix_spawn16, "spawn", true, #if defined(TWAIT_HAVE_PID) static void -fork_detach_forker_body(bool detachfork, bool detachvfork, - bool detachvforkdone, bool kill_process) +fork_detach_forker_body(const char *fn, bool kill_process) { const int exitval = 5; - const int exitval2 = 15; + const int exitval2 = 0; /* Matches exit value from /bin/echo */ const int sigval = SIGSTOP; pid_t child, child2 = 0, wpid; #if defined(TWAIT_HAVE_STATUS) @@ -3297,17 +3296,9 @@ fork_detach_forker_body(bool detachfork, ptrace_event_t event; const int elen = sizeof(event); - pid_t (*fn)(void); int op; - ATF_REQUIRE((detachfork && !detachvfork && !detachvforkdone) || - (!detachfork && detachvfork && !detachvforkdone) || - (!detachfork && !detachvfork && detachvforkdone)); - - if (detachfork) - fn = fork; - else - fn = vfork; + char * const arg[] = { __UNCONST("/bin/echo"), NULL }; DPRINTF("Before forking process PID=%d\n", getpid()); SYSCALL_REQUIRE((child = fork()) != -1); @@ -3318,10 +3309,19 @@ fork_detach_forker_body(bool detachfork, DPRINTF("Before raising %s from child\n", strsignal(sigval)); FORKEE_ASSERT(raise(sigval) == 0); - FORKEE_ASSERT((child2 = (fn)()) != -1); + if (strcmp(fn, "spawn") == 0) { + FORKEE_ASSERT_EQ(posix_spawn(&child2, + arg[0], NULL, NULL, arg, NULL), 0); + } else { + if (strcmp(fn, "fork") == 0) { + FORKEE_ASSERT((child2 = fork()) != -1); + } else { + FORKEE_ASSERT((child2 = vfork()) != -1); + } - if (child2 == 0) - _exit(exitval2); + if (child2 == 0) + _exit(exitval2); + } FORKEE_REQUIRE_SUCCESS (wpid = TWAIT_GENERIC(child2, &status, 0), child2); @@ -3339,7 +3339,8 @@ fork_detach_forker_body(bool detachfork, validate_status_stopped(status, sigval); DPRINTF("Set EVENT_MASK for the child %d\n", child); - event.pe_set_event = PTRACE_FORK | PTRACE_VFORK | PTRACE_VFORK_DONE; + event.pe_set_event = PTRACE_POSIX_SPAWN | PTRACE_FORK | PTRACE_VFORK + | PTRACE_VFORK_DONE; SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); DPRINTF("Before resuming the child process where it left off and " @@ -3353,13 +3354,21 @@ fork_detach_forker_body(bool detachfork, SYSCALL_REQUIRE( ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); - op = (fn == fork) ? PTRACE_FORK : PTRACE_VFORK; + + if (strcmp(fn, "spawn") == 0) + op = PTRACE_POSIX_SPAWN; + else if (strcmp(fn, "fork") == 0) + op = PTRACE_FORK; + else + op = PTRACE_VFORK; + ATF_REQUIRE_EQ(state.pe_report_event & op, op); child2 = state.pe_other_pid; DPRINTF("Reported ptrace event with forkee %d\n", child2); - if (detachfork || detachvfork) + if (strcmp(fn, "spawn") == 0 || strcmp(fn, "fork") == 0 || + strcmp(fn, "vfork") == 0) op = kill_process ? PT_KILL : PT_DETACH; else op = PT_CONTINUE; @@ -3373,7 +3382,13 @@ fork_detach_forker_body(bool detachfork, SYSCALL_REQUIRE( ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1); - op = (fn == fork) ? PTRACE_FORK : PTRACE_VFORK; + if (strcmp(fn, "spawn") == 0) + op = PTRACE_POSIX_SPAWN; + else if (strcmp(fn, "fork") == 0) + op = PTRACE_FORK; + else + op = PTRACE_VFORK; + ATF_REQUIRE_EQ(state.pe_report_event & op, op); ATF_REQUIRE_EQ(state.pe_other_pid, child); @@ -3382,7 +3397,7 @@ fork_detach_forker_body(bool detachfork, SYSCALL_REQUIRE( ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1); - if (detachvforkdone && fn == vfork) { + if (strcmp(fn, "vforkdone") == 0) { DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME, child); TWAIT_REQUIRE_SUCCESS( @@ -3429,33 +3444,32 @@ fork_detach_forker_body(bool detachfork, TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); } -#define FORK_DETACH_FORKER(name,detfork,detvfork,detvforkdone,kprocess) \ +#define FORK_DETACH_FORKER(name,event,kprocess) \ ATF_TC(name); \ ATF_TC_HEAD(name, tc) \ { \ - atf_tc_set_md_var(tc, "descr", "Verify %s %s%s%s", \ - kprocess ? "killed" : "detached", \ - detfork ? "forker" : "", \ - detvfork ? "vforker" : "", \ - detvforkdone ? "vforker done" : ""); \ + atf_tc_set_md_var(tc, "descr", "Verify %s " event, \ + kprocess ? "killed" : "detached"); \ } \ \ ATF_TC_BODY(name, tc) \ { \ \ - fork_detach_forker_body(detfork, detvfork, detvforkdone, \ - kprocess); \ + fork_detach_forker_body(event, kprocess); \ } -FORK_DETACH_FORKER(fork_detach_forker, true, false, false, false) +FORK_DETACH_FORKER(posix_spawn_detach_spawner, "spawn", false) +FORK_DETACH_FORKER(fork_detach_forker, "fork", false) #if TEST_VFORK_ENABLED -FORK_DETACH_FORKER(vfork_detach_vforker, false, true, false, false) -FORK_DETACH_FORKER(vfork_detach_vforkerdone, false, false, true, false) +FORK_DETACH_FORKER(vfork_detach_vforker, "vfork", false) +FORK_DETACH_FORKER(vfork_detach_vforkerdone, "vforkdone", false) #endif -FORK_DETACH_FORKER(fork_kill_forker, true, false, false, true) + +FORK_DETACH_FORKER(posix_spawn_kill_spawner, "spawn", true) +FORK_DETACH_FORKER(fork_kill_forker, "fork", true) #if TEST_VFORK_ENABLED -FORK_DETACH_FORKER(vfork_kill_vforker, false, true, false, true) -FORK_DETACH_FORKER(vfork_kill_vforkerdone, false, false, true, true) +FORK_DETACH_FORKER(vfork_kill_vforker, "vfork", true) +FORK_DETACH_FORKER(vfork_kill_vforkerdone, "vforkdone", true) #endif #endif @@ -5694,11 +5708,10 @@ ATF_TC_BODY(signal_mask_unrelated, tc) #if defined(TWAIT_HAVE_PID) static void -fork2_body(bool trackfork, bool trackvfork, bool trackvforkdone, bool masked, - bool ignored) +fork2_body(const char *fn, bool masked, bool ignored) { const int exitval = 5; - const int exitval2 = 15; + const int exitval2 = 0; /* Match exit status from /bin/echo */ const int sigval = SIGSTOP; pid_t child, child2 = 0, wpid; #if defined(TWAIT_HAVE_STATUS) @@ -5708,7 +5721,6 @@ fork2_body(bool trackfork, bool trackvfo const int slen = sizeof(state); ptrace_event_t event; const int elen = sizeof(event); - pid_t (*fn)(void); struct sigaction sa; struct ptrace_siginfo info; sigset_t intmask; @@ -5720,10 +5732,7 @@ fork2_body(bool trackfork, bool trackvfo ki_sigset_t kp_sigmask; ki_sigset_t kp_sigignore; - if (trackfork) - fn = fork; - if (trackvfork || trackvforkdone) - fn = vfork; + char * const arg[] = { __UNCONST("/bin/echo"), NULL }; DPRINTF("Before forking process PID=%d\n", getpid()); SYSCALL_REQUIRE((child = fork()) != -1); @@ -5747,10 +5756,18 @@ fork2_body(bool trackfork, bool trackvfo DPRINTF("Before raising %s from child\n", strsignal(sigval)); FORKEE_ASSERT(raise(sigval) == 0); - FORKEE_ASSERT((child2 = (fn)()) != -1); - - if (child2 == 0) - _exit(exitval2); + if (strcmp(fn, "spawn") == 0) { + FORKEE_ASSERT_EQ(posix_spawn(&child2, + arg[0], NULL, NULL, arg, NULL), 0); + } else { + if (strcmp(fn, "fork") == 0) { + FORKEE_ASSERT((child2 = fork()) != -1); + } else { + FORKEE_ASSERT((child2 = vfork()) != -1); + } + if (child2 == 0) + _exit(exitval2); + } FORKEE_REQUIRE_SUCCESS (wpid = TWAIT_GENERIC(child2, &status, 0), child2); @@ -5790,16 +5807,19 @@ fork2_body(bool trackfork, bool trackvfo if (ignored) kp_sigignore = kp.p_sigignore; - DPRINTF("Set 0%s%s%s in EVENT_MASK for the child %d\n", - trackfork ? "|PTRACE_FORK" : "", - trackvfork ? "|PTRACE_VFORK" : "", - trackvforkdone ? "|PTRACE_VFORK_DONE" : "", child); + DPRINTF("Set 0%s%s%s%s in EVENT_MASK for the child %d\n", + strcmp(fn, "spawn") == 0 ? "|PTRACE_POSIX_SPAWN" : "", + strcmp(fn, "fork") == 0 ? "|PTRACE_FORK" : "", + strcmp(fn, "vfork") == 0 ? "|PTRACE_VFORK" : "", + strcmp(fn, "vforkdone") == 0 ? "|PTRACE_VFORK_DONE" : "", child); event.pe_set_event = 0; - if (trackfork) + if (strcmp(fn, "spawn") == 0) + event.pe_set_event |= PTRACE_POSIX_SPAWN; + if (strcmp(fn, "fork") == 0) event.pe_set_event |= PTRACE_FORK; - if (trackvfork) + if (strcmp(fn, "vfork") == 0) event.pe_set_event |= PTRACE_VFORK; - if (trackvforkdone) + if (strcmp(fn, "vforkdone") == 0) event.pe_set_event |= PTRACE_VFORK_DONE; SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); @@ -5807,7 +5827,8 @@ fork2_body(bool trackfork, bool trackvfo "without signal to be sent\n"); SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); - if (trackfork || trackvfork) { + if (strcmp(fn, "spawn") == 0 || strcmp(fn, "fork") == 0 || + strcmp(fn, "vfork") == 0) { DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME, child); TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), @@ -5853,11 +5874,16 @@ fork2_body(bool trackfork, bool trackvfo SYSCALL_REQUIRE( ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); - if (trackfork) { + if (strcmp(fn, "spawn") == 0) { + ATF_REQUIRE_EQ( + state.pe_report_event & PTRACE_POSIX_SPAWN, + PTRACE_POSIX_SPAWN); + } + if (strcmp(fn, "fork") == 0) { ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK, PTRACE_FORK); } - if (trackvfork) { + if (strcmp(fn, "vfork") == 0) { ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK, PTRACE_VFORK); } @@ -5911,11 +5937,16 @@ fork2_body(bool trackfork, bool trackvfo SYSCALL_REQUIRE( ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1); - if (trackfork) { + if (strcmp(fn, "spawn") == 0) { + ATF_REQUIRE_EQ( + state.pe_report_event & PTRACE_POSIX_SPAWN, + PTRACE_POSIX_SPAWN); + } + if (strcmp(fn, "fork") == 0) { ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK, PTRACE_FORK); } - if (trackvfork) { + if (strcmp(fn, "vfork") == 0) { ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK, PTRACE_VFORK); } @@ -5932,7 +5963,7 @@ fork2_body(bool trackfork, bool trackvfo SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); } - if (trackvforkdone) { + if (strcmp(fn, "vforkdone") == 0) { DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME, child); TWAIT_REQUIRE_SUCCESS( @@ -5996,7 +6027,8 @@ fork2_body(bool trackfork, bool trackvfo SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); } - if (trackfork || trackvfork) { + if (strcmp(fn, "spawn") == 0 || strcmp(fn, "fork") == 0 || + strcmp(fn, "vfork") == 0) { DPRINTF("Before calling %s() for the forkee - expected exited" "\n", TWAIT_FNAME); TWAIT_REQUIRE_SUCCESS( @@ -6031,33 +6063,30 @@ fork2_body(bool trackfork, bool trackvfo TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); } -#define FORK2_TEST(name,trackfork,trackvfork,trackvforkdone, \ - masked,ignored) \ +#define FORK2_TEST(name,fn,masked,ignored) \ ATF_TC(name); \ ATF_TC_HEAD(name, tc) \ { \ - atf_tc_set_md_var(tc, "descr", "Verify that %s%s%s is caught " \ + atf_tc_set_md_var(tc, "descr", "Verify that " fn " is caught " \ "regardless of signal %s%s", \ - trackfork ? "PTRACE_FORK" : "", \ - trackvfork ? "PTRACE_VFORK" : "", \ - trackvforkdone ? "PTRACE_VFORK_DONE" : "", \ masked ? "masked" : "", ignored ? "ignored" : ""); \ } \ \ ATF_TC_BODY(name, tc) \ { \ \ - fork2_body(trackfork, trackvfork, trackvforkdone, masked, \ - ignored); \ + fork2_body(fn, masked, ignored); \ } -FORK2_TEST(fork_singalmasked, true, false, false, true, false) -FORK2_TEST(fork_singalignored, true, false, false, false, true) +FORK2_TEST(posix_spawn_singalmasked, "spawn", true, false) +FORK2_TEST(posix_spawn_singalignored, "spawn", false, true) +FORK2_TEST(fork_singalmasked, "fork", true, false) +FORK2_TEST(fork_singalignored, "fork", false, true) #if TEST_VFORK_ENABLED -FORK2_TEST(vfork_singalmasked, false, true, false, true, false) -FORK2_TEST(vfork_singalignored, false, true, false, false, true) -FORK2_TEST(vforkdone_singalmasked, false, false, true, true, false) -FORK2_TEST(vforkdone_singalignored, false, false, true, false, true) +FORK2_TEST(vfork_singalmasked, "vfork", true, false) +FORK2_TEST(vfork_singalignored, "vfork", false, true) +FORK2_TEST(vforkdone_singalmasked, "vforkdone", true, false) +FORK2_TEST(vforkdone_singalignored, "vforkdone", false, true) #endif #endif @@ -7842,11 +7871,14 @@ ATF_TP_ADD_TCS(tp) ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn15); ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn16); + ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn_detach_spawner); ATF_TP_ADD_TC_HAVE_PID(tp, fork_detach_forker); #if TEST_VFORK_ENABLED ATF_TP_ADD_TC_HAVE_PID(tp, vfork_detach_vforker); ATF_TP_ADD_TC_HAVE_PID(tp, vfork_detach_vforkerdone); #endif + + ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn_kill_spawner); ATF_TP_ADD_TC_HAVE_PID(tp, fork_kill_forker); #if TEST_VFORK_ENABLED ATF_TP_ADD_TC_HAVE_PID(tp, vfork_kill_vforker); @@ -7983,6 +8015,8 @@ ATF_TP_ADD_TCS(tp) ATF_TP_ADD_TC(tp, signal_mask_unrelated); + ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn_singalmasked); + ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn_singalignored); ATF_TP_ADD_TC_HAVE_PID(tp, fork_singalmasked); ATF_TP_ADD_TC_HAVE_PID(tp, fork_singalignored); #if TEST_VFORK_ENABLED