t_ptrace_wait.c revision 1.88
11.88Skamil/* $NetBSD: t_ptrace_wait.c,v 1.88 2019/02/15 05:06:38 kamil Exp $ */ 21.1Skamil 31.1Skamil/*- 41.78Skamil * Copyright (c) 2016, 2017, 2018, 2019 The NetBSD Foundation, Inc. 51.1Skamil * All rights reserved. 61.1Skamil * 71.1Skamil * Redistribution and use in source and binary forms, with or without 81.1Skamil * modification, are permitted provided that the following conditions 91.1Skamil * are met: 101.1Skamil * 1. Redistributions of source code must retain the above copyright 111.1Skamil * notice, this list of conditions and the following disclaimer. 121.1Skamil * 2. Redistributions in binary form must reproduce the above copyright 131.1Skamil * notice, this list of conditions and the following disclaimer in the 141.1Skamil * documentation and/or other materials provided with the distribution. 151.1Skamil * 161.1Skamil * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 171.1Skamil * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 181.1Skamil * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 191.1Skamil * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 201.1Skamil * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 211.1Skamil * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 221.1Skamil * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 231.1Skamil * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 241.1Skamil * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 251.1Skamil * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 261.1Skamil * POSSIBILITY OF SUCH DAMAGE. 271.1Skamil */ 281.1Skamil 291.1Skamil#include <sys/cdefs.h> 301.88Skamil__RCSID("$NetBSD: t_ptrace_wait.c,v 1.88 2019/02/15 05:06:38 kamil Exp $"); 311.1Skamil 321.1Skamil#include <sys/param.h> 331.1Skamil#include <sys/types.h> 341.39Skamil#include <sys/mman.h> 351.1Skamil#include <sys/ptrace.h> 361.1Skamil#include <sys/resource.h> 371.1Skamil#include <sys/stat.h> 381.1Skamil#include <sys/syscall.h> 391.1Skamil#include <sys/sysctl.h> 401.1Skamil#include <sys/wait.h> 411.1Skamil#include <machine/reg.h> 421.1Skamil#include <elf.h> 431.1Skamil#include <err.h> 441.1Skamil#include <errno.h> 451.1Skamil#include <lwp.h> 461.77Skamil#include <pthread.h> 471.1Skamil#include <sched.h> 481.1Skamil#include <signal.h> 491.1Skamil#include <stdint.h> 501.1Skamil#include <stdio.h> 511.1Skamil#include <stdlib.h> 521.1Skamil#include <strings.h> 531.26Skamil#include <time.h> 541.1Skamil#include <unistd.h> 551.1Skamil 561.1Skamil#include <atf-c.h> 571.1Skamil 581.1Skamil#include "h_macros.h" 591.1Skamil 601.1Skamil#include "t_ptrace_wait.h" 611.1Skamil#include "msg.h" 621.1Skamil 631.1Skamil#define PARENT_TO_CHILD(info, fds, msg) \ 641.61Skre SYSCALL_REQUIRE(msg_write_child(info " to child " # fds, &fds, &msg, \ 651.61Skre sizeof(msg)) == 0) 661.1Skamil 671.1Skamil#define CHILD_FROM_PARENT(info, fds, msg) \ 681.61Skre FORKEE_ASSERT(msg_read_parent(info " from parent " # fds, &fds, &msg, \ 691.61Skre sizeof(msg)) == 0) 701.1Skamil 711.1Skamil#define CHILD_TO_PARENT(info, fds, msg) \ 721.61Skre FORKEE_ASSERT(msg_write_parent(info " to parent " # fds, &fds, &msg, \ 731.61Skre sizeof(msg)) == 0) 741.1Skamil 751.1Skamil#define PARENT_FROM_CHILD(info, fds, msg) \ 761.61Skre SYSCALL_REQUIRE(msg_read_child(info " from parent " # fds, &fds, &msg, \ 771.61Skre sizeof(msg)) == 0) 781.13Schristos 791.13Schristos#define SYSCALL_REQUIRE(expr) ATF_REQUIRE_MSG(expr, "%s: %s", # expr, \ 801.13Schristos strerror(errno)) 811.18Schristos#define SYSCALL_REQUIRE_ERRNO(res, exp) ATF_REQUIRE_MSG(res == exp, \ 821.18Schristos "%d(%s) != %d", res, strerror(res), exp) 831.13Schristos 841.13Schristosstatic int debug = 0; 851.13Schristos 861.13Schristos#define DPRINTF(a, ...) do \ 871.13Schristos if (debug) printf(a, ##__VA_ARGS__); \ 881.13Schristos while (/*CONSTCOND*/0) 891.1Skamil 901.34Skamil/// ---------------------------------------------------------------------------- 911.34Skamil 921.33Skamilstatic void 931.33Skamiltraceme_raise(int sigval) 941.1Skamil{ 951.1Skamil const int exitval = 5; 961.1Skamil pid_t child, wpid; 971.1Skamil#if defined(TWAIT_HAVE_STATUS) 981.1Skamil int status; 991.1Skamil#endif 1001.1Skamil 1011.45Skamil struct ptrace_siginfo info; 1021.45Skamil memset(&info, 0, sizeof(info)); 1031.45Skamil 1041.13Schristos DPRINTF("Before forking process PID=%d\n", getpid()); 1051.13Schristos SYSCALL_REQUIRE((child = fork()) != -1); 1061.1Skamil if (child == 0) { 1071.13Schristos DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 1081.1Skamil FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 1091.1Skamil 1101.13Schristos DPRINTF("Before raising %s from child\n", strsignal(sigval)); 1111.1Skamil FORKEE_ASSERT(raise(sigval) == 0); 1121.1Skamil 1131.36Skamil switch (sigval) { 1141.36Skamil case SIGKILL: 1151.36Skamil /* NOTREACHED */ 1161.36Skamil FORKEE_ASSERTX(0 && "This shall not be reached"); 1171.70Smrg __unreachable(); 1181.36Skamil default: 1191.36Skamil DPRINTF("Before exiting of the child process\n"); 1201.36Skamil _exit(exitval); 1211.36Skamil } 1221.1Skamil } 1231.13Schristos DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 1241.1Skamil 1251.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1261.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1271.1Skamil 1281.36Skamil switch (sigval) { 1291.36Skamil case SIGKILL: 1301.36Skamil validate_status_signaled(status, sigval, 0); 1311.36Skamil break; 1321.36Skamil default: 1331.36Skamil validate_status_stopped(status, sigval); 1341.1Skamil 1351.45Skamil DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for " 1361.61Skre "child\n"); 1371.45Skamil SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, 1381.61Skre sizeof(info)) != -1); 1391.45Skamil 1401.45Skamil DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 1411.45Skamil DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 1421.61Skre "si_errno=%#x\n", 1431.61Skre info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 1441.61Skre info.psi_siginfo.si_errno); 1451.45Skamil 1461.45Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 1471.45Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 1481.45Skamil 1491.36Skamil DPRINTF("Before resuming the child process where it left off " 1501.36Skamil "and without signal to be sent\n"); 1511.36Skamil SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 1521.1Skamil 1531.36Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1541.36Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), 1551.61Skre child); 1561.36Skamil break; 1571.36Skamil } 1581.1Skamil 1591.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1601.1Skamil TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 1611.1Skamil} 1621.1Skamil 1631.61Skre#define TRACEME_RAISE(test, sig) \ 1641.61SkreATF_TC(test); \ 1651.61SkreATF_TC_HEAD(test, tc) \ 1661.61Skre{ \ 1671.61Skre atf_tc_set_md_var(tc, "descr", \ 1681.61Skre "Verify " #sig " followed by _exit(2) in a child"); \ 1691.61Skre} \ 1701.61Skre \ 1711.61SkreATF_TC_BODY(test, tc) \ 1721.61Skre{ \ 1731.61Skre \ 1741.61Skre traceme_raise(sig); \ 1751.33Skamil} 1761.33Skamil 1771.36SkamilTRACEME_RAISE(traceme_raise1, SIGKILL) /* non-maskable */ 1781.33SkamilTRACEME_RAISE(traceme_raise2, SIGSTOP) /* non-maskable */ 1791.33SkamilTRACEME_RAISE(traceme_raise3, SIGABRT) /* regular abort trap */ 1801.33SkamilTRACEME_RAISE(traceme_raise4, SIGHUP) /* hangup */ 1811.33SkamilTRACEME_RAISE(traceme_raise5, SIGCONT) /* continued? */ 1821.85SkamilTRACEME_RAISE(traceme_raise6, SIGTRAP) /* crash signal */ 1831.85SkamilTRACEME_RAISE(traceme_raise7, SIGBUS) /* crash signal */ 1841.85SkamilTRACEME_RAISE(traceme_raise8, SIGILL) /* crash signal */ 1851.85SkamilTRACEME_RAISE(traceme_raise9, SIGFPE) /* crash signal */ 1861.85SkamilTRACEME_RAISE(traceme_raise10, SIGSEGV) /* crash signal */ 1871.33Skamil 1881.34Skamil/// ---------------------------------------------------------------------------- 1891.1Skamil 1901.1Skamilstatic void 1911.87Skamiltraceme_raisesignal_ignored(int sigignored) 1921.87Skamil{ 1931.87Skamil const int exitval = 5; 1941.87Skamil const int sigval = SIGSTOP; 1951.87Skamil pid_t child, wpid; 1961.87Skamil struct sigaction sa; 1971.87Skamil#if defined(TWAIT_HAVE_STATUS) 1981.87Skamil int status; 1991.87Skamil#endif 2001.87Skamil struct ptrace_siginfo info; 2011.87Skamil 2021.87Skamil memset(&info, 0, sizeof(info)); 2031.87Skamil 2041.87Skamil DPRINTF("Before forking process PID=%d\n", getpid()); 2051.87Skamil SYSCALL_REQUIRE((child = fork()) != -1); 2061.87Skamil if (child == 0) { 2071.87Skamil DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 2081.87Skamil FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 2091.87Skamil 2101.87Skamil memset(&sa, 0, sizeof(sa)); 2111.87Skamil sa.sa_handler = SIG_IGN; 2121.87Skamil sigemptyset(&sa.sa_mask); 2131.87Skamil FORKEE_ASSERT(sigaction(sigignored, &sa, NULL) != -1); 2141.87Skamil 2151.87Skamil DPRINTF("Before raising %s from child\n", strsignal(sigval)); 2161.87Skamil FORKEE_ASSERT(raise(sigval) == 0); 2171.87Skamil 2181.87Skamil DPRINTF("Before raising %s from child\n", 2191.87Skamil strsignal(sigignored)); 2201.87Skamil FORKEE_ASSERT(raise(sigignored) == 0); 2211.87Skamil 2221.87Skamil DPRINTF("Before exiting of the child process\n"); 2231.87Skamil _exit(exitval); 2241.87Skamil } 2251.87Skamil DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 2261.87Skamil 2271.87Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 2281.87Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 2291.87Skamil 2301.87Skamil validate_status_stopped(status, sigval); 2311.87Skamil 2321.87Skamil DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 2331.87Skamil SYSCALL_REQUIRE( 2341.87Skamil ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 2351.87Skamil 2361.87Skamil DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 2371.87Skamil DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 2381.87Skamil info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 2391.87Skamil info.psi_siginfo.si_errno); 2401.87Skamil 2411.87Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 2421.87Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 2431.87Skamil 2441.87Skamil DPRINTF("Before resuming the child process where it left off and " 2451.87Skamil "without signal to be sent\n"); 2461.87Skamil SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 2471.87Skamil 2481.87Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 2491.87Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 2501.87Skamil 2511.87Skamil validate_status_stopped(status, sigignored); 2521.87Skamil 2531.87Skamil DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 2541.87Skamil SYSCALL_REQUIRE( 2551.87Skamil ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 2561.87Skamil 2571.87Skamil DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 2581.87Skamil DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 2591.87Skamil info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 2601.87Skamil info.psi_siginfo.si_errno); 2611.87Skamil 2621.87Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigignored); 2631.87Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 2641.87Skamil 2651.87Skamil DPRINTF("Before resuming the child process where it left off and " 2661.87Skamil "without signal to be sent\n"); 2671.87Skamil SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 2681.87Skamil 2691.87Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 2701.87Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 2711.87Skamil 2721.87Skamil validate_status_exited(status, exitval); 2731.87Skamil 2741.87Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 2751.87Skamil TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 2761.87Skamil} 2771.87Skamil 2781.87Skamil#define TRACEME_RAISESIGNAL_IGNORED(test, sig) \ 2791.87SkamilATF_TC(test); \ 2801.87SkamilATF_TC_HEAD(test, tc) \ 2811.87Skamil{ \ 2821.87Skamil atf_tc_set_md_var(tc, "descr", \ 2831.87Skamil "Verify that ignoring (with SIG_IGN) " #sig " in tracee " \ 2841.87Skamil "does not stop tracer from catching this raised signal"); \ 2851.87Skamil} \ 2861.87Skamil \ 2871.87SkamilATF_TC_BODY(test, tc) \ 2881.87Skamil{ \ 2891.87Skamil \ 2901.87Skamil traceme_raisesignal_ignored(sig); \ 2911.87Skamil} 2921.87Skamil 2931.87Skamil// A signal handler for SIGKILL and SIGSTOP cannot be ignored. 2941.87SkamilTRACEME_RAISESIGNAL_IGNORED(traceme_raisesignal_ignored1, SIGABRT) /* abort */ 2951.87SkamilTRACEME_RAISESIGNAL_IGNORED(traceme_raisesignal_ignored2, SIGHUP) /* hangup */ 2961.87SkamilTRACEME_RAISESIGNAL_IGNORED(traceme_raisesignal_ignored3, SIGCONT) /* cont. */ 2971.87SkamilTRACEME_RAISESIGNAL_IGNORED(traceme_raisesignal_ignored4, SIGTRAP) /* crash */ 2981.87SkamilTRACEME_RAISESIGNAL_IGNORED(traceme_raisesignal_ignored5, SIGBUS) /* crash */ 2991.87SkamilTRACEME_RAISESIGNAL_IGNORED(traceme_raisesignal_ignored6, SIGILL) /* crash */ 3001.87SkamilTRACEME_RAISESIGNAL_IGNORED(traceme_raisesignal_ignored7, SIGFPE) /* crash */ 3011.87SkamilTRACEME_RAISESIGNAL_IGNORED(traceme_raisesignal_ignored8, SIGSEGV) /* crash */ 3021.87Skamil 3031.87Skamil/// ---------------------------------------------------------------------------- 3041.87Skamil 3051.87Skamilstatic void 3061.86Skamiltraceme_raisesignal_masked(int sigmasked) 3071.86Skamil{ 3081.86Skamil const int exitval = 5; 3091.86Skamil const int sigval = SIGSTOP; 3101.86Skamil pid_t child, wpid; 3111.86Skamil#if defined(TWAIT_HAVE_STATUS) 3121.86Skamil int status; 3131.86Skamil#endif 3141.86Skamil sigset_t intmask; 3151.86Skamil struct ptrace_siginfo info; 3161.86Skamil 3171.86Skamil memset(&info, 0, sizeof(info)); 3181.86Skamil 3191.86Skamil DPRINTF("Before forking process PID=%d\n", getpid()); 3201.86Skamil SYSCALL_REQUIRE((child = fork()) != -1); 3211.86Skamil if (child == 0) { 3221.86Skamil DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 3231.86Skamil FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 3241.86Skamil 3251.86Skamil sigemptyset(&intmask); 3261.86Skamil sigaddset(&intmask, sigmasked); 3271.86Skamil sigprocmask(SIG_BLOCK, &intmask, NULL); 3281.86Skamil 3291.86Skamil DPRINTF("Before raising %s from child\n", strsignal(sigval)); 3301.86Skamil FORKEE_ASSERT(raise(sigval) == 0); 3311.86Skamil 3321.86Skamil DPRINTF("Before raising %s breakpoint from child\n", 3331.86Skamil strsignal(sigmasked)); 3341.86Skamil FORKEE_ASSERT(raise(sigmasked) == 0); 3351.86Skamil 3361.86Skamil DPRINTF("Before exiting of the child process\n"); 3371.86Skamil _exit(exitval); 3381.86Skamil } 3391.86Skamil DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 3401.86Skamil 3411.86Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 3421.86Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 3431.86Skamil 3441.86Skamil validate_status_stopped(status, sigval); 3451.86Skamil 3461.86Skamil DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 3471.86Skamil SYSCALL_REQUIRE( 3481.86Skamil ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 3491.86Skamil 3501.86Skamil DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 3511.86Skamil DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 3521.86Skamil info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 3531.86Skamil info.psi_siginfo.si_errno); 3541.86Skamil 3551.86Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 3561.86Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 3571.86Skamil 3581.86Skamil DPRINTF("Before resuming the child process where it left off and " 3591.86Skamil "without signal to be sent\n"); 3601.86Skamil SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 3611.86Skamil 3621.86Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 3631.86Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 3641.86Skamil 3651.86Skamil validate_status_exited(status, exitval); 3661.86Skamil 3671.86Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 3681.86Skamil TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 3691.86Skamil} 3701.86Skamil 3711.86Skamil#define TRACEME_RAISESIGNAL_MASKED(test, sig) \ 3721.86SkamilATF_TC(test); \ 3731.86SkamilATF_TC_HEAD(test, tc) \ 3741.86Skamil{ \ 3751.86Skamil atf_tc_set_md_var(tc, "descr", \ 3761.86Skamil "Verify that masking (with SIG_BLOCK) " #sig " in tracee " \ 3771.86Skamil "stops tracer from catching this raised signal"); \ 3781.86Skamil} \ 3791.86Skamil \ 3801.86SkamilATF_TC_BODY(test, tc) \ 3811.86Skamil{ \ 3821.86Skamil \ 3831.86Skamil traceme_raisesignal_masked(sig); \ 3841.86Skamil} 3851.86Skamil 3861.86Skamil// A signal handler for SIGKILL and SIGSTOP cannot be masked. 3871.86SkamilTRACEME_RAISESIGNAL_MASKED(traceme_raisesignal_masked1, SIGABRT) /* abort trap */ 3881.86SkamilTRACEME_RAISESIGNAL_MASKED(traceme_raisesignal_masked2, SIGHUP) /* hangup */ 3891.86SkamilTRACEME_RAISESIGNAL_MASKED(traceme_raisesignal_masked3, SIGCONT) /* continued? */ 3901.86SkamilTRACEME_RAISESIGNAL_MASKED(traceme_raisesignal_masked4, SIGTRAP) /* crash sig. */ 3911.86SkamilTRACEME_RAISESIGNAL_MASKED(traceme_raisesignal_masked5, SIGBUS) /* crash sig. */ 3921.86SkamilTRACEME_RAISESIGNAL_MASKED(traceme_raisesignal_masked6, SIGILL) /* crash sig. */ 3931.86SkamilTRACEME_RAISESIGNAL_MASKED(traceme_raisesignal_masked7, SIGFPE) /* crash sig. */ 3941.86SkamilTRACEME_RAISESIGNAL_MASKED(traceme_raisesignal_masked8, SIGSEGV) /* crash sig. */ 3951.86Skamil 3961.86Skamil/// ---------------------------------------------------------------------------- 3971.86Skamil 3981.86Skamilstatic void 3991.59Skamiltraceme_crash(int sig) 4001.59Skamil{ 4011.59Skamil pid_t child, wpid; 4021.59Skamil#if defined(TWAIT_HAVE_STATUS) 4031.59Skamil int status; 4041.59Skamil#endif 4051.59Skamil struct ptrace_siginfo info; 4061.61Skre 4071.71Skamil#ifndef PTRACE_ILLEGAL_ASM 4081.71Skamil if (sig == SIGILL) 4091.71Skamil atf_tc_skip("PTRACE_ILLEGAL_ASM not defined"); 4101.71Skamil#endif 4111.71Skamil 4121.59Skamil memset(&info, 0, sizeof(info)); 4131.59Skamil 4141.59Skamil DPRINTF("Before forking process PID=%d\n", getpid()); 4151.59Skamil SYSCALL_REQUIRE((child = fork()) != -1); 4161.59Skamil if (child == 0) { 4171.59Skamil DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 4181.59Skamil FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 4191.59Skamil 4201.59Skamil DPRINTF("Before executing a trap\n"); 4211.59Skamil switch (sig) { 4221.59Skamil case SIGTRAP: 4231.59Skamil trigger_trap(); 4241.59Skamil break; 4251.59Skamil case SIGSEGV: 4261.59Skamil trigger_segv(); 4271.59Skamil break; 4281.59Skamil case SIGILL: 4291.59Skamil trigger_ill(); 4301.59Skamil break; 4311.59Skamil case SIGFPE: 4321.59Skamil trigger_fpe(); 4331.59Skamil break; 4341.59Skamil case SIGBUS: 4351.59Skamil trigger_bus(); 4361.59Skamil break; 4371.59Skamil default: 4381.59Skamil /* NOTREACHED */ 4391.59Skamil FORKEE_ASSERTX(0 && "This shall not be reached"); 4401.59Skamil } 4411.59Skamil 4421.59Skamil /* NOTREACHED */ 4431.59Skamil FORKEE_ASSERTX(0 && "This shall not be reached"); 4441.59Skamil } 4451.59Skamil DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 4461.59Skamil 4471.59Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4481.59Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4491.59Skamil 4501.59Skamil validate_status_stopped(status, sig); 4511.59Skamil 4521.59Skamil DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child"); 4531.61Skre SYSCALL_REQUIRE( 4541.61Skre ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 4551.59Skamil 4561.59Skamil DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 4571.59Skamil DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 4581.61Skre info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 4591.61Skre info.psi_siginfo.si_errno); 4601.59Skamil 4611.59Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sig); 4621.59Skamil switch (sig) { 4631.59Skamil case SIGTRAP: 4641.59Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_BRKPT); 4651.59Skamil break; 4661.59Skamil case SIGSEGV: 4671.59Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SEGV_MAPERR); 4681.59Skamil break; 4691.71Skamil case SIGILL: 4701.71Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_code, ILL_PRVOPC); 4711.71Skamil break; 4721.59Skamil case SIGFPE: 4731.59Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_code, FPE_INTDIV); 4741.59Skamil break; 4751.59Skamil case SIGBUS: 4761.59Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_code, BUS_ADRERR); 4771.59Skamil break; 4781.59Skamil } 4791.59Skamil 4801.59Skamil SYSCALL_REQUIRE(ptrace(PT_KILL, child, NULL, 0) != -1); 4811.59Skamil 4821.59Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4831.59Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4841.59Skamil 4851.59Skamil validate_status_signaled(status, SIGKILL, 0); 4861.59Skamil 4871.59Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4881.59Skamil TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 4891.59Skamil} 4901.59Skamil 4911.61Skre#define TRACEME_CRASH(test, sig) \ 4921.61SkreATF_TC(test); \ 4931.61SkreATF_TC_HEAD(test, tc) \ 4941.61Skre{ \ 4951.61Skre atf_tc_set_md_var(tc, "descr", \ 4961.61Skre "Verify crash signal " #sig " in a child after PT_TRACE_ME"); \ 4971.61Skre} \ 4981.61Skre \ 4991.61SkreATF_TC_BODY(test, tc) \ 5001.61Skre{ \ 5011.61Skre \ 5021.61Skre traceme_crash(sig); \ 5031.59Skamil} 5041.59Skamil 5051.59SkamilTRACEME_CRASH(traceme_crash_trap, SIGTRAP) 5061.59SkamilTRACEME_CRASH(traceme_crash_segv, SIGSEGV) 5071.71SkamilTRACEME_CRASH(traceme_crash_ill, SIGILL) 5081.59SkamilTRACEME_CRASH(traceme_crash_fpe, SIGFPE) 5091.59SkamilTRACEME_CRASH(traceme_crash_bus, SIGBUS) 5101.59Skamil 5111.59Skamil/// ---------------------------------------------------------------------------- 5121.59Skamil 5131.59Skamilstatic void 5141.88Skamiltraceme_signalmasked_crash(int sig) 5151.88Skamil{ 5161.88Skamil pid_t child, wpid; 5171.88Skamil#if defined(TWAIT_HAVE_STATUS) 5181.88Skamil int status; 5191.88Skamil#endif 5201.88Skamil struct ptrace_siginfo info; 5211.88Skamil sigset_t intmask; 5221.88Skamil 5231.88Skamil#ifndef PTRACE_ILLEGAL_ASM 5241.88Skamil if (sig == SIGILL) 5251.88Skamil atf_tc_skip("PTRACE_ILLEGAL_ASM not defined"); 5261.88Skamil#endif 5271.88Skamil 5281.88Skamil memset(&info, 0, sizeof(info)); 5291.88Skamil 5301.88Skamil DPRINTF("Before forking process PID=%d\n", getpid()); 5311.88Skamil SYSCALL_REQUIRE((child = fork()) != -1); 5321.88Skamil if (child == 0) { 5331.88Skamil DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 5341.88Skamil FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 5351.88Skamil 5361.88Skamil sigemptyset(&intmask); 5371.88Skamil sigaddset(&intmask, sig); 5381.88Skamil sigprocmask(SIG_BLOCK, &intmask, NULL); 5391.88Skamil 5401.88Skamil DPRINTF("Before executing a trap\n"); 5411.88Skamil switch (sig) { 5421.88Skamil case SIGTRAP: 5431.88Skamil trigger_trap(); 5441.88Skamil break; 5451.88Skamil case SIGSEGV: 5461.88Skamil trigger_segv(); 5471.88Skamil break; 5481.88Skamil case SIGILL: 5491.88Skamil trigger_ill(); 5501.88Skamil break; 5511.88Skamil case SIGFPE: 5521.88Skamil trigger_fpe(); 5531.88Skamil break; 5541.88Skamil case SIGBUS: 5551.88Skamil trigger_bus(); 5561.88Skamil break; 5571.88Skamil default: 5581.88Skamil /* NOTREACHED */ 5591.88Skamil FORKEE_ASSERTX(0 && "This shall not be reached"); 5601.88Skamil } 5611.88Skamil 5621.88Skamil /* NOTREACHED */ 5631.88Skamil FORKEE_ASSERTX(0 && "This shall not be reached"); 5641.88Skamil } 5651.88Skamil DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 5661.88Skamil 5671.88Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 5681.88Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5691.88Skamil 5701.88Skamil validate_status_stopped(status, sig); 5711.88Skamil 5721.88Skamil DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child"); 5731.88Skamil SYSCALL_REQUIRE( 5741.88Skamil ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 5751.88Skamil 5761.88Skamil DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 5771.88Skamil DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 5781.88Skamil info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 5791.88Skamil info.psi_siginfo.si_errno); 5801.88Skamil 5811.88Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sig); 5821.88Skamil switch (sig) { 5831.88Skamil case SIGTRAP: 5841.88Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_BRKPT); 5851.88Skamil break; 5861.88Skamil case SIGSEGV: 5871.88Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SEGV_MAPERR); 5881.88Skamil break; 5891.88Skamil case SIGILL: 5901.88Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_code, ILL_PRVOPC); 5911.88Skamil break; 5921.88Skamil case SIGFPE: 5931.88Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_code, FPE_INTDIV); 5941.88Skamil break; 5951.88Skamil case SIGBUS: 5961.88Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_code, BUS_ADRERR); 5971.88Skamil break; 5981.88Skamil } 5991.88Skamil 6001.88Skamil 6011.88Skamil 6021.88Skamil SYSCALL_REQUIRE(ptrace(PT_KILL, child, NULL, 0) != -1); 6031.88Skamil 6041.88Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 6051.88Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 6061.88Skamil 6071.88Skamil validate_status_signaled(status, SIGKILL, 0); 6081.88Skamil 6091.88Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 6101.88Skamil TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 6111.88Skamil} 6121.88Skamil 6131.88Skamil#define TRACEME_SIGNALMASKED_CRASH(test, sig) \ 6141.88SkamilATF_TC(test); \ 6151.88SkamilATF_TC_HEAD(test, tc) \ 6161.88Skamil{ \ 6171.88Skamil atf_tc_set_md_var(tc, "descr", \ 6181.88Skamil "Verify masked crash signal " #sig " in a child after " \ 6191.88Skamil "PT_TRACE_ME is delivered to its tracer"); \ 6201.88Skamil} \ 6211.88Skamil \ 6221.88SkamilATF_TC_BODY(test, tc) \ 6231.88Skamil{ \ 6241.88Skamil \ 6251.88Skamil traceme_signalmasked_crash(sig); \ 6261.88Skamil} 6271.88Skamil 6281.88SkamilTRACEME_SIGNALMASKED_CRASH(traceme_signalmasked_crash_trap, SIGTRAP) 6291.88SkamilTRACEME_SIGNALMASKED_CRASH(traceme_signalmasked_crash_segv, SIGSEGV) 6301.88SkamilTRACEME_SIGNALMASKED_CRASH(traceme_signalmasked_crash_ill, SIGILL) 6311.88SkamilTRACEME_SIGNALMASKED_CRASH(traceme_signalmasked_crash_fpe, SIGFPE) 6321.88SkamilTRACEME_SIGNALMASKED_CRASH(traceme_signalmasked_crash_bus, SIGBUS) 6331.88Skamil 6341.88Skamil/// ---------------------------------------------------------------------------- 6351.88Skamil 6361.88Skamilstatic void 6371.88Skamiltraceme_signalignored_crash(int sig) 6381.88Skamil{ 6391.88Skamil pid_t child, wpid; 6401.88Skamil#if defined(TWAIT_HAVE_STATUS) 6411.88Skamil int status; 6421.88Skamil#endif 6431.88Skamil struct sigaction sa; 6441.88Skamil struct ptrace_siginfo info; 6451.88Skamil 6461.88Skamil#ifndef PTRACE_ILLEGAL_ASM 6471.88Skamil if (sig == SIGILL) 6481.88Skamil atf_tc_skip("PTRACE_ILLEGAL_ASM not defined"); 6491.88Skamil#endif 6501.88Skamil 6511.88Skamil memset(&info, 0, sizeof(info)); 6521.88Skamil 6531.88Skamil DPRINTF("Before forking process PID=%d\n", getpid()); 6541.88Skamil SYSCALL_REQUIRE((child = fork()) != -1); 6551.88Skamil if (child == 0) { 6561.88Skamil DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 6571.88Skamil FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 6581.88Skamil 6591.88Skamil memset(&sa, 0, sizeof(sa)); 6601.88Skamil sa.sa_handler = SIG_IGN; 6611.88Skamil sigemptyset(&sa.sa_mask); 6621.88Skamil 6631.88Skamil FORKEE_ASSERT(sigaction(sig, &sa, NULL) != -1); 6641.88Skamil 6651.88Skamil DPRINTF("Before executing a trap\n"); 6661.88Skamil switch (sig) { 6671.88Skamil case SIGTRAP: 6681.88Skamil trigger_trap(); 6691.88Skamil break; 6701.88Skamil case SIGSEGV: 6711.88Skamil trigger_segv(); 6721.88Skamil break; 6731.88Skamil case SIGILL: 6741.88Skamil trigger_ill(); 6751.88Skamil break; 6761.88Skamil case SIGFPE: 6771.88Skamil trigger_fpe(); 6781.88Skamil break; 6791.88Skamil case SIGBUS: 6801.88Skamil trigger_bus(); 6811.88Skamil break; 6821.88Skamil default: 6831.88Skamil /* NOTREACHED */ 6841.88Skamil FORKEE_ASSERTX(0 && "This shall not be reached"); 6851.88Skamil } 6861.88Skamil 6871.88Skamil /* NOTREACHED */ 6881.88Skamil FORKEE_ASSERTX(0 && "This shall not be reached"); 6891.88Skamil } 6901.88Skamil DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 6911.88Skamil 6921.88Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 6931.88Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 6941.88Skamil 6951.88Skamil validate_status_stopped(status, sig); 6961.88Skamil 6971.88Skamil DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child"); 6981.88Skamil SYSCALL_REQUIRE( 6991.88Skamil ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 7001.88Skamil 7011.88Skamil DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 7021.88Skamil DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 7031.88Skamil info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 7041.88Skamil info.psi_siginfo.si_errno); 7051.88Skamil 7061.88Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sig); 7071.88Skamil switch (sig) { 7081.88Skamil case SIGTRAP: 7091.88Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_BRKPT); 7101.88Skamil break; 7111.88Skamil case SIGSEGV: 7121.88Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SEGV_MAPERR); 7131.88Skamil break; 7141.88Skamil case SIGILL: 7151.88Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_code, ILL_PRVOPC); 7161.88Skamil break; 7171.88Skamil case SIGFPE: 7181.88Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_code, FPE_INTDIV); 7191.88Skamil break; 7201.88Skamil case SIGBUS: 7211.88Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_code, BUS_ADRERR); 7221.88Skamil break; 7231.88Skamil } 7241.88Skamil 7251.88Skamil SYSCALL_REQUIRE(ptrace(PT_KILL, child, NULL, 0) != -1); 7261.88Skamil 7271.88Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 7281.88Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 7291.88Skamil 7301.88Skamil validate_status_signaled(status, SIGKILL, 0); 7311.88Skamil 7321.88Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 7331.88Skamil TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 7341.88Skamil} 7351.88Skamil 7361.88Skamil#define TRACEME_SIGNALIGNORED_CRASH(test, sig) \ 7371.88SkamilATF_TC(test); \ 7381.88SkamilATF_TC_HEAD(test, tc) \ 7391.88Skamil{ \ 7401.88Skamil atf_tc_set_md_var(tc, "descr", \ 7411.88Skamil "Verify ignored crash signal " #sig " in a child after " \ 7421.88Skamil "PT_TRACE_ME is delivered to its tracer"); \ 7431.88Skamil} \ 7441.88Skamil \ 7451.88SkamilATF_TC_BODY(test, tc) \ 7461.88Skamil{ \ 7471.88Skamil \ 7481.88Skamil traceme_signalignored_crash(sig); \ 7491.88Skamil} 7501.88Skamil 7511.88SkamilTRACEME_SIGNALIGNORED_CRASH(traceme_signalignored_crash_trap, SIGTRAP) 7521.88SkamilTRACEME_SIGNALIGNORED_CRASH(traceme_signalignored_crash_segv, SIGSEGV) 7531.88SkamilTRACEME_SIGNALIGNORED_CRASH(traceme_signalignored_crash_ill, SIGILL) 7541.88SkamilTRACEME_SIGNALIGNORED_CRASH(traceme_signalignored_crash_fpe, SIGFPE) 7551.88SkamilTRACEME_SIGNALIGNORED_CRASH(traceme_signalignored_crash_bus, SIGBUS) 7561.88Skamil 7571.88Skamil/// ---------------------------------------------------------------------------- 7581.88Skamil 7591.88Skamilstatic void 7601.50Skamiltraceme_sendsignal_handle(int sigsent, void (*sah)(int a), int *traceme_caught) 7611.1Skamil{ 7621.1Skamil const int exitval = 5; 7631.34Skamil const int sigval = SIGSTOP; 7641.1Skamil pid_t child, wpid; 7651.1Skamil struct sigaction sa; 7661.1Skamil#if defined(TWAIT_HAVE_STATUS) 7671.1Skamil int status; 7681.1Skamil#endif 7691.61Skre struct ptrace_siginfo info; 7701.1Skamil 7711.45Skamil memset(&info, 0, sizeof(info)); 7721.45Skamil 7731.13Schristos DPRINTF("Before forking process PID=%d\n", getpid()); 7741.13Schristos SYSCALL_REQUIRE((child = fork()) != -1); 7751.1Skamil if (child == 0) { 7761.13Schristos DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 7771.1Skamil FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 7781.1Skamil 7791.34Skamil sa.sa_handler = sah; 7801.1Skamil sa.sa_flags = SA_SIGINFO; 7811.1Skamil sigemptyset(&sa.sa_mask); 7821.1Skamil 7831.1Skamil FORKEE_ASSERT(sigaction(sigsent, &sa, NULL) != -1); 7841.1Skamil 7851.13Schristos DPRINTF("Before raising %s from child\n", strsignal(sigval)); 7861.1Skamil FORKEE_ASSERT(raise(sigval) == 0); 7871.1Skamil 7881.34Skamil FORKEE_ASSERT_EQ(*traceme_caught, 1); 7891.1Skamil 7901.13Schristos DPRINTF("Before exiting of the child process\n"); 7911.1Skamil _exit(exitval); 7921.1Skamil } 7931.13Schristos DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 7941.1Skamil 7951.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 7961.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 7971.1Skamil 7981.1Skamil validate_status_stopped(status, sigval); 7991.1Skamil 8001.45Skamil DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 8011.61Skre SYSCALL_REQUIRE( 8021.61Skre ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 8031.45Skamil 8041.45Skamil DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 8051.45Skamil DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 8061.45Skamil info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 8071.45Skamil info.psi_siginfo.si_errno); 8081.45Skamil 8091.45Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 8101.45Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 8111.45Skamil 8121.13Schristos DPRINTF("Before resuming the child process where it left off and with " 8131.1Skamil "signal %s to be sent\n", strsignal(sigsent)); 8141.13Schristos SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigsent) != -1); 8151.1Skamil 8161.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 8171.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 8181.1Skamil 8191.1Skamil validate_status_exited(status, exitval); 8201.1Skamil 8211.13Schristos DPRINTF("Before calling %s() for the exited child\n", TWAIT_FNAME); 8221.1Skamil TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 8231.1Skamil} 8241.1Skamil 8251.61Skre#define TRACEME_SENDSIGNAL_HANDLE(test, sig) \ 8261.61SkreATF_TC(test); \ 8271.61SkreATF_TC_HEAD(test, tc) \ 8281.61Skre{ \ 8291.61Skre atf_tc_set_md_var(tc, "descr", \ 8301.61Skre "Verify that a signal " #sig " emitted by a tracer to a child is " \ 8311.61Skre "handled correctly and caught by a signal handler"); \ 8321.61Skre} \ 8331.61Skre \ 8341.61Skrestatic int test##_caught = 0; \ 8351.61Skre \ 8361.61Skrestatic void \ 8371.61Skretest##_sighandler(int arg) \ 8381.61Skre{ \ 8391.61Skre FORKEE_ASSERT_EQ(arg, sig); \ 8401.61Skre \ 8411.61Skre ++ test##_caught; \ 8421.61Skre} \ 8431.61Skre \ 8441.61SkreATF_TC_BODY(test, tc) \ 8451.61Skre{ \ 8461.61Skre \ 8471.61Skre traceme_sendsignal_handle(sig, test##_sighandler, & test##_caught); \ 8481.34Skamil} 8491.34Skamil 8501.34Skamil// A signal handler for SIGKILL and SIGSTOP cannot be registered. 8511.50SkamilTRACEME_SENDSIGNAL_HANDLE(traceme_sendsignal_handle1, SIGABRT) /* abort trap */ 8521.50SkamilTRACEME_SENDSIGNAL_HANDLE(traceme_sendsignal_handle2, SIGHUP) /* hangup */ 8531.50SkamilTRACEME_SENDSIGNAL_HANDLE(traceme_sendsignal_handle3, SIGCONT) /* continued? */ 8541.85SkamilTRACEME_SENDSIGNAL_HANDLE(traceme_sendsignal_handle4, SIGTRAP) /* crash sig. */ 8551.85SkamilTRACEME_SENDSIGNAL_HANDLE(traceme_sendsignal_handle5, SIGBUS) /* crash sig. */ 8561.85SkamilTRACEME_SENDSIGNAL_HANDLE(traceme_sendsignal_handle6, SIGILL) /* crash sig. */ 8571.85SkamilTRACEME_SENDSIGNAL_HANDLE(traceme_sendsignal_handle7, SIGFPE) /* crash sig. */ 8581.85SkamilTRACEME_SENDSIGNAL_HANDLE(traceme_sendsignal_handle8, SIGSEGV) /* crash sig. */ 8591.34Skamil 8601.34Skamil/// ---------------------------------------------------------------------------- 8611.34Skamil 8621.35Skamilstatic void 8631.50Skamiltraceme_sendsignal_masked(int sigsent) 8641.50Skamil{ 8651.50Skamil const int exitval = 5; 8661.50Skamil const int sigval = SIGSTOP; 8671.50Skamil pid_t child, wpid; 8681.50Skamil sigset_t set; 8691.50Skamil#if defined(TWAIT_HAVE_STATUS) 8701.50Skamil int status; 8711.50Skamil#endif 8721.61Skre struct ptrace_siginfo info; 8731.50Skamil 8741.50Skamil memset(&info, 0, sizeof(info)); 8751.50Skamil 8761.50Skamil DPRINTF("Before forking process PID=%d\n", getpid()); 8771.50Skamil SYSCALL_REQUIRE((child = fork()) != -1); 8781.50Skamil if (child == 0) { 8791.50Skamil DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 8801.50Skamil FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 8811.50Skamil 8821.50Skamil sigemptyset(&set); 8831.50Skamil sigaddset(&set, sigsent); 8841.50Skamil FORKEE_ASSERT(sigprocmask(SIG_BLOCK, &set, NULL) != -1); 8851.50Skamil 8861.50Skamil DPRINTF("Before raising %s from child\n", strsignal(sigval)); 8871.50Skamil FORKEE_ASSERT(raise(sigval) == 0); 8881.50Skamil 8891.50Skamil _exit(exitval); 8901.50Skamil } 8911.50Skamil DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 8921.50Skamil 8931.50Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 8941.50Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 8951.50Skamil 8961.50Skamil validate_status_stopped(status, sigval); 8971.50Skamil 8981.50Skamil DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 8991.61Skre SYSCALL_REQUIRE( 9001.61Skre ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 9011.50Skamil 9021.50Skamil DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 9031.50Skamil DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 9041.50Skamil info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 9051.50Skamil info.psi_siginfo.si_errno); 9061.50Skamil 9071.50Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 9081.50Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 9091.50Skamil 9101.50Skamil DPRINTF("Before resuming the child process where it left off and with " 9111.50Skamil "signal %s to be sent\n", strsignal(sigsent)); 9121.50Skamil SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigsent) != -1); 9131.50Skamil 9141.50Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 9151.50Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 9161.50Skamil 9171.50Skamil validate_status_exited(status, exitval); 9181.50Skamil 9191.50Skamil DPRINTF("Before calling %s() for the exited child\n", TWAIT_FNAME); 9201.50Skamil TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 9211.50Skamil} 9221.50Skamil 9231.61Skre#define TRACEME_SENDSIGNAL_MASKED(test, sig) \ 9241.61SkreATF_TC(test); \ 9251.61SkreATF_TC_HEAD(test, tc) \ 9261.61Skre{ \ 9271.61Skre atf_tc_set_md_var(tc, "descr", \ 9281.61Skre "Verify that a signal " #sig " emitted by a tracer to a child is " \ 9291.61Skre "handled correctly and the signal is masked by SIG_BLOCK"); \ 9301.61Skre} \ 9311.61Skre \ 9321.61SkreATF_TC_BODY(test, tc) \ 9331.61Skre{ \ 9341.61Skre \ 9351.61Skre traceme_sendsignal_masked(sig); \ 9361.50Skamil} 9371.50Skamil 9381.50Skamil// A signal handler for SIGKILL and SIGSTOP cannot be masked. 9391.50SkamilTRACEME_SENDSIGNAL_MASKED(traceme_sendsignal_masked1, SIGABRT) /* abort trap */ 9401.50SkamilTRACEME_SENDSIGNAL_MASKED(traceme_sendsignal_masked2, SIGHUP) /* hangup */ 9411.50SkamilTRACEME_SENDSIGNAL_MASKED(traceme_sendsignal_masked3, SIGCONT) /* continued? */ 9421.85SkamilTRACEME_SENDSIGNAL_MASKED(traceme_sendsignal_masked4, SIGTRAP) /* crash sig. */ 9431.85SkamilTRACEME_SENDSIGNAL_MASKED(traceme_sendsignal_masked5, SIGBUS) /* crash sig. */ 9441.85SkamilTRACEME_SENDSIGNAL_MASKED(traceme_sendsignal_masked6, SIGILL) /* crash sig. */ 9451.85SkamilTRACEME_SENDSIGNAL_MASKED(traceme_sendsignal_masked7, SIGFPE) /* crash sig. */ 9461.85SkamilTRACEME_SENDSIGNAL_MASKED(traceme_sendsignal_masked8, SIGSEGV) /* crash sig. */ 9471.50Skamil 9481.50Skamil/// ---------------------------------------------------------------------------- 9491.50Skamil 9501.50Skamilstatic void 9511.50Skamiltraceme_sendsignal_ignored(int sigsent) 9521.50Skamil{ 9531.50Skamil const int exitval = 5; 9541.50Skamil const int sigval = SIGSTOP; 9551.50Skamil pid_t child, wpid; 9561.50Skamil struct sigaction sa; 9571.50Skamil#if defined(TWAIT_HAVE_STATUS) 9581.50Skamil int status; 9591.50Skamil#endif 9601.61Skre struct ptrace_siginfo info; 9611.50Skamil 9621.50Skamil memset(&info, 0, sizeof(info)); 9631.50Skamil 9641.50Skamil DPRINTF("Before forking process PID=%d\n", getpid()); 9651.50Skamil SYSCALL_REQUIRE((child = fork()) != -1); 9661.50Skamil if (child == 0) { 9671.50Skamil DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 9681.61Skre 9691.50Skamil FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 9701.50Skamil 9711.50Skamil memset(&sa, 0, sizeof(sa)); 9721.50Skamil sa.sa_handler = SIG_IGN; 9731.50Skamil sigemptyset(&sa.sa_mask); 9741.50Skamil FORKEE_ASSERT(sigaction(sigsent, &sa, NULL) != -1); 9751.50Skamil 9761.50Skamil DPRINTF("Before raising %s from child\n", strsignal(sigval)); 9771.50Skamil FORKEE_ASSERT(raise(sigval) == 0); 9781.50Skamil 9791.50Skamil _exit(exitval); 9801.50Skamil } 9811.50Skamil DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 9821.50Skamil 9831.50Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 9841.50Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 9851.50Skamil 9861.50Skamil validate_status_stopped(status, sigval); 9871.50Skamil 9881.50Skamil DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 9891.61Skre SYSCALL_REQUIRE( 9901.61Skre ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 9911.50Skamil 9921.50Skamil DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 9931.50Skamil DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 9941.50Skamil info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 9951.50Skamil info.psi_siginfo.si_errno); 9961.50Skamil 9971.50Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 9981.50Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 9991.50Skamil 10001.50Skamil DPRINTF("Before resuming the child process where it left off and with " 10011.50Skamil "signal %s to be sent\n", strsignal(sigsent)); 10021.50Skamil SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigsent) != -1); 10031.50Skamil 10041.50Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 10051.50Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 10061.50Skamil 10071.50Skamil validate_status_exited(status, exitval); 10081.50Skamil 10091.50Skamil DPRINTF("Before calling %s() for the exited child\n", TWAIT_FNAME); 10101.50Skamil TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 10111.50Skamil} 10121.50Skamil 10131.61Skre#define TRACEME_SENDSIGNAL_IGNORED(test, sig) \ 10141.61SkreATF_TC(test); \ 10151.61SkreATF_TC_HEAD(test, tc) \ 10161.61Skre{ \ 10171.61Skre atf_tc_set_md_var(tc, "descr", \ 10181.61Skre "Verify that a signal " #sig " emitted by a tracer to a child is " \ 10191.61Skre "handled correctly and the signal is masked by SIG_IGN"); \ 10201.61Skre} \ 10211.61Skre \ 10221.61SkreATF_TC_BODY(test, tc) \ 10231.61Skre{ \ 10241.61Skre \ 10251.61Skre traceme_sendsignal_ignored(sig); \ 10261.50Skamil} 10271.50Skamil 10281.50Skamil// A signal handler for SIGKILL and SIGSTOP cannot be ignored. 10291.61SkreTRACEME_SENDSIGNAL_IGNORED(traceme_sendsignal_ignored1, SIGABRT) /* abort */ 10301.50SkamilTRACEME_SENDSIGNAL_IGNORED(traceme_sendsignal_ignored2, SIGHUP) /* hangup */ 10311.61SkreTRACEME_SENDSIGNAL_IGNORED(traceme_sendsignal_ignored3, SIGCONT) /* continued */ 10321.85SkamilTRACEME_SENDSIGNAL_IGNORED(traceme_sendsignal_ignored4, SIGTRAP) /* crash s. */ 10331.85SkamilTRACEME_SENDSIGNAL_IGNORED(traceme_sendsignal_ignored5, SIGBUS) /* crash s. */ 10341.85SkamilTRACEME_SENDSIGNAL_IGNORED(traceme_sendsignal_ignored6, SIGILL) /* crash s. */ 10351.85SkamilTRACEME_SENDSIGNAL_IGNORED(traceme_sendsignal_ignored7, SIGFPE) /* crash s. */ 10361.85SkamilTRACEME_SENDSIGNAL_IGNORED(traceme_sendsignal_ignored8, SIGSEGV) /* crash s. */ 10371.50Skamil 10381.50Skamil/// ---------------------------------------------------------------------------- 10391.50Skamil 10401.50Skamilstatic void 10411.50Skamiltraceme_sendsignal_simple(int sigsent) 10421.1Skamil{ 10431.35Skamil const int sigval = SIGSTOP; 10441.35Skamil int exitval = 0; 10451.1Skamil pid_t child, wpid; 10461.1Skamil#if defined(TWAIT_HAVE_STATUS) 10471.1Skamil int status; 10481.85Skamil int expect_core; 10491.85Skamil 10501.85Skamil switch (sigsent) { 10511.85Skamil case SIGABRT: 10521.85Skamil case SIGTRAP: 10531.85Skamil case SIGBUS: 10541.85Skamil case SIGILL: 10551.85Skamil case SIGFPE: 10561.85Skamil case SIGSEGV: 10571.85Skamil expect_core = 1; 10581.85Skamil break; 10591.85Skamil default: 10601.85Skamil expect_core = 0; 10611.85Skamil break; 10621.85Skamil } 10631.1Skamil#endif 10641.61Skre struct ptrace_siginfo info; 10651.1Skamil 10661.45Skamil memset(&info, 0, sizeof(info)); 10671.45Skamil 10681.13Schristos DPRINTF("Before forking process PID=%d\n", getpid()); 10691.13Schristos SYSCALL_REQUIRE((child = fork()) != -1); 10701.1Skamil if (child == 0) { 10711.13Schristos DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 10721.1Skamil FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 10731.1Skamil 10741.13Schristos DPRINTF("Before raising %s from child\n", strsignal(sigval)); 10751.1Skamil FORKEE_ASSERT(raise(sigval) == 0); 10761.1Skamil 10771.35Skamil switch (sigsent) { 10781.35Skamil case SIGCONT: 10791.48Skamil case SIGSTOP: 10801.35Skamil _exit(exitval); 10811.35Skamil default: 10821.35Skamil /* NOTREACHED */ 10831.35Skamil FORKEE_ASSERTX(0 && "This shall not be reached"); 10841.35Skamil } 10851.1Skamil } 10861.13Schristos DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 10871.1Skamil 10881.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 10891.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 10901.1Skamil 10911.1Skamil validate_status_stopped(status, sigval); 10921.1Skamil 10931.45Skamil DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 10941.61Skre SYSCALL_REQUIRE( 10951.61Skre ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 10961.45Skamil 10971.45Skamil DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 10981.45Skamil DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 10991.45Skamil info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 11001.45Skamil info.psi_siginfo.si_errno); 11011.45Skamil 11021.45Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 11031.45Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 11041.45Skamil 11051.13Schristos DPRINTF("Before resuming the child process where it left off and with " 11061.1Skamil "signal %s to be sent\n", strsignal(sigsent)); 11071.13Schristos SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigsent) != -1); 11081.1Skamil 11091.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 11101.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 11111.1Skamil 11121.35Skamil switch (sigsent) { 11131.48Skamil case SIGSTOP: 11141.48Skamil validate_status_stopped(status, sigsent); 11151.48Skamil DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for " 11161.61Skre "child\n"); 11171.48Skamil SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, 11181.61Skre sizeof(info)) != -1); 11191.48Skamil 11201.48Skamil DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 11211.48Skamil DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 11221.61Skre "si_errno=%#x\n", 11231.61Skre info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 11241.61Skre info.psi_siginfo.si_errno); 11251.48Skamil 11261.48Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 11271.48Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 11281.48Skamil 11291.48Skamil DPRINTF("Before resuming the child process where it left off " 11301.61Skre "and with signal %s to be sent\n", strsignal(sigsent)); 11311.48Skamil SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 11321.48Skamil 11331.48Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 11341.48Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), 11351.61Skre child); 11361.48Skamil /* FALLTHROUGH */ 11371.35Skamil case SIGCONT: 11381.35Skamil validate_status_exited(status, exitval); 11391.35Skamil break; 11401.35Skamil default: 11411.35Skamil validate_status_signaled(status, sigsent, expect_core); 11421.35Skamil break; 11431.35Skamil } 11441.1Skamil 11451.13Schristos DPRINTF("Before calling %s() for the exited child\n", TWAIT_FNAME); 11461.1Skamil TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 11471.1Skamil} 11481.1Skamil 11491.61Skre#define TRACEME_SENDSIGNAL_SIMPLE(test, sig) \ 11501.61SkreATF_TC(test); \ 11511.61SkreATF_TC_HEAD(test, tc) \ 11521.61Skre{ \ 11531.61Skre atf_tc_set_md_var(tc, "descr", \ 11541.61Skre "Verify that a signal " #sig " emitted by a tracer to a child is " \ 11551.61Skre "handled correctly in a child without a signal handler"); \ 11561.61Skre} \ 11571.61Skre \ 11581.61SkreATF_TC_BODY(test, tc) \ 11591.61Skre{ \ 11601.61Skre \ 11611.61Skre traceme_sendsignal_simple(sig); \ 11621.35Skamil} 11631.35Skamil 11641.61SkreTRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple1, SIGKILL) /* non-maskable*/ 11651.61SkreTRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple2, SIGSTOP) /* non-maskable*/ 11661.50SkamilTRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple3, SIGABRT) /* abort trap */ 11671.50SkamilTRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple4, SIGHUP) /* hangup */ 11681.50SkamilTRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple5, SIGCONT) /* continued? */ 11691.85SkamilTRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple6, SIGTRAP) /* crash sig. */ 11701.85SkamilTRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple7, SIGBUS) /* crash sig. */ 11711.85SkamilTRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple8, SIGILL) /* crash sig. */ 11721.85SkamilTRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple9, SIGFPE) /* crash sig. */ 11731.85SkamilTRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple10, SIGSEGV) /* crash sig. */ 11741.35Skamil 11751.35Skamil/// ---------------------------------------------------------------------------- 11761.35Skamil 11771.37SkamilATF_TC(traceme_pid1_parent); 11781.37SkamilATF_TC_HEAD(traceme_pid1_parent, tc) 11791.37Skamil{ 11801.37Skamil atf_tc_set_md_var(tc, "descr", 11811.37Skamil "Verify that PT_TRACE_ME is not allowed when our parent is PID1"); 11821.37Skamil} 11831.37Skamil 11841.37SkamilATF_TC_BODY(traceme_pid1_parent, tc) 11851.37Skamil{ 11861.37Skamil struct msg_fds parent_child; 11871.37Skamil int exitval_child1 = 1, exitval_child2 = 2; 11881.37Skamil pid_t child1, child2, wpid; 11891.37Skamil uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */ 11901.37Skamil#if defined(TWAIT_HAVE_STATUS) 11911.37Skamil int status; 11921.37Skamil#endif 11931.37Skamil 11941.37Skamil SYSCALL_REQUIRE(msg_open(&parent_child) == 0); 11951.37Skamil 11961.37Skamil DPRINTF("Before forking process PID=%d\n", getpid()); 11971.37Skamil SYSCALL_REQUIRE((child1 = fork()) != -1); 11981.37Skamil if (child1 == 0) { 11991.37Skamil DPRINTF("Before forking process PID=%d\n", getpid()); 12001.37Skamil SYSCALL_REQUIRE((child2 = fork()) != -1); 12011.37Skamil if (child2 != 0) { 12021.37Skamil DPRINTF("Parent process PID=%d, child2's PID=%d\n", 12031.61Skre getpid(), child2); 12041.37Skamil _exit(exitval_child1); 12051.37Skamil } 12061.37Skamil CHILD_FROM_PARENT("exit child1", parent_child, msg); 12071.37Skamil 12081.37Skamil DPRINTF("Assert that our parent is PID1 (initproc)\n"); 12091.37Skamil FORKEE_ASSERT_EQ(getppid(), 1); 12101.37Skamil 12111.37Skamil DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 12121.37Skamil FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) == -1); 12131.37Skamil SYSCALL_REQUIRE_ERRNO(errno, EPERM); 12141.37Skamil 12151.37Skamil CHILD_TO_PARENT("child2 exiting", parent_child, msg); 12161.37Skamil 12171.37Skamil _exit(exitval_child2); 12181.37Skamil } 12191.37Skamil DPRINTF("Parent process PID=%d, child1's PID=%d\n", getpid(), child1); 12201.37Skamil 12211.37Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 12221.61Skre TWAIT_REQUIRE_SUCCESS( 12231.61Skre wpid = TWAIT_GENERIC(child1, &status, WEXITED), child1); 12241.37Skamil 12251.37Skamil validate_status_exited(status, exitval_child1); 12261.37Skamil 12271.37Skamil DPRINTF("Notify that child1 is dead\n"); 12281.37Skamil PARENT_TO_CHILD("exit child1", parent_child, msg); 12291.37Skamil 12301.37Skamil DPRINTF("Wait for exiting of child2\n"); 12311.37Skamil PARENT_FROM_CHILD("child2 exiting", parent_child, msg); 12321.37Skamil} 12331.37Skamil 12341.37Skamil/// ---------------------------------------------------------------------------- 12351.37Skamil 12361.40Skamilstatic void 12371.40Skamiltraceme_vfork_raise(int sigval) 12381.40Skamil{ 12391.46Skamil const int exitval = 5, exitval_watcher = 10; 12401.46Skamil pid_t child, parent, watcher, wpid; 12411.46Skamil int rv; 12421.40Skamil#if defined(TWAIT_HAVE_STATUS) 12431.40Skamil int status; 12441.85Skamil 12451.85Skamil /* volatile workarounds GCC -Werror=clobbered */ 12461.85Skamil volatile int expect_core; 12471.85Skamil 12481.85Skamil switch (sigval) { 12491.85Skamil case SIGABRT: 12501.85Skamil case SIGTRAP: 12511.85Skamil case SIGBUS: 12521.85Skamil case SIGILL: 12531.85Skamil case SIGFPE: 12541.85Skamil case SIGSEGV: 12551.85Skamil expect_core = 1; 12561.85Skamil break; 12571.85Skamil default: 12581.85Skamil expect_core = 0; 12591.85Skamil break; 12601.85Skamil } 12611.40Skamil#endif 12621.40Skamil 12631.46Skamil /* 12641.46Skamil * Spawn a dedicated thread to watch for a stopped child and emit 12651.46Skamil * the SIGKILL signal to it. 12661.46Skamil * 12671.46Skamil * vfork(2) might clobber watcher, this means that it's safer and 12681.46Skamil * simpler to reparent this process to initproc and forget about it. 12691.46Skamil */ 12701.46Skamil if (sigval == SIGSTOP) { 12711.46Skamil parent = getpid(); 12721.46Skamil 12731.46Skamil watcher = fork(); 12741.46Skamil ATF_REQUIRE(watcher != 1); 12751.46Skamil if (watcher == 0) { 12761.46Skamil /* Double fork(2) trick to reparent to initproc */ 12771.46Skamil watcher = fork(); 12781.46Skamil FORKEE_ASSERT_NEQ(watcher, -1); 12791.46Skamil if (watcher != 0) 12801.46Skamil _exit(exitval_watcher); 12811.46Skamil 12821.46Skamil child = await_stopped_child(parent); 12831.46Skamil 12841.46Skamil errno = 0; 12851.46Skamil rv = kill(child, SIGKILL); 12861.46Skamil FORKEE_ASSERT_EQ(rv, 0); 12871.46Skamil FORKEE_ASSERT_EQ(errno, 0); 12881.46Skamil 12891.46Skamil /* This exit value will be collected by initproc */ 12901.46Skamil _exit(0); 12911.46Skamil } 12921.46Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 12931.46Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(watcher, &status, 0), 12941.61Skre watcher); 12951.46Skamil 12961.46Skamil validate_status_exited(status, exitval_watcher); 12971.46Skamil 12981.46Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 12991.61Skre TWAIT_REQUIRE_FAILURE(ECHILD, 13001.61Skre wpid = TWAIT_GENERIC(watcher, &status, 0)); 13011.46Skamil } 13021.46Skamil 13031.40Skamil DPRINTF("Before forking process PID=%d\n", getpid()); 13041.40Skamil SYSCALL_REQUIRE((child = vfork()) != -1); 13051.40Skamil if (child == 0) { 13061.40Skamil DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 13071.40Skamil FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 13081.40Skamil 13091.40Skamil DPRINTF("Before raising %s from child\n", strsignal(sigval)); 13101.40Skamil FORKEE_ASSERT(raise(sigval) == 0); 13111.40Skamil 13121.40Skamil switch (sigval) { 13131.46Skamil case SIGSTOP: 13141.40Skamil case SIGKILL: 13151.40Skamil case SIGABRT: 13161.40Skamil case SIGHUP: 13171.85Skamil case SIGTRAP: 13181.85Skamil case SIGBUS: 13191.85Skamil case SIGILL: 13201.85Skamil case SIGFPE: 13211.85Skamil case SIGSEGV: 13221.40Skamil /* NOTREACHED */ 13231.40Skamil FORKEE_ASSERTX(0 && "This shall not be reached"); 13241.70Smrg __unreachable(); 13251.40Skamil default: 13261.40Skamil DPRINTF("Before exiting of the child process\n"); 13271.40Skamil _exit(exitval); 13281.40Skamil } 13291.40Skamil } 13301.40Skamil DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 13311.40Skamil 13321.40Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 13331.40Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 13341.40Skamil 13351.40Skamil switch (sigval) { 13361.40Skamil case SIGKILL: 13371.40Skamil case SIGABRT: 13381.40Skamil case SIGHUP: 13391.85Skamil case SIGTRAP: 13401.85Skamil case SIGBUS: 13411.85Skamil case SIGILL: 13421.85Skamil case SIGFPE: 13431.85Skamil case SIGSEGV: 13441.40Skamil validate_status_signaled(status, sigval, expect_core); 13451.40Skamil break; 13461.40Skamil case SIGSTOP: 13471.46Skamil validate_status_signaled(status, SIGKILL, 0); 13481.46Skamil break; 13491.40Skamil case SIGCONT: 13501.47Skamil case SIGTSTP: 13511.47Skamil case SIGTTIN: 13521.47Skamil case SIGTTOU: 13531.40Skamil validate_status_exited(status, exitval); 13541.40Skamil break; 13551.40Skamil default: 13561.40Skamil /* NOTREACHED */ 13571.40Skamil ATF_REQUIRE(0 && "NOT IMPLEMENTED"); 13581.40Skamil break; 13591.40Skamil } 13601.40Skamil 13611.40Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 13621.40Skamil TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 13631.40Skamil} 13641.40Skamil 13651.61Skre#define TRACEME_VFORK_RAISE(test, sig) \ 13661.61SkreATF_TC(test); \ 13671.61SkreATF_TC_HEAD(test, tc) \ 13681.61Skre{ \ 13691.61Skre atf_tc_set_md_var(tc, "descr", \ 13701.61Skre "Verify PT_TRACE_ME followed by raise of " #sig " in a " \ 13711.61Skre "vfork(2)ed child"); \ 13721.61Skre} \ 13731.61Skre \ 13741.61SkreATF_TC_BODY(test, tc) \ 13751.61Skre{ \ 13761.61Skre \ 13771.61Skre traceme_vfork_raise(sig); \ 13781.40Skamil} 13791.40Skamil 13801.40SkamilTRACEME_VFORK_RAISE(traceme_vfork_raise1, SIGKILL) /* non-maskable */ 13811.46SkamilTRACEME_VFORK_RAISE(traceme_vfork_raise2, SIGSTOP) /* non-maskable */ 13821.47SkamilTRACEME_VFORK_RAISE(traceme_vfork_raise3, SIGTSTP) /* ignored in vfork(2) */ 13831.47SkamilTRACEME_VFORK_RAISE(traceme_vfork_raise4, SIGTTIN) /* ignored in vfork(2) */ 13841.47SkamilTRACEME_VFORK_RAISE(traceme_vfork_raise5, SIGTTOU) /* ignored in vfork(2) */ 13851.47SkamilTRACEME_VFORK_RAISE(traceme_vfork_raise6, SIGABRT) /* regular abort trap */ 13861.47SkamilTRACEME_VFORK_RAISE(traceme_vfork_raise7, SIGHUP) /* hangup */ 13871.47SkamilTRACEME_VFORK_RAISE(traceme_vfork_raise8, SIGCONT) /* continued? */ 13881.85SkamilTRACEME_VFORK_RAISE(traceme_vfork_raise9, SIGTRAP) /* crash signal */ 13891.85SkamilTRACEME_VFORK_RAISE(traceme_vfork_raise10, SIGBUS) /* crash signal */ 13901.85SkamilTRACEME_VFORK_RAISE(traceme_vfork_raise11, SIGILL) /* crash signal */ 13911.85SkamilTRACEME_VFORK_RAISE(traceme_vfork_raise12, SIGFPE) /* crash signal */ 13921.85SkamilTRACEME_VFORK_RAISE(traceme_vfork_raise13, SIGSEGV) /* crash signal */ 13931.40Skamil 13941.40Skamil/// ---------------------------------------------------------------------------- 13951.40Skamil 13961.52Skamilstatic void 13971.52Skamiltraceme_vfork_crash(int sig) 13981.41Skamil{ 13991.41Skamil pid_t child, wpid; 14001.41Skamil#if defined(TWAIT_HAVE_STATUS) 14011.41Skamil int status; 14021.41Skamil#endif 14031.41Skamil 14041.71Skamil#ifndef PTRACE_ILLEGAL_ASM 14051.71Skamil if (sig == SIGILL) 14061.71Skamil atf_tc_skip("PTRACE_ILLEGAL_ASM not defined"); 14071.71Skamil#endif 14081.71Skamil 14091.41Skamil DPRINTF("Before forking process PID=%d\n", getpid()); 14101.41Skamil SYSCALL_REQUIRE((child = vfork()) != -1); 14111.41Skamil if (child == 0) { 14121.41Skamil DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 14131.41Skamil FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 14141.41Skamil 14151.52Skamil DPRINTF("Before executing a trap\n"); 14161.52Skamil switch (sig) { 14171.52Skamil case SIGTRAP: 14181.52Skamil trigger_trap(); 14191.52Skamil break; 14201.52Skamil case SIGSEGV: 14211.52Skamil trigger_segv(); 14221.52Skamil break; 14231.52Skamil case SIGILL: 14241.52Skamil trigger_ill(); 14251.52Skamil break; 14261.52Skamil case SIGFPE: 14271.52Skamil trigger_fpe(); 14281.52Skamil break; 14291.52Skamil case SIGBUS: 14301.52Skamil trigger_bus(); 14311.52Skamil break; 14321.52Skamil default: 14331.52Skamil /* NOTREACHED */ 14341.52Skamil FORKEE_ASSERTX(0 && "This shall not be reached"); 14351.52Skamil } 14361.41Skamil 14371.41Skamil /* NOTREACHED */ 14381.41Skamil FORKEE_ASSERTX(0 && "This shall not be reached"); 14391.41Skamil } 14401.41Skamil DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 14411.41Skamil 14421.41Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 14431.41Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 14441.41Skamil 14451.52Skamil validate_status_signaled(status, sig, 1); 14461.41Skamil 14471.41Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 14481.41Skamil TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 14491.41Skamil} 14501.41Skamil 14511.61Skre#define TRACEME_VFORK_CRASH(test, sig) \ 14521.61SkreATF_TC(test); \ 14531.61SkreATF_TC_HEAD(test, tc) \ 14541.61Skre{ \ 14551.61Skre atf_tc_set_md_var(tc, "descr", \ 14561.61Skre "Verify PT_TRACE_ME followed by a crash signal " #sig " in a " \ 14571.61Skre "vfork(2)ed child"); \ 14581.61Skre} \ 14591.61Skre \ 14601.61SkreATF_TC_BODY(test, tc) \ 14611.61Skre{ \ 14621.61Skre \ 14631.61Skre traceme_vfork_crash(sig); \ 14641.52Skamil} 14651.52Skamil 14661.52SkamilTRACEME_VFORK_CRASH(traceme_vfork_crash_trap, SIGTRAP) 14671.52SkamilTRACEME_VFORK_CRASH(traceme_vfork_crash_segv, SIGSEGV) 14681.71SkamilTRACEME_VFORK_CRASH(traceme_vfork_crash_ill, SIGILL) 14691.52SkamilTRACEME_VFORK_CRASH(traceme_vfork_crash_fpe, SIGFPE) 14701.52SkamilTRACEME_VFORK_CRASH(traceme_vfork_crash_bus, SIGBUS) 14711.52Skamil 14721.41Skamil/// ---------------------------------------------------------------------------- 14731.41Skamil 14741.43SkamilATF_TC(traceme_vfork_exec); 14751.43SkamilATF_TC_HEAD(traceme_vfork_exec, tc) 14761.43Skamil{ 14771.43Skamil atf_tc_set_md_var(tc, "descr", 14781.43Skamil "Verify PT_TRACE_ME followed by exec(3) in a vfork(2)ed child"); 14791.43Skamil} 14801.43Skamil 14811.43SkamilATF_TC_BODY(traceme_vfork_exec, tc) 14821.43Skamil{ 14831.43Skamil const int sigval = SIGTRAP; 14841.43Skamil pid_t child, wpid; 14851.43Skamil#if defined(TWAIT_HAVE_STATUS) 14861.43Skamil int status; 14871.43Skamil#endif 14881.61Skre struct ptrace_siginfo info; 14891.43Skamil 14901.43Skamil memset(&info, 0, sizeof(info)); 14911.43Skamil 14921.43Skamil DPRINTF("Before forking process PID=%d\n", getpid()); 14931.43Skamil SYSCALL_REQUIRE((child = vfork()) != -1); 14941.43Skamil if (child == 0) { 14951.43Skamil DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 14961.43Skamil FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 14971.43Skamil 14981.43Skamil DPRINTF("Before calling execve(2) from child\n"); 14991.43Skamil execlp("/bin/echo", "/bin/echo", NULL); 15001.43Skamil 15011.43Skamil /* NOTREACHED */ 15021.43Skamil FORKEE_ASSERTX(0 && "Not reached"); 15031.43Skamil } 15041.43Skamil DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 15051.43Skamil 15061.43Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 15071.43Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 15081.43Skamil 15091.43Skamil validate_status_stopped(status, sigval); 15101.43Skamil 15111.43Skamil DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 15121.61Skre SYSCALL_REQUIRE( 15131.61Skre ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 15141.43Skamil 15151.43Skamil DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 15161.43Skamil DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 15171.43Skamil info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 15181.43Skamil info.psi_siginfo.si_errno); 15191.43Skamil 15201.43Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 15211.43Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_EXEC); 15221.43Skamil 15231.43Skamil DPRINTF("Before resuming the child process where it left off and " 15241.43Skamil "without signal to be sent\n"); 15251.43Skamil SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 15261.43Skamil 15271.43Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 15281.43Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 15291.43Skamil 15301.43Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 15311.43Skamil TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 15321.43Skamil} 15331.43Skamil 15341.43Skamil/// ---------------------------------------------------------------------------- 15351.43Skamil 15361.1Skamil#if defined(TWAIT_HAVE_PID) 15371.51Skamilstatic void 15381.59Skamilunrelated_tracer_sees_crash(int sig) 15391.59Skamil{ 15401.59Skamil struct msg_fds parent_tracee, parent_tracer; 15411.59Skamil const int exitval = 10; 15421.59Skamil pid_t tracee, tracer, wpid; 15431.59Skamil uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */ 15441.59Skamil#if defined(TWAIT_HAVE_STATUS) 15451.59Skamil int status; 15461.59Skamil#endif 15471.59Skamil struct ptrace_siginfo info; 15481.61Skre 15491.71Skamil#ifndef PTRACE_ILLEGAL_ASM 15501.71Skamil if (sig == SIGILL) 15511.71Skamil atf_tc_skip("PTRACE_ILLEGAL_ASM not defined"); 15521.71Skamil#endif 15531.71Skamil 15541.59Skamil memset(&info, 0, sizeof(info)); 15551.59Skamil 15561.59Skamil DPRINTF("Spawn tracee\n"); 15571.59Skamil SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0); 15581.59Skamil tracee = atf_utils_fork(); 15591.59Skamil if (tracee == 0) { 15601.59Skamil // Wait for parent to let us crash 15611.59Skamil CHILD_FROM_PARENT("exit tracee", parent_tracee, msg); 15621.61Skre 15631.59Skamil DPRINTF("Before executing a trap\n"); 15641.59Skamil switch (sig) { 15651.59Skamil case SIGTRAP: 15661.59Skamil trigger_trap(); 15671.59Skamil break; 15681.59Skamil case SIGSEGV: 15691.59Skamil trigger_segv(); 15701.59Skamil break; 15711.59Skamil case SIGILL: 15721.59Skamil trigger_ill(); 15731.59Skamil break; 15741.59Skamil case SIGFPE: 15751.59Skamil trigger_fpe(); 15761.59Skamil break; 15771.59Skamil case SIGBUS: 15781.59Skamil trigger_bus(); 15791.59Skamil break; 15801.59Skamil default: 15811.59Skamil /* NOTREACHED */ 15821.59Skamil FORKEE_ASSERTX(0 && "This shall not be reached"); 15831.59Skamil } 15841.59Skamil 15851.59Skamil /* NOTREACHED */ 15861.59Skamil FORKEE_ASSERTX(0 && "This shall not be reached"); 15871.59Skamil } 15881.59Skamil 15891.59Skamil DPRINTF("Spawn debugger\n"); 15901.59Skamil SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0); 15911.59Skamil tracer = atf_utils_fork(); 15921.59Skamil if (tracer == 0) { 15931.59Skamil /* Fork again and drop parent to reattach to PID 1 */ 15941.59Skamil tracer = atf_utils_fork(); 15951.59Skamil if (tracer != 0) 15961.61Skre _exit(exitval); 15971.59Skamil 15981.59Skamil DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid()); 15991.59Skamil FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1); 16001.59Skamil 16011.59Skamil /* Wait for tracee and assert that it was stopped w/ SIGSTOP */ 16021.59Skamil FORKEE_REQUIRE_SUCCESS( 16031.59Skamil wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 16041.59Skamil 16051.59Skamil forkee_status_stopped(status, SIGSTOP); 16061.59Skamil 16071.59Skamil /* Resume tracee with PT_CONTINUE */ 16081.59Skamil FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1); 16091.59Skamil 16101.59Skamil /* Inform parent that tracer has attached to tracee */ 16111.59Skamil CHILD_TO_PARENT("tracer ready", parent_tracer, msg); 16121.59Skamil 16131.59Skamil /* Wait for parent to tell use that tracee should have exited */ 16141.59Skamil CHILD_FROM_PARENT("wait for tracee exit", parent_tracer, msg); 16151.59Skamil 16161.59Skamil /* Wait for tracee and assert that it exited */ 16171.59Skamil FORKEE_REQUIRE_SUCCESS( 16181.59Skamil wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 16191.59Skamil 16201.59Skamil validate_status_stopped(status, sig); 16211.59Skamil 16221.59Skamil DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for the " 16231.61Skre "traced process\n"); 16241.61Skre SYSCALL_REQUIRE( 16251.61Skre ptrace(PT_GET_SIGINFO, tracee, &info, sizeof(info)) != -1); 16261.59Skamil 16271.59Skamil DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 16281.59Skamil DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 16291.61Skre "si_errno=%#x\n", info.psi_siginfo.si_signo, 16301.61Skre info.psi_siginfo.si_code, info.psi_siginfo.si_errno); 16311.59Skamil 16321.59Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sig); 16331.59Skamil switch (sig) { 16341.59Skamil case SIGTRAP: 16351.59Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_BRKPT); 16361.59Skamil break; 16371.59Skamil case SIGSEGV: 16381.59Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SEGV_MAPERR); 16391.59Skamil break; 16401.71Skamil case SIGILL: 16411.71Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_code, ILL_PRVOPC); 16421.71Skamil break; 16431.59Skamil case SIGFPE: 16441.59Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_code, FPE_INTDIV); 16451.59Skamil break; 16461.59Skamil case SIGBUS: 16471.59Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_code, BUS_ADRERR); 16481.59Skamil break; 16491.59Skamil } 16501.59Skamil 16511.59Skamil FORKEE_ASSERT(ptrace(PT_KILL, tracee, NULL, 0) != -1); 16521.59Skamil DPRINTF("Before calling %s() for the tracee\n", TWAIT_FNAME); 16531.61Skre TWAIT_REQUIRE_SUCCESS( 16541.61Skre wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 16551.59Skamil 16561.59Skamil validate_status_signaled(status, SIGKILL, 0); 16571.59Skamil 16581.59Skamil DPRINTF("Before calling %s() for tracee\n", TWAIT_FNAME); 16591.59Skamil TWAIT_REQUIRE_FAILURE(ECHILD, 16601.59Skamil wpid = TWAIT_GENERIC(tracee, &status, 0)); 16611.59Skamil 16621.71Skamil /* Inform parent that tracer is exiting normally */ 16631.71Skamil CHILD_TO_PARENT("tracer done", parent_tracer, msg); 16641.71Skamil 16651.59Skamil DPRINTF("Before exiting of the tracer process\n"); 16661.59Skamil _exit(0 /* collect by initproc */); 16671.59Skamil } 16681.59Skamil 16691.59Skamil DPRINTF("Wait for the tracer process (direct child) to exit " 16701.59Skamil "calling %s()\n", TWAIT_FNAME); 16711.59Skamil TWAIT_REQUIRE_SUCCESS( 16721.59Skamil wpid = TWAIT_GENERIC(tracer, &status, 0), tracer); 16731.59Skamil 16741.59Skamil validate_status_exited(status, exitval); 16751.59Skamil 16761.59Skamil DPRINTF("Wait for the non-exited tracee process with %s()\n", 16771.59Skamil TWAIT_FNAME); 16781.59Skamil TWAIT_REQUIRE_SUCCESS( 16791.59Skamil wpid = TWAIT_GENERIC(tracee, NULL, WNOHANG), 0); 16801.59Skamil 16811.59Skamil DPRINTF("Wait for the tracer to attach to the tracee\n"); 16821.59Skamil PARENT_FROM_CHILD("tracer ready", parent_tracer, msg); 16831.59Skamil 16841.59Skamil DPRINTF("Resume the tracee and let it crash\n"); 16851.59Skamil PARENT_TO_CHILD("exit tracee", parent_tracee, msg); 16861.59Skamil 16871.59Skamil DPRINTF("Resume the tracer and let it detect crashed tracee\n"); 16881.59Skamil PARENT_TO_CHILD("Message 2", parent_tracer, msg); 16891.59Skamil 16901.59Skamil DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n", 16911.59Skamil TWAIT_FNAME); 16921.59Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 16931.59Skamil 16941.59Skamil validate_status_signaled(status, SIGKILL, 0); 16951.59Skamil 16961.71Skamil DPRINTF("Await normal exit of tracer\n"); 16971.71Skamil PARENT_FROM_CHILD("tracer done", parent_tracer, msg); 16981.71Skamil 16991.59Skamil msg_close(&parent_tracer); 17001.59Skamil msg_close(&parent_tracee); 17011.59Skamil} 17021.59Skamil 17031.61Skre#define UNRELATED_TRACER_SEES_CRASH(test, sig) \ 17041.61SkreATF_TC(test); \ 17051.61SkreATF_TC_HEAD(test, tc) \ 17061.61Skre{ \ 17071.61Skre atf_tc_set_md_var(tc, "descr", \ 17081.61Skre "Assert that an unrelated tracer sees crash signal from the " \ 17091.61Skre "debuggee"); \ 17101.61Skre} \ 17111.61Skre \ 17121.61SkreATF_TC_BODY(test, tc) \ 17131.61Skre{ \ 17141.61Skre \ 17151.61Skre unrelated_tracer_sees_crash(sig); \ 17161.59Skamil} 17171.59Skamil 17181.59SkamilUNRELATED_TRACER_SEES_CRASH(unrelated_tracer_sees_crash_trap, SIGTRAP) 17191.59SkamilUNRELATED_TRACER_SEES_CRASH(unrelated_tracer_sees_crash_segv, SIGSEGV) 17201.71SkamilUNRELATED_TRACER_SEES_CRASH(unrelated_tracer_sees_crash_ill, SIGILL) 17211.59SkamilUNRELATED_TRACER_SEES_CRASH(unrelated_tracer_sees_crash_fpe, SIGFPE) 17221.59SkamilUNRELATED_TRACER_SEES_CRASH(unrelated_tracer_sees_crash_bus, SIGBUS) 17231.59Skamil#endif 17241.59Skamil 17251.59Skamil/// ---------------------------------------------------------------------------- 17261.59Skamil 17271.59Skamil#if defined(TWAIT_HAVE_PID) 17281.59Skamilstatic void 17291.67Skamiltracer_sees_terminaton_before_the_parent_raw(bool notimeout, bool unrelated, 17301.67Skamil bool stopped) 17311.1Skamil{ 17321.51Skamil /* 17331.51Skamil * notimeout - disable timeout in await zombie function 17341.51Skamil * unrelated - attach from unrelated tracer reparented to initproc 17351.67Skamil * stopped - attach to a stopped process 17361.51Skamil */ 17371.1Skamil 17381.1Skamil struct msg_fds parent_tracee, parent_tracer; 17391.1Skamil const int exitval_tracee = 5; 17401.1Skamil const int exitval_tracer = 10; 17411.1Skamil pid_t tracee, tracer, wpid; 17421.1Skamil uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */ 17431.1Skamil#if defined(TWAIT_HAVE_STATUS) 17441.1Skamil int status; 17451.1Skamil#endif 17461.1Skamil 17471.67Skamil /* 17481.67Skamil * Only a subset of options are supported. 17491.67Skamil */ 17501.67Skamil ATF_REQUIRE((!notimeout && !unrelated && !stopped) || 17511.67Skamil (!notimeout && unrelated && !stopped) || 17521.67Skamil (notimeout && !unrelated && !stopped) || 17531.67Skamil (!notimeout && unrelated && stopped)); 17541.67Skamil 17551.13Schristos DPRINTF("Spawn tracee\n"); 17561.13Schristos SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0); 17571.1Skamil tracee = atf_utils_fork(); 17581.1Skamil if (tracee == 0) { 17591.67Skamil if (stopped) { 17601.67Skamil DPRINTF("Stop self PID %d\n", getpid()); 17611.67Skamil raise(SIGSTOP); 17621.67Skamil } 17631.67Skamil 17641.1Skamil // Wait for parent to let us exit 17651.1Skamil CHILD_FROM_PARENT("exit tracee", parent_tracee, msg); 17661.1Skamil _exit(exitval_tracee); 17671.1Skamil } 17681.1Skamil 17691.13Schristos DPRINTF("Spawn debugger\n"); 17701.13Schristos SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0); 17711.1Skamil tracer = atf_utils_fork(); 17721.1Skamil if (tracer == 0) { 17731.51Skamil if(unrelated) { 17741.51Skamil /* Fork again and drop parent to reattach to PID 1 */ 17751.51Skamil tracer = atf_utils_fork(); 17761.51Skamil if (tracer != 0) 17771.51Skamil _exit(exitval_tracer); 17781.51Skamil } 17791.51Skamil 17801.67Skamil if (stopped) { 17811.67Skamil DPRINTF("Await for a stopped parent PID %d\n", tracee); 17821.67Skamil await_stopped(tracee); 17831.67Skamil } 17841.67Skamil 17851.13Schristos DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid()); 17861.1Skamil FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1); 17871.1Skamil 17881.1Skamil /* Wait for tracee and assert that it was stopped w/ SIGSTOP */ 17891.1Skamil FORKEE_REQUIRE_SUCCESS( 17901.1Skamil wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 17911.1Skamil 17921.1Skamil forkee_status_stopped(status, SIGSTOP); 17931.1Skamil 17941.1Skamil /* Resume tracee with PT_CONTINUE */ 17951.1Skamil FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1); 17961.1Skamil 17971.1Skamil /* Inform parent that tracer has attached to tracee */ 17981.1Skamil CHILD_TO_PARENT("tracer ready", parent_tracer, msg); 17991.1Skamil 18001.1Skamil /* Wait for parent to tell use that tracee should have exited */ 18011.1Skamil CHILD_FROM_PARENT("wait for tracee exit", parent_tracer, msg); 18021.1Skamil 18031.1Skamil /* Wait for tracee and assert that it exited */ 18041.1Skamil FORKEE_REQUIRE_SUCCESS( 18051.1Skamil wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 18061.1Skamil 18071.1Skamil forkee_status_exited(status, exitval_tracee); 18081.13Schristos DPRINTF("Tracee %d exited with %d\n", tracee, exitval_tracee); 18091.1Skamil 18101.13Schristos DPRINTF("Before exiting of the tracer process\n"); 18111.51Skamil _exit(unrelated ? 0 /* collect by initproc */ : exitval_tracer); 18121.51Skamil } 18131.51Skamil 18141.51Skamil if (unrelated) { 18151.51Skamil DPRINTF("Wait for the tracer process (direct child) to exit " 18161.51Skamil "calling %s()\n", TWAIT_FNAME); 18171.51Skamil TWAIT_REQUIRE_SUCCESS( 18181.51Skamil wpid = TWAIT_GENERIC(tracer, &status, 0), tracer); 18191.51Skamil 18201.51Skamil validate_status_exited(status, exitval_tracer); 18211.51Skamil 18221.51Skamil DPRINTF("Wait for the non-exited tracee process with %s()\n", 18231.51Skamil TWAIT_FNAME); 18241.51Skamil TWAIT_REQUIRE_SUCCESS( 18251.51Skamil wpid = TWAIT_GENERIC(tracee, NULL, WNOHANG), 0); 18261.1Skamil } 18271.1Skamil 18281.13Schristos DPRINTF("Wait for the tracer to attach to the tracee\n"); 18291.1Skamil PARENT_FROM_CHILD("tracer ready", parent_tracer, msg); 18301.1Skamil 18311.13Schristos DPRINTF("Resume the tracee and let it exit\n"); 18321.1Skamil PARENT_TO_CHILD("exit tracee", parent_tracee, msg); 18331.1Skamil 18341.13Schristos DPRINTF("Detect that tracee is zombie\n"); 18351.51Skamil if (notimeout) 18361.26Skamil await_zombie_raw(tracee, 0); 18371.26Skamil else 18381.26Skamil await_zombie(tracee); 18391.1Skamil 18401.13Schristos DPRINTF("Assert that there is no status about tracee %d - " 18411.1Skamil "Tracer must detect zombie first - calling %s()\n", tracee, 18421.1Skamil TWAIT_FNAME); 18431.1Skamil TWAIT_REQUIRE_SUCCESS( 18441.1Skamil wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0); 18451.1Skamil 18461.51Skamil if (unrelated) { 18471.51Skamil DPRINTF("Resume the tracer and let it detect exited tracee\n"); 18481.51Skamil PARENT_TO_CHILD("Message 2", parent_tracer, msg); 18491.51Skamil } else { 18501.51Skamil DPRINTF("Tell the tracer child should have exited\n"); 18511.51Skamil PARENT_TO_CHILD("wait for tracee exit", parent_tracer, msg); 18521.51Skamil DPRINTF("Wait for tracer to finish its job and exit - calling " 18531.59Skamil "%s()\n", TWAIT_FNAME); 18541.51Skamil 18551.51Skamil DPRINTF("Wait from tracer child to complete waiting for " 18561.59Skamil "tracee\n"); 18571.51Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0), 18581.51Skamil tracer); 18591.1Skamil 18601.51Skamil validate_status_exited(status, exitval_tracer); 18611.51Skamil } 18621.1Skamil 18631.13Schristos DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n", 18641.1Skamil TWAIT_FNAME); 18651.51Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 18661.1Skamil 18671.1Skamil validate_status_exited(status, exitval_tracee); 18681.1Skamil 18691.1Skamil msg_close(&parent_tracer); 18701.1Skamil msg_close(&parent_tracee); 18711.1Skamil} 18721.26Skamil 18731.51SkamilATF_TC(tracer_sees_terminaton_before_the_parent); 18741.51SkamilATF_TC_HEAD(tracer_sees_terminaton_before_the_parent, tc) 18751.51Skamil{ 18761.51Skamil atf_tc_set_md_var(tc, "descr", 18771.51Skamil "Assert that tracer sees process termination before the parent"); 18781.51Skamil} 18791.51Skamil 18801.51SkamilATF_TC_BODY(tracer_sees_terminaton_before_the_parent, tc) 18811.26Skamil{ 18821.26Skamil 18831.67Skamil tracer_sees_terminaton_before_the_parent_raw(false, false, false); 18841.26Skamil} 18851.26Skamil 18861.51SkamilATF_TC(tracer_sysctl_lookup_without_duplicates); 18871.51SkamilATF_TC_HEAD(tracer_sysctl_lookup_without_duplicates, tc) 18881.1Skamil{ 18891.1Skamil atf_tc_set_md_var(tc, "descr", 18901.51Skamil "Assert that await_zombie() in attach1 always finds a single " 18911.51Skamil "process and no other error is reported"); 18921.1Skamil} 18931.1Skamil 18941.51SkamilATF_TC_BODY(tracer_sysctl_lookup_without_duplicates, tc) 18951.1Skamil{ 18961.51Skamil time_t start, end; 18971.51Skamil double diff; 18981.51Skamil unsigned long N = 0; 18991.1Skamil 19001.51Skamil /* 19011.51Skamil * Reuse this test with tracer_sees_terminaton_before_the_parent_raw(). 19021.51Skamil * This test body isn't specific to this race, however it's just good 19031.51Skamil * enough for this purposes, no need to invent a dedicated code flow. 19041.51Skamil */ 19051.1Skamil 19061.51Skamil start = time(NULL); 19071.51Skamil while (true) { 19081.51Skamil DPRINTF("Step: %lu\n", N); 19091.67Skamil tracer_sees_terminaton_before_the_parent_raw(true, false, 19101.67Skamil false); 19111.51Skamil end = time(NULL); 19121.51Skamil diff = difftime(end, start); 19131.51Skamil if (diff >= 5.0) 19141.51Skamil break; 19151.51Skamil ++N; 19161.1Skamil } 19171.51Skamil DPRINTF("Iterations: %lu\n", N); 19181.51Skamil} 19191.1Skamil 19201.51SkamilATF_TC(unrelated_tracer_sees_terminaton_before_the_parent); 19211.51SkamilATF_TC_HEAD(unrelated_tracer_sees_terminaton_before_the_parent, tc) 19221.51Skamil{ 19231.51Skamil atf_tc_set_md_var(tc, "descr", 19241.51Skamil "Assert that tracer sees process termination before the parent"); 19251.51Skamil} 19261.1Skamil 19271.51SkamilATF_TC_BODY(unrelated_tracer_sees_terminaton_before_the_parent, tc) 19281.51Skamil{ 19291.1Skamil 19301.67Skamil tracer_sees_terminaton_before_the_parent_raw(false, true, false); 19311.67Skamil} 19321.67Skamil 19331.67SkamilATF_TC(tracer_attach_to_unrelated_stopped_process); 19341.67SkamilATF_TC_HEAD(tracer_attach_to_unrelated_stopped_process, tc) 19351.67Skamil{ 19361.67Skamil atf_tc_set_md_var(tc, "descr", 19371.67Skamil "Assert that tracer can attach to an unrelated stopped process"); 19381.67Skamil} 19391.67Skamil 19401.67SkamilATF_TC_BODY(tracer_attach_to_unrelated_stopped_process, tc) 19411.67Skamil{ 19421.67Skamil 19431.67Skamil tracer_sees_terminaton_before_the_parent_raw(false, true, true); 19441.1Skamil} 19451.1Skamil#endif 19461.1Skamil 19471.51Skamil/// ---------------------------------------------------------------------------- 19481.51Skamil 19491.66Skamilstatic void 19501.66Skamilparent_attach_to_its_child(bool stopped) 19511.1Skamil{ 19521.1Skamil struct msg_fds parent_tracee; 19531.1Skamil const int exitval_tracee = 5; 19541.1Skamil pid_t tracee, wpid; 19551.1Skamil uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */ 19561.1Skamil#if defined(TWAIT_HAVE_STATUS) 19571.1Skamil int status; 19581.1Skamil#endif 19591.1Skamil 19601.13Schristos DPRINTF("Spawn tracee\n"); 19611.13Schristos SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0); 19621.1Skamil tracee = atf_utils_fork(); 19631.1Skamil if (tracee == 0) { 19641.1Skamil CHILD_FROM_PARENT("Message 1", parent_tracee, msg); 19651.13Schristos DPRINTF("Parent should now attach to tracee\n"); 19661.1Skamil 19671.66Skamil if (stopped) { 19681.66Skamil DPRINTF("Stop self PID %d\n", getpid()); 19691.66Skamil SYSCALL_REQUIRE(raise(SIGSTOP) != -1); 19701.66Skamil } 19711.66Skamil 19721.1Skamil CHILD_FROM_PARENT("Message 2", parent_tracee, msg); 19731.1Skamil /* Wait for message from the parent */ 19741.1Skamil _exit(exitval_tracee); 19751.1Skamil } 19761.1Skamil PARENT_TO_CHILD("Message 1", parent_tracee, msg); 19771.57Skamil 19781.66Skamil if (stopped) { 19791.66Skamil DPRINTF("Await for a stopped tracee PID %d\n", tracee); 19801.66Skamil await_stopped(tracee); 19811.66Skamil } 19821.66Skamil 19831.13Schristos DPRINTF("Before calling PT_ATTACH for tracee %d\n", tracee); 19841.13Schristos SYSCALL_REQUIRE(ptrace(PT_ATTACH, tracee, NULL, 0) != -1); 19851.1Skamil 19861.13Schristos DPRINTF("Wait for the stopped tracee process with %s()\n", 19871.1Skamil TWAIT_FNAME); 19881.1Skamil TWAIT_REQUIRE_SUCCESS( 19891.1Skamil wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 19901.1Skamil 19911.1Skamil validate_status_stopped(status, SIGSTOP); 19921.1Skamil 19931.13Schristos DPRINTF("Resume tracee with PT_CONTINUE\n"); 19941.13Schristos SYSCALL_REQUIRE(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1); 19951.1Skamil 19961.13Schristos DPRINTF("Let the tracee exit now\n"); 19971.1Skamil PARENT_TO_CHILD("Message 2", parent_tracee, msg); 19981.1Skamil 19991.13Schristos DPRINTF("Wait for tracee to exit with %s()\n", TWAIT_FNAME); 20001.1Skamil TWAIT_REQUIRE_SUCCESS( 20011.1Skamil wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 20021.1Skamil 20031.1Skamil validate_status_exited(status, exitval_tracee); 20041.1Skamil 20051.13Schristos DPRINTF("Before calling %s() for tracee\n", TWAIT_FNAME); 20061.1Skamil TWAIT_REQUIRE_FAILURE(ECHILD, 20071.1Skamil wpid = TWAIT_GENERIC(tracee, &status, 0)); 20081.1Skamil 20091.1Skamil msg_close(&parent_tracee); 20101.1Skamil} 20111.1Skamil 20121.66SkamilATF_TC(parent_attach_to_its_child); 20131.66SkamilATF_TC_HEAD(parent_attach_to_its_child, tc) 20141.66Skamil{ 20151.66Skamil atf_tc_set_md_var(tc, "descr", 20161.66Skamil "Assert that tracer parent can PT_ATTACH to its child"); 20171.66Skamil} 20181.66Skamil 20191.66SkamilATF_TC_BODY(parent_attach_to_its_child, tc) 20201.66Skamil{ 20211.66Skamil 20221.66Skamil parent_attach_to_its_child(false); 20231.66Skamil} 20241.66Skamil 20251.66SkamilATF_TC(parent_attach_to_its_stopped_child); 20261.66SkamilATF_TC_HEAD(parent_attach_to_its_stopped_child, tc) 20271.66Skamil{ 20281.66Skamil atf_tc_set_md_var(tc, "descr", 20291.66Skamil "Assert that tracer parent can PT_ATTACH to its stopped child"); 20301.66Skamil} 20311.66Skamil 20321.66SkamilATF_TC_BODY(parent_attach_to_its_stopped_child, tc) 20331.66Skamil{ 20341.66Skamil 20351.66Skamil parent_attach_to_its_child(true); 20361.66Skamil} 20371.66Skamil 20381.51Skamil/// ---------------------------------------------------------------------------- 20391.51Skamil 20401.65Skamilstatic void 20411.65Skamilchild_attach_to_its_parent(bool stopped) 20421.1Skamil{ 20431.1Skamil struct msg_fds parent_tracee; 20441.1Skamil const int exitval_tracer = 5; 20451.1Skamil pid_t tracer, wpid; 20461.1Skamil uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */ 20471.1Skamil#if defined(TWAIT_HAVE_STATUS) 20481.1Skamil int status; 20491.1Skamil#endif 20501.1Skamil 20511.13Schristos DPRINTF("Spawn tracer\n"); 20521.13Schristos SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0); 20531.1Skamil tracer = atf_utils_fork(); 20541.1Skamil if (tracer == 0) { 20551.1Skamil /* Wait for message from the parent */ 20561.1Skamil CHILD_FROM_PARENT("Message 1", parent_tracee, msg); 20571.1Skamil 20581.65Skamil if (stopped) { 20591.65Skamil DPRINTF("Await for a stopped parent PID %d\n", 20601.65Skamil getppid()); 20611.65Skamil await_stopped(getppid()); 20621.65Skamil } 20631.65Skamil 20641.13Schristos DPRINTF("Attach to parent PID %d with PT_ATTACH from child\n", 20651.1Skamil getppid()); 20661.1Skamil FORKEE_ASSERT(ptrace(PT_ATTACH, getppid(), NULL, 0) != -1); 20671.1Skamil 20681.13Schristos DPRINTF("Wait for the stopped parent process with %s()\n", 20691.1Skamil TWAIT_FNAME); 20701.1Skamil FORKEE_REQUIRE_SUCCESS( 20711.1Skamil wpid = TWAIT_GENERIC(getppid(), &status, 0), getppid()); 20721.1Skamil 20731.1Skamil forkee_status_stopped(status, SIGSTOP); 20741.1Skamil 20751.13Schristos DPRINTF("Resume parent with PT_DETACH\n"); 20761.1Skamil FORKEE_ASSERT(ptrace(PT_DETACH, getppid(), (void *)1, 0) 20771.1Skamil != -1); 20781.1Skamil 20791.1Skamil /* Tell parent we are ready */ 20801.1Skamil CHILD_TO_PARENT("Message 1", parent_tracee, msg); 20811.1Skamil 20821.1Skamil _exit(exitval_tracer); 20831.1Skamil } 20841.1Skamil 20851.13Schristos DPRINTF("Wait for the tracer to become ready\n"); 20861.1Skamil PARENT_TO_CHILD("Message 1", parent_tracee, msg); 20871.65Skamil 20881.65Skamil if (stopped) { 20891.65Skamil DPRINTF("Stop self PID %d\n", getpid()); 20901.65Skamil SYSCALL_REQUIRE(raise(SIGSTOP) != -1); 20911.65Skamil } 20921.65Skamil 20931.13Schristos DPRINTF("Allow the tracer to exit now\n"); 20941.1Skamil PARENT_FROM_CHILD("Message 1", parent_tracee, msg); 20951.1Skamil 20961.13Schristos DPRINTF("Wait for tracer to exit with %s()\n", TWAIT_FNAME); 20971.1Skamil TWAIT_REQUIRE_SUCCESS( 20981.1Skamil wpid = TWAIT_GENERIC(tracer, &status, 0), tracer); 20991.1Skamil 21001.1Skamil validate_status_exited(status, exitval_tracer); 21011.1Skamil 21021.13Schristos DPRINTF("Before calling %s() for tracer\n", TWAIT_FNAME); 21031.1Skamil TWAIT_REQUIRE_FAILURE(ECHILD, 21041.1Skamil wpid = TWAIT_GENERIC(tracer, &status, 0)); 21051.1Skamil 21061.1Skamil msg_close(&parent_tracee); 21071.1Skamil} 21081.1Skamil 21091.65SkamilATF_TC(child_attach_to_its_parent); 21101.65SkamilATF_TC_HEAD(child_attach_to_its_parent, tc) 21111.65Skamil{ 21121.65Skamil atf_tc_set_md_var(tc, "descr", 21131.65Skamil "Assert that tracer child can PT_ATTACH to its parent"); 21141.65Skamil} 21151.65Skamil 21161.65SkamilATF_TC_BODY(child_attach_to_its_parent, tc) 21171.65Skamil{ 21181.65Skamil 21191.65Skamil child_attach_to_its_parent(false); 21201.65Skamil} 21211.65Skamil 21221.65SkamilATF_TC(child_attach_to_its_stopped_parent); 21231.65SkamilATF_TC_HEAD(child_attach_to_its_stopped_parent, tc) 21241.65Skamil{ 21251.65Skamil atf_tc_set_md_var(tc, "descr", 21261.65Skamil "Assert that tracer child can PT_ATTACH to its stopped parent"); 21271.65Skamil} 21281.65Skamil 21291.65SkamilATF_TC_BODY(child_attach_to_its_stopped_parent, tc) 21301.65Skamil{ 21311.65Skamil /* 21321.65Skamil * The ATF framework (atf-run) does not tolerate raise(SIGSTOP), as 21331.65Skamil * this causes a pipe (established from atf-run) to be broken. 21341.65Skamil * atf-run uses this mechanism to monitor whether a test is alive. 21351.65Skamil * 21361.65Skamil * As a workaround spawn this test as a subprocess. 21371.65Skamil */ 21381.65Skamil 21391.65Skamil const int exitval = 15; 21401.65Skamil pid_t child, wpid; 21411.65Skamil#if defined(TWAIT_HAVE_STATUS) 21421.65Skamil int status; 21431.65Skamil#endif 21441.65Skamil 21451.65Skamil SYSCALL_REQUIRE((child = fork()) != -1); 21461.65Skamil if (child == 0) { 21471.65Skamil child_attach_to_its_parent(true); 21481.65Skamil _exit(exitval); 21491.65Skamil } else { 21501.65Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 21511.65Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 21521.65Skamil 21531.65Skamil validate_status_exited(status, exitval); 21541.65Skamil 21551.65Skamil DPRINTF("Before calling %s() for the exited child\n", TWAIT_FNAME); 21561.65Skamil TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 21571.65Skamil } 21581.65Skamil} 21591.65Skamil 21601.51Skamil/// ---------------------------------------------------------------------------- 21611.51Skamil 21621.1Skamil#if defined(TWAIT_HAVE_PID) 21631.1Skamil 21641.51Skamilenum tracee_sees_its_original_parent_type { 21651.51Skamil TRACEE_SEES_ITS_ORIGINAL_PARENT_GETPPID, 21661.51Skamil TRACEE_SEES_ITS_ORIGINAL_PARENT_SYSCTL_KINFO_PROC2, 21671.51Skamil TRACEE_SEES_ITS_ORIGINAL_PARENT_PROCFS_STATUS 21681.51Skamil}; 21691.51Skamil 21701.51Skamilstatic void 21711.51Skamiltracee_sees_its_original_parent(enum tracee_sees_its_original_parent_type type) 21721.1Skamil{ 21731.1Skamil struct msg_fds parent_tracer, parent_tracee; 21741.1Skamil const int exitval_tracee = 5; 21751.1Skamil const int exitval_tracer = 10; 21761.1Skamil pid_t parent, tracee, tracer, wpid; 21771.1Skamil uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */ 21781.1Skamil#if defined(TWAIT_HAVE_STATUS) 21791.1Skamil int status; 21801.1Skamil#endif 21811.51Skamil /* sysctl(3) - kinfo_proc2 */ 21821.51Skamil int name[CTL_MAXNAME]; 21831.51Skamil struct kinfo_proc2 kp; 21841.51Skamil size_t len = sizeof(kp); 21851.51Skamil unsigned int namelen; 21861.51Skamil 21871.51Skamil /* procfs - status */ 21881.51Skamil FILE *fp; 21891.51Skamil struct stat st; 21901.51Skamil const char *fname = "/proc/curproc/status"; 21911.51Skamil char s_executable[MAXPATHLEN]; 21921.51Skamil int s_pid, s_ppid; 21931.51Skamil int rv; 21941.51Skamil 21951.51Skamil if (type == TRACEE_SEES_ITS_ORIGINAL_PARENT_PROCFS_STATUS) { 21961.61Skre SYSCALL_REQUIRE( 21971.61Skre (rv = stat(fname, &st)) == 0 || (errno == ENOENT)); 21981.61Skre if (rv != 0) 21991.51Skamil atf_tc_skip("/proc/curproc/status not found"); 22001.51Skamil } 22011.1Skamil 22021.13Schristos DPRINTF("Spawn tracee\n"); 22031.13Schristos SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0); 22041.13Schristos SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0); 22051.1Skamil tracee = atf_utils_fork(); 22061.1Skamil if (tracee == 0) { 22071.1Skamil parent = getppid(); 22081.1Skamil 22091.1Skamil /* Emit message to the parent */ 22101.1Skamil CHILD_TO_PARENT("tracee ready", parent_tracee, msg); 22111.1Skamil CHILD_FROM_PARENT("exit tracee", parent_tracee, msg); 22121.1Skamil 22131.51Skamil switch (type) { 22141.51Skamil case TRACEE_SEES_ITS_ORIGINAL_PARENT_GETPPID: 22151.51Skamil FORKEE_ASSERT_EQ(parent, getppid()); 22161.51Skamil break; 22171.51Skamil case TRACEE_SEES_ITS_ORIGINAL_PARENT_SYSCTL_KINFO_PROC2: 22181.51Skamil namelen = 0; 22191.51Skamil name[namelen++] = CTL_KERN; 22201.51Skamil name[namelen++] = KERN_PROC2; 22211.51Skamil name[namelen++] = KERN_PROC_PID; 22221.51Skamil name[namelen++] = getpid(); 22231.51Skamil name[namelen++] = len; 22241.51Skamil name[namelen++] = 1; 22251.51Skamil 22261.61Skre FORKEE_ASSERT_EQ( 22271.61Skre sysctl(name, namelen, &kp, &len, NULL, 0), 0); 22281.51Skamil FORKEE_ASSERT_EQ(parent, kp.p_ppid); 22291.51Skamil break; 22301.51Skamil case TRACEE_SEES_ITS_ORIGINAL_PARENT_PROCFS_STATUS: 22311.51Skamil /* 22321.51Skamil * Format: 22331.51Skamil * EXECUTABLE PID PPID ... 22341.51Skamil */ 22351.51Skamil FORKEE_ASSERT((fp = fopen(fname, "r")) != NULL); 22361.51Skamil fscanf(fp, "%s %d %d", s_executable, &s_pid, &s_ppid); 22371.51Skamil FORKEE_ASSERT_EQ(fclose(fp), 0); 22381.51Skamil FORKEE_ASSERT_EQ(parent, s_ppid); 22391.51Skamil break; 22401.51Skamil } 22411.1Skamil 22421.1Skamil _exit(exitval_tracee); 22431.1Skamil } 22441.13Schristos DPRINTF("Wait for child to record its parent identifier (pid)\n"); 22451.1Skamil PARENT_FROM_CHILD("tracee ready", parent_tracee, msg); 22461.1Skamil 22471.13Schristos DPRINTF("Spawn debugger\n"); 22481.1Skamil tracer = atf_utils_fork(); 22491.1Skamil if (tracer == 0) { 22501.1Skamil /* No IPC to communicate with the child */ 22511.13Schristos DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid()); 22521.1Skamil FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1); 22531.1Skamil 22541.1Skamil /* Wait for tracee and assert that it was stopped w/ SIGSTOP */ 22551.1Skamil FORKEE_REQUIRE_SUCCESS( 22561.1Skamil wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 22571.1Skamil 22581.1Skamil forkee_status_stopped(status, SIGSTOP); 22591.1Skamil 22601.1Skamil /* Resume tracee with PT_CONTINUE */ 22611.1Skamil FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1); 22621.1Skamil 22631.1Skamil /* Inform parent that tracer has attached to tracee */ 22641.1Skamil CHILD_TO_PARENT("tracer ready", parent_tracer, msg); 22651.1Skamil 22661.1Skamil /* Wait for parent to tell use that tracee should have exited */ 22671.1Skamil CHILD_FROM_PARENT("wait for tracee exit", parent_tracer, msg); 22681.1Skamil 22691.1Skamil /* Wait for tracee and assert that it exited */ 22701.1Skamil FORKEE_REQUIRE_SUCCESS( 22711.1Skamil wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 22721.1Skamil 22731.1Skamil forkee_status_exited(status, exitval_tracee); 22741.1Skamil 22751.13Schristos DPRINTF("Before exiting of the tracer process\n"); 22761.1Skamil _exit(exitval_tracer); 22771.1Skamil } 22781.1Skamil 22791.13Schristos DPRINTF("Wait for the tracer to attach to the tracee\n"); 22801.1Skamil PARENT_FROM_CHILD("tracer ready", parent_tracer, msg); 22811.1Skamil 22821.13Schristos DPRINTF("Resume the tracee and let it exit\n"); 22831.1Skamil PARENT_TO_CHILD("exit tracee", parent_tracee, msg); 22841.1Skamil 22851.13Schristos DPRINTF("Detect that tracee is zombie\n"); 22861.1Skamil await_zombie(tracee); 22871.1Skamil 22881.13Schristos DPRINTF("Assert that there is no status about tracee - " 22891.1Skamil "Tracer must detect zombie first - calling %s()\n", TWAIT_FNAME); 22901.1Skamil TWAIT_REQUIRE_SUCCESS( 22911.1Skamil wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0); 22921.1Skamil 22931.13Schristos DPRINTF("Tell the tracer child should have exited\n"); 22941.1Skamil PARENT_TO_CHILD("wait for tracee exit", parent_tracer, msg); 22951.1Skamil 22961.13Schristos DPRINTF("Wait from tracer child to complete waiting for tracee\n"); 22971.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0), 22981.1Skamil tracer); 22991.1Skamil 23001.1Skamil validate_status_exited(status, exitval_tracer); 23011.1Skamil 23021.13Schristos DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n", 23031.1Skamil TWAIT_FNAME); 23041.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 23051.1Skamil tracee); 23061.1Skamil 23071.1Skamil validate_status_exited(status, exitval_tracee); 23081.1Skamil 23091.1Skamil msg_close(&parent_tracer); 23101.1Skamil msg_close(&parent_tracee); 23111.1Skamil} 23121.1Skamil 23131.61Skre#define TRACEE_SEES_ITS_ORIGINAL_PARENT(test, type, descr) \ 23141.61SkreATF_TC(test); \ 23151.61SkreATF_TC_HEAD(test, tc) \ 23161.61Skre{ \ 23171.61Skre atf_tc_set_md_var(tc, "descr", \ 23181.61Skre "Assert that tracee sees its original parent when being traced " \ 23191.61Skre "(check " descr ")"); \ 23201.61Skre} \ 23211.61Skre \ 23221.61SkreATF_TC_BODY(test, tc) \ 23231.61Skre{ \ 23241.61Skre \ 23251.61Skre tracee_sees_its_original_parent(type); \ 23261.1Skamil} 23271.1Skamil 23281.51SkamilTRACEE_SEES_ITS_ORIGINAL_PARENT( 23291.51Skamil tracee_sees_its_original_parent_getppid, 23301.51Skamil TRACEE_SEES_ITS_ORIGINAL_PARENT_GETPPID, 23311.51Skamil "getppid(2)"); 23321.51SkamilTRACEE_SEES_ITS_ORIGINAL_PARENT( 23331.51Skamil tracee_sees_its_original_parent_sysctl_kinfo_proc2, 23341.51Skamil TRACEE_SEES_ITS_ORIGINAL_PARENT_SYSCTL_KINFO_PROC2, 23351.51Skamil "sysctl(3) and kinfo_proc2"); 23361.51SkamilTRACEE_SEES_ITS_ORIGINAL_PARENT( 23371.51Skamil tracee_sees_its_original_parent_procfs_status, 23381.51Skamil TRACEE_SEES_ITS_ORIGINAL_PARENT_PROCFS_STATUS, 23391.51Skamil "the status file in procfs"); 23401.1Skamil#endif 23411.1Skamil 23421.51Skamil/// ---------------------------------------------------------------------------- 23431.1Skamil 23441.53Skamilstatic void 23451.53Skamileventmask_preserved(int event) 23461.1Skamil{ 23471.1Skamil const int exitval = 5; 23481.1Skamil const int sigval = SIGSTOP; 23491.1Skamil pid_t child, wpid; 23501.1Skamil#if defined(TWAIT_HAVE_STATUS) 23511.1Skamil int status; 23521.1Skamil#endif 23531.1Skamil ptrace_event_t set_event, get_event; 23541.1Skamil const int len = sizeof(ptrace_event_t); 23551.1Skamil 23561.13Schristos DPRINTF("Before forking process PID=%d\n", getpid()); 23571.13Schristos SYSCALL_REQUIRE((child = fork()) != -1); 23581.1Skamil if (child == 0) { 23591.13Schristos DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 23601.1Skamil FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 23611.1Skamil 23621.13Schristos DPRINTF("Before raising %s from child\n", strsignal(sigval)); 23631.1Skamil FORKEE_ASSERT(raise(sigval) == 0); 23641.1Skamil 23651.13Schristos DPRINTF("Before exiting of the child process\n"); 23661.1Skamil _exit(exitval); 23671.1Skamil } 23681.13Schristos DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 23691.1Skamil 23701.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 23711.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 23721.1Skamil 23731.1Skamil validate_status_stopped(status, sigval); 23741.1Skamil 23751.53Skamil set_event.pe_set_event = event; 23761.61Skre SYSCALL_REQUIRE( 23771.61Skre ptrace(PT_SET_EVENT_MASK, child, &set_event, len) != -1); 23781.61Skre SYSCALL_REQUIRE( 23791.61Skre ptrace(PT_GET_EVENT_MASK, child, &get_event, len) != -1); 23801.1Skamil ATF_REQUIRE(memcmp(&set_event, &get_event, len) == 0); 23811.1Skamil 23821.13Schristos DPRINTF("Before resuming the child process where it left off and " 23831.1Skamil "without signal to be sent\n"); 23841.13Schristos SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 23851.1Skamil 23861.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 23871.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 23881.1Skamil 23891.1Skamil validate_status_exited(status, exitval); 23901.1Skamil 23911.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 23921.1Skamil TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 23931.1Skamil} 23941.1Skamil 23951.61Skre#define EVENTMASK_PRESERVED(test, event) \ 23961.61SkreATF_TC(test); \ 23971.61SkreATF_TC_HEAD(test, tc) \ 23981.61Skre{ \ 23991.61Skre atf_tc_set_md_var(tc, "descr", \ 24001.61Skre "Verify that eventmask " #event " is preserved"); \ 24011.61Skre} \ 24021.61Skre \ 24031.61SkreATF_TC_BODY(test, tc) \ 24041.61Skre{ \ 24051.61Skre \ 24061.61Skre eventmask_preserved(event); \ 24071.1Skamil} 24081.1Skamil 24091.53SkamilEVENTMASK_PRESERVED(eventmask_preserved_empty, 0) 24101.53SkamilEVENTMASK_PRESERVED(eventmask_preserved_fork, PTRACE_FORK) 24111.53SkamilEVENTMASK_PRESERVED(eventmask_preserved_vfork, PTRACE_VFORK) 24121.53SkamilEVENTMASK_PRESERVED(eventmask_preserved_vfork_done, PTRACE_VFORK_DONE) 24131.53SkamilEVENTMASK_PRESERVED(eventmask_preserved_lwp_create, PTRACE_LWP_CREATE) 24141.53SkamilEVENTMASK_PRESERVED(eventmask_preserved_lwp_exit, PTRACE_LWP_EXIT) 24151.1Skamil 24161.53Skamil/// ---------------------------------------------------------------------------- 24171.1Skamil 24181.28Skamilstatic void 24191.32Skamilfork_body(pid_t (*fn)(void), bool trackfork, bool trackvfork, 24201.61Skre bool trackvforkdone, bool detachchild, bool detachparent) 24211.1Skamil{ 24221.1Skamil const int exitval = 5; 24231.1Skamil const int exitval2 = 15; 24241.1Skamil const int sigval = SIGSTOP; 24251.31Skamil pid_t child, child2 = 0, wpid; 24261.1Skamil#if defined(TWAIT_HAVE_STATUS) 24271.1Skamil int status; 24281.1Skamil#endif 24291.1Skamil ptrace_state_t state; 24301.1Skamil const int slen = sizeof(state); 24311.1Skamil ptrace_event_t event; 24321.1Skamil const int elen = sizeof(event); 24331.1Skamil 24341.13Schristos DPRINTF("Before forking process PID=%d\n", getpid()); 24351.13Schristos SYSCALL_REQUIRE((child = fork()) != -1); 24361.1Skamil if (child == 0) { 24371.13Schristos DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 24381.1Skamil FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 24391.1Skamil 24401.13Schristos DPRINTF("Before raising %s from child\n", strsignal(sigval)); 24411.1Skamil FORKEE_ASSERT(raise(sigval) == 0); 24421.1Skamil 24431.30Skamil FORKEE_ASSERT((child2 = (fn)()) != -1); 24441.1Skamil 24451.1Skamil if (child2 == 0) 24461.1Skamil _exit(exitval2); 24471.1Skamil 24481.1Skamil FORKEE_REQUIRE_SUCCESS 24491.1Skamil (wpid = TWAIT_GENERIC(child2, &status, 0), child2); 24501.1Skamil 24511.1Skamil forkee_status_exited(status, exitval2); 24521.1Skamil 24531.13Schristos DPRINTF("Before exiting of the child process\n"); 24541.1Skamil _exit(exitval); 24551.1Skamil } 24561.13Schristos DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 24571.1Skamil 24581.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 24591.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 24601.1Skamil 24611.1Skamil validate_status_stopped(status, sigval); 24621.1Skamil 24631.30Skamil DPRINTF("Set 0%s%s%s in EVENT_MASK for the child %d\n", 24641.61Skre trackfork ? "|PTRACE_FORK" : "", 24651.61Skre trackvfork ? "|PTRACE_VFORK" : "", 24661.61Skre trackvforkdone ? "|PTRACE_VFORK_DONE" : "", child); 24671.30Skamil event.pe_set_event = 0; 24681.30Skamil if (trackfork) 24691.30Skamil event.pe_set_event |= PTRACE_FORK; 24701.30Skamil if (trackvfork) 24711.30Skamil event.pe_set_event |= PTRACE_VFORK; 24721.30Skamil if (trackvforkdone) 24731.30Skamil event.pe_set_event |= PTRACE_VFORK_DONE; 24741.13Schristos SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); 24751.1Skamil 24761.13Schristos DPRINTF("Before resuming the child process where it left off and " 24771.1Skamil "without signal to be sent\n"); 24781.13Schristos SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 24791.1Skamil 24801.29Skamil#if defined(TWAIT_HAVE_PID) 24811.31Skamil if ((trackfork && fn == fork) || (trackvfork && fn == vfork)) { 24821.29Skamil DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME, 24831.61Skre child); 24841.29Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), 24851.61Skre child); 24861.1Skamil 24871.29Skamil validate_status_stopped(status, SIGTRAP); 24881.1Skamil 24891.61Skre SYSCALL_REQUIRE( 24901.61Skre ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 24911.31Skamil if (trackfork && fn == fork) { 24921.30Skamil ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK, 24931.30Skamil PTRACE_FORK); 24941.30Skamil } 24951.31Skamil if (trackvfork && fn == vfork) { 24961.30Skamil ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK, 24971.30Skamil PTRACE_VFORK); 24981.30Skamil } 24991.29Skamil 25001.29Skamil child2 = state.pe_other_pid; 25011.30Skamil DPRINTF("Reported ptrace event with forkee %d\n", child2); 25021.29Skamil 25031.29Skamil DPRINTF("Before calling %s() for the forkee %d of the child " 25041.61Skre "%d\n", TWAIT_FNAME, child2, child); 25051.29Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0), 25061.29Skamil child2); 25071.1Skamil 25081.29Skamil validate_status_stopped(status, SIGTRAP); 25091.1Skamil 25101.61Skre SYSCALL_REQUIRE( 25111.61Skre ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1); 25121.31Skamil if (trackfork && fn == fork) { 25131.30Skamil ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK, 25141.30Skamil PTRACE_FORK); 25151.30Skamil } 25161.31Skamil if (trackvfork && fn == vfork) { 25171.30Skamil ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK, 25181.30Skamil PTRACE_VFORK); 25191.30Skamil } 25201.30Skamil 25211.29Skamil ATF_REQUIRE_EQ(state.pe_other_pid, child); 25221.29Skamil 25231.29Skamil DPRINTF("Before resuming the forkee process where it left off " 25241.29Skamil "and without signal to be sent\n"); 25251.61Skre SYSCALL_REQUIRE( 25261.61Skre ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1); 25271.29Skamil 25281.29Skamil DPRINTF("Before resuming the child process where it left off " 25291.61Skre "and without signal to be sent\n"); 25301.29Skamil SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 25311.30Skamil } 25321.30Skamil#endif 25331.30Skamil 25341.31Skamil if (trackvforkdone && fn == vfork) { 25351.30Skamil DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME, 25361.61Skre child); 25371.61Skre TWAIT_REQUIRE_SUCCESS( 25381.61Skre wpid = TWAIT_GENERIC(child, &status, 0), child); 25391.30Skamil 25401.30Skamil validate_status_stopped(status, SIGTRAP); 25411.30Skamil 25421.61Skre SYSCALL_REQUIRE( 25431.61Skre ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 25441.30Skamil ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK_DONE); 25451.30Skamil 25461.30Skamil child2 = state.pe_other_pid; 25471.30Skamil DPRINTF("Reported PTRACE_VFORK_DONE event with forkee %d\n", 25481.61Skre child2); 25491.30Skamil 25501.30Skamil DPRINTF("Before resuming the child process where it left off " 25511.61Skre "and without signal to be sent\n"); 25521.30Skamil SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 25531.30Skamil } 25541.29Skamil 25551.30Skamil#if defined(TWAIT_HAVE_PID) 25561.31Skamil if ((trackfork && fn == fork) || (trackvfork && fn == vfork)) { 25571.29Skamil DPRINTF("Before calling %s() for the forkee - expected exited" 25581.61Skre "\n", TWAIT_FNAME); 25591.61Skre TWAIT_REQUIRE_SUCCESS( 25601.61Skre wpid = TWAIT_GENERIC(child2, &status, 0), child2); 25611.29Skamil 25621.29Skamil validate_status_exited(status, exitval2); 25631.29Skamil 25641.29Skamil DPRINTF("Before calling %s() for the forkee - expected no " 25651.61Skre "process\n", TWAIT_FNAME); 25661.29Skamil TWAIT_REQUIRE_FAILURE(ECHILD, 25671.29Skamil wpid = TWAIT_GENERIC(child2, &status, 0)); 25681.29Skamil } 25691.29Skamil#endif 25701.1Skamil 25711.13Schristos DPRINTF("Before calling %s() for the child - expected stopped " 25721.1Skamil "SIGCHLD\n", TWAIT_FNAME); 25731.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 25741.1Skamil 25751.1Skamil validate_status_stopped(status, SIGCHLD); 25761.1Skamil 25771.13Schristos DPRINTF("Before resuming the child process where it left off and " 25781.1Skamil "without signal to be sent\n"); 25791.13Schristos SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 25801.1Skamil 25811.13Schristos DPRINTF("Before calling %s() for the child - expected exited\n", 25821.1Skamil TWAIT_FNAME); 25831.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 25841.1Skamil 25851.1Skamil validate_status_exited(status, exitval); 25861.1Skamil 25871.13Schristos DPRINTF("Before calling %s() for the child - expected no process\n", 25881.1Skamil TWAIT_FNAME); 25891.1Skamil TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 25901.1Skamil} 25911.28Skamil 25921.61Skre#define FORK_TEST(name,descr,fun,tfork,tvfork,tvforkdone,detchild,detparent) \ 25931.61SkreATF_TC(name); \ 25941.61SkreATF_TC_HEAD(name, tc) \ 25951.61Skre{ \ 25961.61Skre atf_tc_set_md_var(tc, "descr", descr); \ 25971.61Skre} \ 25981.61Skre \ 25991.61SkreATF_TC_BODY(name, tc) \ 26001.61Skre{ \ 26011.61Skre \ 26021.61Skre fork_body(fun, tfork, tvfork, tvforkdone, detchild, detparent); \ 26031.32Skamil} 26041.32Skamil 26051.32Skamil#define F false 26061.32Skamil#define T true 26071.32Skamil 26081.32Skamil#define F_IF__0(x) 26091.32Skamil#define F_IF__1(x) x 26101.32Skamil#define F_IF__(x,y) F_IF__ ## x (y) 26111.32Skamil#define F_IF_(x,y) F_IF__(x,y) 26121.32Skamil#define F_IF(x,y) F_IF_(x,y) 26131.32Skamil 26141.61Skre#define DSCR(function,forkbit,vforkbit,vforkdonebit,dchildbit,dparentbit) \ 26151.61Skre "Verify " #function "(2) called with 0" \ 26161.61Skre F_IF(forkbit,"|PTRACE_FORK") \ 26171.61Skre F_IF(vforkbit,"|PTRACE_VFORK") \ 26181.61Skre F_IF(vforkdonebit,"|PTRACE_VFORK_DONE") \ 26191.61Skre " in EVENT_MASK." \ 26201.61Skre F_IF(dchildbit," Detach child in this test.") \ 26211.61Skre F_IF(dparentbit," Detach parent in this test.") 26221.1Skamil 26231.32SkamilFORK_TEST(fork1, DSCR(fork,0,0,0,0,0), fork, F, F, F, F, F) 26241.31Skamil#if defined(TWAIT_HAVE_PID) 26251.32SkamilFORK_TEST(fork2, DSCR(fork,1,0,0,0,0), fork, T, F, F, F, F) 26261.32SkamilFORK_TEST(fork3, DSCR(fork,0,1,0,0,0), fork, F, T, F, F, F) 26271.32SkamilFORK_TEST(fork4, DSCR(fork,1,1,0,0,0), fork, T, T, F, F, F) 26281.31Skamil#endif 26291.32SkamilFORK_TEST(fork5, DSCR(fork,0,0,1,0,0), fork, F, F, T, F, F) 26301.31Skamil#if defined(TWAIT_HAVE_PID) 26311.32SkamilFORK_TEST(fork6, DSCR(fork,1,0,1,0,0), fork, T, F, T, F, F) 26321.32SkamilFORK_TEST(fork7, DSCR(fork,0,1,1,0,0), fork, F, T, T, F, F) 26331.32SkamilFORK_TEST(fork8, DSCR(fork,1,1,1,0,0), fork, T, T, T, F, F) 26341.31Skamil#endif 26351.1Skamil 26361.32SkamilFORK_TEST(vfork1, DSCR(vfork,0,0,0,0,0), vfork, F, F, F, F, F) 26371.31Skamil#if defined(TWAIT_HAVE_PID) 26381.32SkamilFORK_TEST(vfork2, DSCR(vfork,1,0,0,0,0), vfork, T, F, F, F, F) 26391.32SkamilFORK_TEST(vfork3, DSCR(vfork,0,1,0,0,0), vfork, F, T, F, F, F) 26401.32SkamilFORK_TEST(vfork4, DSCR(vfork,1,1,0,0,0), vfork, T, T, F, F, F) 26411.31Skamil#endif 26421.32SkamilFORK_TEST(vfork5, DSCR(vfork,0,0,1,0,0), vfork, F, F, T, F, F) 26431.31Skamil#if defined(TWAIT_HAVE_PID) 26441.32SkamilFORK_TEST(vfork6, DSCR(vfork,1,0,1,0,0), vfork, T, F, T, F, F) 26451.32SkamilFORK_TEST(vfork7, DSCR(vfork,0,1,1,0,0), vfork, F, T, T, F, F) 26461.32SkamilFORK_TEST(vfork8, DSCR(vfork,1,1,1,0,0), vfork, T, T, T, F, F) 26471.31Skamil#endif 26481.31Skamil 26491.54Skamil/// ---------------------------------------------------------------------------- 26501.31Skamil 26511.54Skamilenum bytes_transfer_type { 26521.54Skamil BYTES_TRANSFER_DATA, 26531.54Skamil BYTES_TRANSFER_DATAIO, 26541.54Skamil BYTES_TRANSFER_TEXT, 26551.54Skamil BYTES_TRANSFER_TEXTIO, 26561.54Skamil BYTES_TRANSFER_AUXV 26571.54Skamil}; 26581.31Skamil 26591.54Skamilstatic int __used 26601.54Skamilbytes_transfer_dummy(int a, int b, int c, int d) 26611.54Skamil{ 26621.54Skamil int e, f, g, h; 26631.1Skamil 26641.54Skamil a *= 4; 26651.54Skamil b += 3; 26661.54Skamil c -= 2; 26671.54Skamil d /= 1; 26681.1Skamil 26691.54Skamil e = strtol("10", NULL, 10); 26701.54Skamil f = strtol("20", NULL, 10); 26711.54Skamil g = strtol("30", NULL, 10); 26721.54Skamil h = strtol("40", NULL, 10); 26731.1Skamil 26741.54Skamil return (a + b * c - d) + (e * f - g / h); 26751.1Skamil} 26761.1Skamil 26771.54Skamilstatic void 26781.55Schristosbytes_transfer(int operation, size_t size, enum bytes_transfer_type type) 26791.1Skamil{ 26801.1Skamil const int exitval = 5; 26811.1Skamil const int sigval = SIGSTOP; 26821.1Skamil pid_t child, wpid; 26831.54Skamil bool skip = false; 26841.1Skamil 26851.54Skamil int lookup_me = 0; 26861.54Skamil uint8_t lookup_me8 = 0; 26871.54Skamil uint16_t lookup_me16 = 0; 26881.54Skamil uint32_t lookup_me32 = 0; 26891.54Skamil uint64_t lookup_me64 = 0; 26901.1Skamil 26911.54Skamil int magic = 0x13579246; 26921.54Skamil uint8_t magic8 = 0xab; 26931.54Skamil uint16_t magic16 = 0x1234; 26941.54Skamil uint32_t magic32 = 0x98765432; 26951.54Skamil uint64_t magic64 = 0xabcdef0123456789; 26961.1Skamil 26971.54Skamil struct ptrace_io_desc io; 26981.1Skamil#if defined(TWAIT_HAVE_STATUS) 26991.1Skamil int status; 27001.1Skamil#endif 27011.60Skre /* 513 is just enough, for the purposes of ATF it's good enough */ 27021.60Skre AuxInfo ai[513], *aip; 27031.55Schristos 27041.55Schristos ATF_REQUIRE(size < sizeof(ai)); 27051.1Skamil 27061.54Skamil /* Prepare variables for .TEXT transfers */ 27071.54Skamil switch (type) { 27081.54Skamil case BYTES_TRANSFER_TEXT: 27091.54Skamil memcpy(&magic, bytes_transfer_dummy, sizeof(magic)); 27101.54Skamil break; 27111.54Skamil case BYTES_TRANSFER_TEXTIO: 27121.54Skamil switch (size) { 27131.54Skamil case 8: 27141.54Skamil memcpy(&magic8, bytes_transfer_dummy, sizeof(magic8)); 27151.54Skamil break; 27161.54Skamil case 16: 27171.54Skamil memcpy(&magic16, bytes_transfer_dummy, sizeof(magic16)); 27181.54Skamil break; 27191.54Skamil case 32: 27201.54Skamil memcpy(&magic32, bytes_transfer_dummy, sizeof(magic32)); 27211.54Skamil break; 27221.54Skamil case 64: 27231.54Skamil memcpy(&magic64, bytes_transfer_dummy, sizeof(magic64)); 27241.54Skamil break; 27251.54Skamil } 27261.54Skamil break; 27271.54Skamil default: 27281.54Skamil break; 27291.54Skamil } 27301.1Skamil 27311.54Skamil /* Prepare variables for PIOD and AUXV transfers */ 27321.54Skamil switch (type) { 27331.54Skamil case BYTES_TRANSFER_TEXTIO: 27341.54Skamil case BYTES_TRANSFER_DATAIO: 27351.54Skamil io.piod_op = operation; 27361.54Skamil switch (size) { 27371.54Skamil case 8: 27381.54Skamil io.piod_offs = (type == BYTES_TRANSFER_TEXTIO) ? 27391.54Skamil (void *)bytes_transfer_dummy : 27401.54Skamil &lookup_me8; 27411.54Skamil io.piod_addr = &lookup_me8; 27421.54Skamil io.piod_len = sizeof(lookup_me8); 27431.54Skamil break; 27441.54Skamil case 16: 27451.54Skamil io.piod_offs = (type == BYTES_TRANSFER_TEXTIO) ? 27461.54Skamil (void *)bytes_transfer_dummy : 27471.54Skamil &lookup_me16; 27481.54Skamil io.piod_addr = &lookup_me16; 27491.54Skamil io.piod_len = sizeof(lookup_me16); 27501.54Skamil break; 27511.54Skamil case 32: 27521.54Skamil io.piod_offs = (type == BYTES_TRANSFER_TEXTIO) ? 27531.54Skamil (void *)bytes_transfer_dummy : 27541.54Skamil &lookup_me32; 27551.54Skamil io.piod_addr = &lookup_me32; 27561.54Skamil io.piod_len = sizeof(lookup_me32); 27571.54Skamil break; 27581.54Skamil case 64: 27591.54Skamil io.piod_offs = (type == BYTES_TRANSFER_TEXTIO) ? 27601.54Skamil (void *)bytes_transfer_dummy : 27611.54Skamil &lookup_me64; 27621.54Skamil io.piod_addr = &lookup_me64; 27631.54Skamil io.piod_len = sizeof(lookup_me64); 27641.54Skamil break; 27651.54Skamil default: 27661.54Skamil break; 27671.54Skamil } 27681.54Skamil break; 27691.54Skamil case BYTES_TRANSFER_AUXV: 27701.54Skamil io.piod_op = operation; 27711.54Skamil io.piod_offs = 0; 27721.54Skamil io.piod_addr = ai; 27731.54Skamil io.piod_len = size; 27741.54Skamil break; 27751.54Skamil default: 27761.54Skamil break; 27771.1Skamil } 27781.1Skamil 27791.13Schristos DPRINTF("Before forking process PID=%d\n", getpid()); 27801.13Schristos SYSCALL_REQUIRE((child = fork()) != -1); 27811.1Skamil if (child == 0) { 27821.13Schristos DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 27831.1Skamil FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 27841.1Skamil 27851.54Skamil switch (type) { 27861.54Skamil case BYTES_TRANSFER_DATA: 27871.54Skamil switch (operation) { 27881.54Skamil case PT_READ_D: 27891.54Skamil case PT_READ_I: 27901.54Skamil lookup_me = magic; 27911.54Skamil break; 27921.54Skamil default: 27931.54Skamil break; 27941.54Skamil } 27951.54Skamil break; 27961.54Skamil case BYTES_TRANSFER_DATAIO: 27971.54Skamil switch (operation) { 27981.54Skamil case PIOD_READ_D: 27991.54Skamil case PIOD_READ_I: 28001.54Skamil switch (size) { 28011.54Skamil case 8: 28021.54Skamil lookup_me8 = magic8; 28031.54Skamil break; 28041.54Skamil case 16: 28051.54Skamil lookup_me16 = magic16; 28061.54Skamil break; 28071.54Skamil case 32: 28081.54Skamil lookup_me32 = magic32; 28091.54Skamil break; 28101.54Skamil case 64: 28111.54Skamil lookup_me64 = magic64; 28121.54Skamil break; 28131.54Skamil default: 28141.54Skamil break; 28151.54Skamil } 28161.54Skamil break; 28171.54Skamil default: 28181.54Skamil break; 28191.54Skamil } 28201.54Skamil default: 28211.54Skamil break; 28221.54Skamil } 28231.54Skamil 28241.13Schristos DPRINTF("Before raising %s from child\n", strsignal(sigval)); 28251.1Skamil FORKEE_ASSERT(raise(sigval) == 0); 28261.1Skamil 28271.54Skamil /* Handle PIOD and PT separately as operation values overlap */ 28281.54Skamil switch (type) { 28291.54Skamil case BYTES_TRANSFER_DATA: 28301.54Skamil switch (operation) { 28311.54Skamil case PT_WRITE_D: 28321.54Skamil case PT_WRITE_I: 28331.54Skamil FORKEE_ASSERT_EQ(lookup_me, magic); 28341.54Skamil break; 28351.54Skamil default: 28361.54Skamil break; 28371.54Skamil } 28381.54Skamil break; 28391.54Skamil case BYTES_TRANSFER_DATAIO: 28401.54Skamil switch (operation) { 28411.54Skamil case PIOD_WRITE_D: 28421.54Skamil case PIOD_WRITE_I: 28431.54Skamil switch (size) { 28441.54Skamil case 8: 28451.54Skamil FORKEE_ASSERT_EQ(lookup_me8, magic8); 28461.54Skamil break; 28471.54Skamil case 16: 28481.54Skamil FORKEE_ASSERT_EQ(lookup_me16, magic16); 28491.54Skamil break; 28501.54Skamil case 32: 28511.54Skamil FORKEE_ASSERT_EQ(lookup_me32, magic32); 28521.54Skamil break; 28531.54Skamil case 64: 28541.54Skamil FORKEE_ASSERT_EQ(lookup_me64, magic64); 28551.54Skamil break; 28561.54Skamil default: 28571.54Skamil break; 28581.54Skamil } 28591.54Skamil break; 28601.54Skamil default: 28611.54Skamil break; 28621.54Skamil } 28631.54Skamil break; 28641.54Skamil case BYTES_TRANSFER_TEXT: 28651.54Skamil FORKEE_ASSERT(memcmp(&magic, bytes_transfer_dummy, 28661.54Skamil sizeof(magic)) == 0); 28671.54Skamil break; 28681.54Skamil case BYTES_TRANSFER_TEXTIO: 28691.54Skamil switch (size) { 28701.54Skamil case 8: 28711.54Skamil FORKEE_ASSERT(memcmp(&magic8, 28721.54Skamil bytes_transfer_dummy, 28731.54Skamil sizeof(magic8)) == 0); 28741.54Skamil break; 28751.54Skamil case 16: 28761.54Skamil FORKEE_ASSERT(memcmp(&magic16, 28771.54Skamil bytes_transfer_dummy, 28781.54Skamil sizeof(magic16)) == 0); 28791.54Skamil break; 28801.54Skamil case 32: 28811.54Skamil FORKEE_ASSERT(memcmp(&magic32, 28821.54Skamil bytes_transfer_dummy, 28831.54Skamil sizeof(magic32)) == 0); 28841.54Skamil break; 28851.54Skamil case 64: 28861.54Skamil FORKEE_ASSERT(memcmp(&magic64, 28871.54Skamil bytes_transfer_dummy, 28881.54Skamil sizeof(magic64)) == 0); 28891.54Skamil break; 28901.54Skamil } 28911.54Skamil break; 28921.54Skamil default: 28931.54Skamil break; 28941.54Skamil } 28951.54Skamil 28961.13Schristos DPRINTF("Before exiting of the child process\n"); 28971.1Skamil _exit(exitval); 28981.1Skamil } 28991.13Schristos DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 29001.1Skamil 29011.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 29021.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 29031.1Skamil 29041.1Skamil validate_status_stopped(status, sigval); 29051.1Skamil 29061.54Skamil /* Check PaX MPROTECT */ 29071.54Skamil if (!can_we_write_to_text(child)) { 29081.54Skamil switch (type) { 29091.54Skamil case BYTES_TRANSFER_TEXTIO: 29101.54Skamil switch (operation) { 29111.54Skamil case PIOD_WRITE_D: 29121.54Skamil case PIOD_WRITE_I: 29131.54Skamil skip = true; 29141.54Skamil break; 29151.54Skamil default: 29161.54Skamil break; 29171.54Skamil } 29181.54Skamil break; 29191.54Skamil case BYTES_TRANSFER_TEXT: 29201.54Skamil switch (operation) { 29211.54Skamil case PT_WRITE_D: 29221.54Skamil case PT_WRITE_I: 29231.54Skamil skip = true; 29241.54Skamil break; 29251.54Skamil default: 29261.54Skamil break; 29271.54Skamil } 29281.54Skamil break; 29291.54Skamil default: 29301.54Skamil break; 29311.54Skamil } 29321.54Skamil } 29331.1Skamil 29341.54Skamil /* Bailout cleanly killing the child process */ 29351.54Skamil if (skip) { 29361.54Skamil SYSCALL_REQUIRE(ptrace(PT_KILL, child, (void *)1, 0) != -1); 29371.54Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 29381.54Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), 29391.54Skamil child); 29401.1Skamil 29411.54Skamil validate_status_signaled(status, SIGKILL, 0); 29421.1Skamil 29431.54Skamil atf_tc_skip("PaX MPROTECT setup prevents writes to .text"); 29441.54Skamil } 29451.1Skamil 29461.54Skamil DPRINTF("Calling operation to transfer bytes between child=%d and " 29471.54Skamil "parent=%d\n", child, getpid()); 29481.1Skamil 29491.54Skamil switch (type) { 29501.54Skamil case BYTES_TRANSFER_TEXTIO: 29511.54Skamil case BYTES_TRANSFER_DATAIO: 29521.54Skamil case BYTES_TRANSFER_AUXV: 29531.54Skamil switch (operation) { 29541.54Skamil case PIOD_WRITE_D: 29551.54Skamil case PIOD_WRITE_I: 29561.54Skamil switch (size) { 29571.54Skamil case 8: 29581.54Skamil lookup_me8 = magic8; 29591.54Skamil break; 29601.54Skamil case 16: 29611.54Skamil lookup_me16 = magic16; 29621.54Skamil break; 29631.54Skamil case 32: 29641.54Skamil lookup_me32 = magic32; 29651.54Skamil break; 29661.54Skamil case 64: 29671.54Skamil lookup_me64 = magic64; 29681.54Skamil break; 29691.54Skamil default: 29701.54Skamil break; 29711.54Skamil } 29721.54Skamil break; 29731.54Skamil default: 29741.54Skamil break; 29751.54Skamil } 29761.54Skamil SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1); 29771.54Skamil switch (operation) { 29781.54Skamil case PIOD_READ_D: 29791.54Skamil case PIOD_READ_I: 29801.54Skamil switch (size) { 29811.54Skamil case 8: 29821.54Skamil ATF_REQUIRE_EQ(lookup_me8, magic8); 29831.54Skamil break; 29841.54Skamil case 16: 29851.54Skamil ATF_REQUIRE_EQ(lookup_me16, magic16); 29861.54Skamil break; 29871.54Skamil case 32: 29881.54Skamil ATF_REQUIRE_EQ(lookup_me32, magic32); 29891.54Skamil break; 29901.54Skamil case 64: 29911.54Skamil ATF_REQUIRE_EQ(lookup_me64, magic64); 29921.54Skamil break; 29931.54Skamil default: 29941.54Skamil break; 29951.54Skamil } 29961.54Skamil break; 29971.54Skamil case PIOD_READ_AUXV: 29981.54Skamil DPRINTF("Asserting that AUXV length (%zu) is > 0\n", 29991.54Skamil io.piod_len); 30001.54Skamil ATF_REQUIRE(io.piod_len > 0); 30011.54Skamil for (aip = ai; aip->a_type != AT_NULL; aip++) 30021.54Skamil DPRINTF("a_type=%#llx a_v=%#llx\n", 30031.54Skamil (long long int)aip->a_type, 30041.54Skamil (long long int)aip->a_v); 30051.54Skamil break; 30061.54Skamil default: 30071.54Skamil break; 30081.54Skamil } 30091.54Skamil break; 30101.54Skamil case BYTES_TRANSFER_TEXT: 30111.54Skamil switch (operation) { 30121.54Skamil case PT_READ_D: 30131.54Skamil case PT_READ_I: 30141.54Skamil errno = 0; 30151.54Skamil lookup_me = ptrace(operation, child, 30161.54Skamil bytes_transfer_dummy, 0); 30171.54Skamil ATF_REQUIRE_EQ(lookup_me, magic); 30181.54Skamil SYSCALL_REQUIRE_ERRNO(errno, 0); 30191.54Skamil break; 30201.54Skamil case PT_WRITE_D: 30211.54Skamil case PT_WRITE_I: 30221.54Skamil SYSCALL_REQUIRE(ptrace(operation, child, 30231.54Skamil bytes_transfer_dummy, magic) 30241.54Skamil != -1); 30251.54Skamil break; 30261.54Skamil default: 30271.54Skamil break; 30281.54Skamil } 30291.54Skamil break; 30301.54Skamil case BYTES_TRANSFER_DATA: 30311.54Skamil switch (operation) { 30321.54Skamil case PT_READ_D: 30331.54Skamil case PT_READ_I: 30341.54Skamil errno = 0; 30351.54Skamil lookup_me = ptrace(operation, child, &lookup_me, 0); 30361.54Skamil ATF_REQUIRE_EQ(lookup_me, magic); 30371.54Skamil SYSCALL_REQUIRE_ERRNO(errno, 0); 30381.54Skamil break; 30391.54Skamil case PT_WRITE_D: 30401.54Skamil case PT_WRITE_I: 30411.54Skamil lookup_me = magic; 30421.54Skamil SYSCALL_REQUIRE(ptrace(operation, child, &lookup_me, 30431.54Skamil magic) != -1); 30441.54Skamil break; 30451.54Skamil default: 30461.54Skamil break; 30471.54Skamil } 30481.54Skamil break; 30491.54Skamil default: 30501.54Skamil break; 30511.54Skamil } 30521.1Skamil 30531.13Schristos DPRINTF("Before resuming the child process where it left off and " 30541.1Skamil "without signal to be sent\n"); 30551.13Schristos SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 30561.1Skamil 30571.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 30581.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 30591.1Skamil 30601.1Skamil validate_status_exited(status, exitval); 30611.1Skamil 30621.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 30631.1Skamil TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 30641.1Skamil} 30651.1Skamil 30661.61Skre#define BYTES_TRANSFER(test, operation, size, type) \ 30671.61SkreATF_TC(test); \ 30681.61SkreATF_TC_HEAD(test, tc) \ 30691.61Skre{ \ 30701.61Skre atf_tc_set_md_var(tc, "descr", \ 30711.61Skre "Verify bytes transfer operation" #operation " and size " #size \ 30721.61Skre " of type " #type); \ 30731.61Skre} \ 30741.61Skre \ 30751.61SkreATF_TC_BODY(test, tc) \ 30761.61Skre{ \ 30771.61Skre \ 30781.61Skre bytes_transfer(operation, size, BYTES_TRANSFER_##type); \ 30791.1Skamil} 30801.1Skamil 30811.54Skamil// DATA 30821.1Skamil 30831.54SkamilBYTES_TRANSFER(bytes_transfer_piod_read_d_8, PIOD_READ_D, 8, DATAIO) 30841.54SkamilBYTES_TRANSFER(bytes_transfer_piod_read_d_16, PIOD_READ_D, 16, DATAIO) 30851.54SkamilBYTES_TRANSFER(bytes_transfer_piod_read_d_32, PIOD_READ_D, 32, DATAIO) 30861.54SkamilBYTES_TRANSFER(bytes_transfer_piod_read_d_64, PIOD_READ_D, 64, DATAIO) 30871.54Skamil 30881.54SkamilBYTES_TRANSFER(bytes_transfer_piod_read_i_8, PIOD_READ_I, 8, DATAIO) 30891.54SkamilBYTES_TRANSFER(bytes_transfer_piod_read_i_16, PIOD_READ_I, 16, DATAIO) 30901.54SkamilBYTES_TRANSFER(bytes_transfer_piod_read_i_32, PIOD_READ_I, 32, DATAIO) 30911.54SkamilBYTES_TRANSFER(bytes_transfer_piod_read_i_64, PIOD_READ_I, 64, DATAIO) 30921.54Skamil 30931.54SkamilBYTES_TRANSFER(bytes_transfer_piod_write_d_8, PIOD_WRITE_D, 8, DATAIO) 30941.54SkamilBYTES_TRANSFER(bytes_transfer_piod_write_d_16, PIOD_WRITE_D, 16, DATAIO) 30951.54SkamilBYTES_TRANSFER(bytes_transfer_piod_write_d_32, PIOD_WRITE_D, 32, DATAIO) 30961.54SkamilBYTES_TRANSFER(bytes_transfer_piod_write_d_64, PIOD_WRITE_D, 64, DATAIO) 30971.54Skamil 30981.54SkamilBYTES_TRANSFER(bytes_transfer_piod_write_i_8, PIOD_WRITE_I, 8, DATAIO) 30991.54SkamilBYTES_TRANSFER(bytes_transfer_piod_write_i_16, PIOD_WRITE_I, 16, DATAIO) 31001.54SkamilBYTES_TRANSFER(bytes_transfer_piod_write_i_32, PIOD_WRITE_I, 32, DATAIO) 31011.54SkamilBYTES_TRANSFER(bytes_transfer_piod_write_i_64, PIOD_WRITE_I, 64, DATAIO) 31021.54Skamil 31031.54SkamilBYTES_TRANSFER(bytes_transfer_read_d, PT_READ_D, 32, DATA) 31041.54SkamilBYTES_TRANSFER(bytes_transfer_read_i, PT_READ_I, 32, DATA) 31051.54SkamilBYTES_TRANSFER(bytes_transfer_write_d, PT_WRITE_D, 32, DATA) 31061.54SkamilBYTES_TRANSFER(bytes_transfer_write_i, PT_WRITE_I, 32, DATA) 31071.54Skamil 31081.54Skamil// TEXT 31091.54Skamil 31101.54SkamilBYTES_TRANSFER(bytes_transfer_piod_read_d_8_text, PIOD_READ_D, 8, TEXTIO) 31111.54SkamilBYTES_TRANSFER(bytes_transfer_piod_read_d_16_text, PIOD_READ_D, 16, TEXTIO) 31121.54SkamilBYTES_TRANSFER(bytes_transfer_piod_read_d_32_text, PIOD_READ_D, 32, TEXTIO) 31131.54SkamilBYTES_TRANSFER(bytes_transfer_piod_read_d_64_text, PIOD_READ_D, 64, TEXTIO) 31141.54Skamil 31151.54SkamilBYTES_TRANSFER(bytes_transfer_piod_read_i_8_text, PIOD_READ_I, 8, TEXTIO) 31161.54SkamilBYTES_TRANSFER(bytes_transfer_piod_read_i_16_text, PIOD_READ_I, 16, TEXTIO) 31171.54SkamilBYTES_TRANSFER(bytes_transfer_piod_read_i_32_text, PIOD_READ_I, 32, TEXTIO) 31181.54SkamilBYTES_TRANSFER(bytes_transfer_piod_read_i_64_text, PIOD_READ_I, 64, TEXTIO) 31191.54Skamil 31201.54SkamilBYTES_TRANSFER(bytes_transfer_piod_write_d_8_text, PIOD_WRITE_D, 8, TEXTIO) 31211.54SkamilBYTES_TRANSFER(bytes_transfer_piod_write_d_16_text, PIOD_WRITE_D, 16, TEXTIO) 31221.54SkamilBYTES_TRANSFER(bytes_transfer_piod_write_d_32_text, PIOD_WRITE_D, 32, TEXTIO) 31231.54SkamilBYTES_TRANSFER(bytes_transfer_piod_write_d_64_text, PIOD_WRITE_D, 64, TEXTIO) 31241.54Skamil 31251.54SkamilBYTES_TRANSFER(bytes_transfer_piod_write_i_8_text, PIOD_WRITE_I, 8, TEXTIO) 31261.54SkamilBYTES_TRANSFER(bytes_transfer_piod_write_i_16_text, PIOD_WRITE_I, 16, TEXTIO) 31271.54SkamilBYTES_TRANSFER(bytes_transfer_piod_write_i_32_text, PIOD_WRITE_I, 32, TEXTIO) 31281.54SkamilBYTES_TRANSFER(bytes_transfer_piod_write_i_64_text, PIOD_WRITE_I, 64, TEXTIO) 31291.54Skamil 31301.54SkamilBYTES_TRANSFER(bytes_transfer_read_d_text, PT_READ_D, 32, TEXT) 31311.54SkamilBYTES_TRANSFER(bytes_transfer_read_i_text, PT_READ_I, 32, TEXT) 31321.54SkamilBYTES_TRANSFER(bytes_transfer_write_d_text, PT_WRITE_D, 32, TEXT) 31331.54SkamilBYTES_TRANSFER(bytes_transfer_write_i_text, PT_WRITE_I, 32, TEXT) 31341.1Skamil 31351.54Skamil// AUXV 31361.1Skamil 31371.54SkamilBYTES_TRANSFER(bytes_transfer_piod_read_auxv, PIOD_READ_AUXV, 4096, AUXV) 31381.1Skamil 31391.54Skamil/// ---------------------------------------------------------------------------- 31401.1Skamil 31411.76Sscole#if defined(HAVE_GPREGS) || defined(HAVE_FPREGS) 31421.72Skamilstatic void 31431.72Skamilaccess_regs(const char *regset, const char *aux) 31441.1Skamil{ 31451.1Skamil const int exitval = 5; 31461.1Skamil const int sigval = SIGSTOP; 31471.1Skamil pid_t child, wpid; 31481.1Skamil#if defined(TWAIT_HAVE_STATUS) 31491.1Skamil int status; 31501.1Skamil#endif 31511.72Skamil#if defined(HAVE_GPREGS) 31521.72Skamil struct reg gpr; 31531.76Sscole register_t rgstr; 31541.1Skamil#endif 31551.72Skamil#if defined(HAVE_FPREGS) 31561.72Skamil struct fpreg fpr; 31571.1Skamil#endif 31581.76Sscole 31591.72Skamil#if !defined(HAVE_GPREGS) 31601.72Skamil if (strcmp(regset, "regs") == 0) 31611.72Skamil atf_tc_fail("Impossible test scenario!"); 31621.1Skamil#endif 31631.1Skamil 31641.72Skamil#if !defined(HAVE_FPREGS) 31651.72Skamil if (strcmp(regset, "fpregs") == 0) 31661.72Skamil atf_tc_fail("Impossible test scenario!"); 31671.1Skamil#endif 31681.1Skamil 31691.13Schristos DPRINTF("Before forking process PID=%d\n", getpid()); 31701.13Schristos SYSCALL_REQUIRE((child = fork()) != -1); 31711.1Skamil if (child == 0) { 31721.13Schristos DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 31731.1Skamil FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 31741.1Skamil 31751.13Schristos DPRINTF("Before raising %s from child\n", strsignal(sigval)); 31761.1Skamil FORKEE_ASSERT(raise(sigval) == 0); 31771.1Skamil 31781.13Schristos DPRINTF("Before exiting of the child process\n"); 31791.1Skamil _exit(exitval); 31801.1Skamil } 31811.13Schristos DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 31821.1Skamil 31831.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 31841.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 31851.1Skamil 31861.1Skamil validate_status_stopped(status, sigval); 31871.1Skamil 31881.1Skamil#if defined(HAVE_GPREGS) 31891.72Skamil if (strcmp(regset, "regs") == 0) { 31901.72Skamil DPRINTF("Call GETREGS for the child process\n"); 31911.72Skamil SYSCALL_REQUIRE(ptrace(PT_GETREGS, child, &gpr, 0) != -1); 31921.72Skamil 31931.72Skamil if (strcmp(aux, "none") == 0) { 31941.72Skamil DPRINTF("Retrieved registers\n"); 31951.72Skamil } else if (strcmp(aux, "pc") == 0) { 31961.72Skamil rgstr = PTRACE_REG_PC(&gpr); 31971.72Skamil DPRINTF("Retrieved %" PRIxREGISTER "\n", rgstr); 31981.72Skamil } else if (strcmp(aux, "set_pc") == 0) { 31991.72Skamil rgstr = PTRACE_REG_PC(&gpr); 32001.72Skamil PTRACE_REG_SET_PC(&gpr, rgstr); 32011.72Skamil } else if (strcmp(aux, "sp") == 0) { 32021.72Skamil rgstr = PTRACE_REG_SP(&gpr); 32031.72Skamil DPRINTF("Retrieved %" PRIxREGISTER "\n", rgstr); 32041.72Skamil } else if (strcmp(aux, "intrv") == 0) { 32051.72Skamil rgstr = PTRACE_REG_INTRV(&gpr); 32061.72Skamil DPRINTF("Retrieved %" PRIxREGISTER "\n", rgstr); 32071.72Skamil } else if (strcmp(aux, "setregs") == 0) { 32081.72Skamil DPRINTF("Call SETREGS for the child process\n"); 32091.72Skamil SYSCALL_REQUIRE( 32101.72Skamil ptrace(PT_GETREGS, child, &gpr, 0) != -1); 32111.72Skamil } 32121.72Skamil } 32131.1Skamil#endif 32141.1Skamil 32151.72Skamil#if defined(HAVE_FPREGS) 32161.72Skamil if (strcmp(regset, "fpregs") == 0) { 32171.72Skamil DPRINTF("Call GETFPREGS for the child process\n"); 32181.72Skamil SYSCALL_REQUIRE(ptrace(PT_GETFPREGS, child, &fpr, 0) != -1); 32191.72Skamil 32201.72Skamil if (strcmp(aux, "getfpregs") == 0) { 32211.72Skamil DPRINTF("Retrieved FP registers\n"); 32221.72Skamil } else if (strcmp(aux, "setfpregs") == 0) { 32231.72Skamil DPRINTF("Call SETFPREGS for the child\n"); 32241.72Skamil SYSCALL_REQUIRE( 32251.72Skamil ptrace(PT_SETFPREGS, child, &fpr, 0) != -1); 32261.72Skamil } 32271.1Skamil } 32281.1Skamil#endif 32291.1Skamil 32301.13Schristos DPRINTF("Before resuming the child process where it left off and " 32311.1Skamil "without signal to be sent\n"); 32321.13Schristos SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 32331.1Skamil 32341.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 32351.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 32361.1Skamil 32371.1Skamil validate_status_exited(status, exitval); 32381.1Skamil 32391.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 32401.1Skamil TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 32411.1Skamil} 32421.1Skamil 32431.72Skamil#define ACCESS_REGS(test, regset, aux) \ 32441.72SkamilATF_TC(test); \ 32451.72SkamilATF_TC_HEAD(test, tc) \ 32461.72Skamil{ \ 32471.72Skamil atf_tc_set_md_var(tc, "descr", \ 32481.72Skamil "Verify " regset " with auxiliary operation: " aux); \ 32491.72Skamil} \ 32501.72Skamil \ 32511.72SkamilATF_TC_BODY(test, tc) \ 32521.72Skamil{ \ 32531.72Skamil \ 32541.72Skamil access_regs(regset, aux); \ 32551.1Skamil} 32561.1Skamil#endif 32571.1Skamil 32581.72Skamil#if defined(HAVE_GPREGS) 32591.72SkamilACCESS_REGS(access_regs1, "regs", "none") 32601.72SkamilACCESS_REGS(access_regs2, "regs", "pc") 32611.72SkamilACCESS_REGS(access_regs3, "regs", "set_pc") 32621.72SkamilACCESS_REGS(access_regs4, "regs", "sp") 32631.72SkamilACCESS_REGS(access_regs5, "regs", "intrv") 32641.72SkamilACCESS_REGS(access_regs6, "regs", "setregs") 32651.1Skamil#endif 32661.1Skamil#if defined(HAVE_FPREGS) 32671.72SkamilACCESS_REGS(access_fpregs1, "fpregs", "getfpregs") 32681.72SkamilACCESS_REGS(access_fpregs2, "fpregs", "setfpregs") 32691.1Skamil#endif 32701.1Skamil 32711.72Skamil/// ---------------------------------------------------------------------------- 32721.1Skamil 32731.1Skamil#if defined(PT_STEP) 32741.1Skamilstatic void 32751.2Skamilptrace_step(int N, int setstep) 32761.1Skamil{ 32771.1Skamil const int exitval = 5; 32781.1Skamil const int sigval = SIGSTOP; 32791.1Skamil pid_t child, wpid; 32801.1Skamil#if defined(TWAIT_HAVE_STATUS) 32811.1Skamil int status; 32821.1Skamil#endif 32831.1Skamil int happy; 32841.81Skamil struct ptrace_siginfo info; 32851.1Skamil 32861.1Skamil#if defined(__arm__) 32871.1Skamil /* PT_STEP not supported on arm 32-bit */ 32881.1Skamil atf_tc_expect_fail("PR kern/52119"); 32891.1Skamil#endif 32901.1Skamil 32911.13Schristos DPRINTF("Before forking process PID=%d\n", getpid()); 32921.13Schristos SYSCALL_REQUIRE((child = fork()) != -1); 32931.1Skamil if (child == 0) { 32941.13Schristos DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 32951.1Skamil FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 32961.1Skamil 32971.1Skamil happy = check_happy(999); 32981.1Skamil 32991.13Schristos DPRINTF("Before raising %s from child\n", strsignal(sigval)); 33001.1Skamil FORKEE_ASSERT(raise(sigval) == 0); 33011.1Skamil 33021.1Skamil FORKEE_ASSERT_EQ(happy, check_happy(999)); 33031.1Skamil 33041.13Schristos DPRINTF("Before exiting of the child process\n"); 33051.1Skamil _exit(exitval); 33061.1Skamil } 33071.13Schristos DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 33081.1Skamil 33091.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 33101.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 33111.1Skamil 33121.1Skamil validate_status_stopped(status, sigval); 33131.1Skamil 33141.81Skamil DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 33151.81Skamil SYSCALL_REQUIRE( 33161.81Skamil ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 33171.81Skamil 33181.81Skamil DPRINTF("Before checking siginfo_t\n"); 33191.81Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 33201.81Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 33211.81Skamil 33221.1Skamil while (N --> 0) { 33231.2Skamil if (setstep) { 33241.13Schristos DPRINTF("Before resuming the child process where it " 33251.2Skamil "left off and without signal to be sent (use " 33261.9Skamil "PT_SETSTEP and PT_CONTINUE)\n"); 33271.13Schristos SYSCALL_REQUIRE(ptrace(PT_SETSTEP, child, 0, 0) != -1); 33281.13Schristos SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) 33291.2Skamil != -1); 33301.2Skamil } else { 33311.13Schristos DPRINTF("Before resuming the child process where it " 33321.2Skamil "left off and without signal to be sent (use " 33331.2Skamil "PT_STEP)\n"); 33341.13Schristos SYSCALL_REQUIRE(ptrace(PT_STEP, child, (void *)1, 0) 33351.2Skamil != -1); 33361.2Skamil } 33371.1Skamil 33381.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 33391.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), 33401.1Skamil child); 33411.1Skamil 33421.1Skamil validate_status_stopped(status, SIGTRAP); 33431.2Skamil 33441.81Skamil DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 33451.81Skamil SYSCALL_REQUIRE( 33461.81Skamil ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 33471.81Skamil 33481.81Skamil DPRINTF("Before checking siginfo_t\n"); 33491.81Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); 33501.81Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_TRACE); 33511.81Skamil 33521.2Skamil if (setstep) { 33531.13Schristos SYSCALL_REQUIRE(ptrace(PT_CLEARSTEP, child, 0, 0) != -1); 33541.2Skamil } 33551.1Skamil } 33561.1Skamil 33571.13Schristos DPRINTF("Before resuming the child process where it left off and " 33581.1Skamil "without signal to be sent\n"); 33591.13Schristos SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 33601.1Skamil 33611.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 33621.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 33631.1Skamil 33641.1Skamil validate_status_exited(status, exitval); 33651.1Skamil 33661.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 33671.1Skamil TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 33681.1Skamil} 33691.1Skamil 33701.73Skamil#define PTRACE_STEP(test, N, setstep) \ 33711.73SkamilATF_TC(test); \ 33721.73SkamilATF_TC_HEAD(test, tc) \ 33731.73Skamil{ \ 33741.73Skamil atf_tc_set_md_var(tc, "descr", \ 33751.74Skamil "Verify " #N " (PT_SETSTEP set to: " #setstep ")"); \ 33761.73Skamil} \ 33771.73Skamil \ 33781.73SkamilATF_TC_BODY(test, tc) \ 33791.73Skamil{ \ 33801.73Skamil \ 33811.73Skamil ptrace_step(N, setstep); \ 33821.1Skamil} 33831.1Skamil 33841.73SkamilPTRACE_STEP(step1, 1, 0) 33851.73SkamilPTRACE_STEP(step2, 2, 0) 33861.73SkamilPTRACE_STEP(step3, 3, 0) 33871.73SkamilPTRACE_STEP(step4, 4, 0) 33881.73SkamilPTRACE_STEP(setstep1, 1, 1) 33891.73SkamilPTRACE_STEP(setstep2, 2, 1) 33901.73SkamilPTRACE_STEP(setstep3, 3, 1) 33911.73SkamilPTRACE_STEP(setstep4, 4, 1) 33921.1Skamil#endif 33931.1Skamil 33941.73Skamil/// ---------------------------------------------------------------------------- 33951.1Skamil 33961.75Skamilstatic void 33971.75Skamilptrace_kill(const char *type) 33981.1Skamil{ 33991.75Skamil const int sigval = SIGSTOP; 34001.1Skamil pid_t child, wpid; 34011.1Skamil#if defined(TWAIT_HAVE_STATUS) 34021.1Skamil int status; 34031.1Skamil#endif 34041.1Skamil 34051.13Schristos DPRINTF("Before forking process PID=%d\n", getpid()); 34061.13Schristos SYSCALL_REQUIRE((child = fork()) != -1); 34071.1Skamil if (child == 0) { 34081.13Schristos DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 34091.1Skamil FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 34101.1Skamil 34111.13Schristos DPRINTF("Before raising %s from child\n", strsignal(sigval)); 34121.1Skamil FORKEE_ASSERT(raise(sigval) == 0); 34131.1Skamil 34141.1Skamil /* NOTREACHED */ 34151.1Skamil FORKEE_ASSERTX(0 && 34161.1Skamil "Child should be terminated by a signal from its parent"); 34171.1Skamil } 34181.13Schristos DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 34191.1Skamil 34201.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 34211.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 34221.1Skamil 34231.1Skamil validate_status_stopped(status, sigval); 34241.1Skamil 34251.75Skamil DPRINTF("Before killing the child process with %s\n", type); 34261.75Skamil if (strcmp(type, "ptrace(PT_KILL)") == 0) { 34271.75Skamil SYSCALL_REQUIRE(ptrace(PT_KILL, child, (void*)1, 0) != -1); 34281.75Skamil } else if (strcmp(type, "kill(SIGKILL)") == 0) { 34291.75Skamil kill(child, SIGKILL); 34301.75Skamil } else if (strcmp(type, "killpg(SIGKILL)") == 0) { 34311.75Skamil setpgid(child, 0); 34321.75Skamil killpg(getpgid(child), SIGKILL); 34331.75Skamil } 34341.1Skamil 34351.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 34361.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 34371.1Skamil 34381.75Skamil validate_status_signaled(status, SIGKILL, 0); 34391.1Skamil 34401.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 34411.1Skamil TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 34421.1Skamil} 34431.1Skamil 34441.75Skamil#define PTRACE_KILL(test, type) \ 34451.75SkamilATF_TC(test); \ 34461.75SkamilATF_TC_HEAD(test, tc) \ 34471.75Skamil{ \ 34481.75Skamil atf_tc_set_md_var(tc, "descr", \ 34491.75Skamil "Verify killing the child with " type); \ 34501.75Skamil} \ 34511.75Skamil \ 34521.75SkamilATF_TC_BODY(test, tc) \ 34531.75Skamil{ \ 34541.75Skamil \ 34551.75Skamil ptrace_kill(type); \ 34561.1Skamil} 34571.1Skamil 34581.75Skamil// PT_CONTINUE with SIGKILL is covered by traceme_sendsignal_simple1 34591.75SkamilPTRACE_KILL(kill1, "ptrace(PT_KILL)") 34601.75SkamilPTRACE_KILL(kill2, "kill(SIGKILL)") 34611.75SkamilPTRACE_KILL(kill3, "killpg(SIGKILL)") 34621.1Skamil 34631.75Skamil/// ---------------------------------------------------------------------------- 34641.1Skamil 34651.77Skamilstatic void 34661.77Skamiltraceme_lwpinfo(const int threads) 34671.1Skamil{ 34681.1Skamil const int sigval = SIGSTOP; 34691.77Skamil const int sigval2 = SIGINT; 34701.1Skamil pid_t child, wpid; 34711.1Skamil#if defined(TWAIT_HAVE_STATUS) 34721.1Skamil int status; 34731.1Skamil#endif 34741.77Skamil struct ptrace_lwpinfo lwp = {0, 0}; 34751.77Skamil struct ptrace_siginfo info; 34761.77Skamil 34771.77Skamil /* Maximum number of supported threads in this test */ 34781.77Skamil pthread_t t[3]; 34791.77Skamil int n, rv; 34801.77Skamil 34811.77Skamil ATF_REQUIRE((int)__arraycount(t) >= threads); 34821.1Skamil 34831.13Schristos DPRINTF("Before forking process PID=%d\n", getpid()); 34841.13Schristos SYSCALL_REQUIRE((child = fork()) != -1); 34851.1Skamil if (child == 0) { 34861.13Schristos DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 34871.1Skamil FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 34881.1Skamil 34891.13Schristos DPRINTF("Before raising %s from child\n", strsignal(sigval)); 34901.1Skamil FORKEE_ASSERT(raise(sigval) == 0); 34911.1Skamil 34921.77Skamil for (n = 0; n < threads; n++) { 34931.77Skamil rv = pthread_create(&t[n], NULL, infinite_thread, NULL); 34941.77Skamil FORKEE_ASSERT(rv == 0); 34951.77Skamil } 34961.77Skamil 34971.77Skamil DPRINTF("Before raising %s from child\n", strsignal(sigval2)); 34981.77Skamil FORKEE_ASSERT(raise(sigval2) == 0); 34991.77Skamil 35001.77Skamil /* NOTREACHED */ 35011.77Skamil FORKEE_ASSERTX(0 && "Not reached"); 35021.1Skamil } 35031.13Schristos DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 35041.1Skamil 35051.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 35061.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 35071.1Skamil 35081.1Skamil validate_status_stopped(status, sigval); 35091.1Skamil 35101.77Skamil DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child"); 35111.77Skamil SYSCALL_REQUIRE( 35121.77Skamil ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 35131.77Skamil 35141.77Skamil DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 35151.77Skamil DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 35161.77Skamil info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 35171.77Skamil info.psi_siginfo.si_errno); 35181.77Skamil 35191.77Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 35201.77Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 35211.77Skamil 35221.13Schristos DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n"); 35231.77Skamil SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &lwp, sizeof(lwp)) != -1); 35241.1Skamil 35251.77Skamil DPRINTF("Assert that there exists a single thread only\n"); 35261.77Skamil ATF_REQUIRE(lwp.pl_lwpid > 0); 35271.1Skamil 35281.13Schristos DPRINTF("Assert that lwp thread %d received event PL_EVENT_SIGNAL\n", 35291.77Skamil lwp.pl_lwpid); 35301.77Skamil FORKEE_ASSERT_EQ(lwp.pl_event, PL_EVENT_SIGNAL); 35311.1Skamil 35321.13Schristos DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n"); 35331.77Skamil SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &lwp, sizeof(lwp)) != -1); 35341.1Skamil 35351.77Skamil DPRINTF("Assert that there exists a single thread only\n"); 35361.77Skamil ATF_REQUIRE_EQ(lwp.pl_lwpid, 0); 35371.1Skamil 35381.13Schristos DPRINTF("Before resuming the child process where it left off and " 35391.1Skamil "without signal to be sent\n"); 35401.13Schristos SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 35411.1Skamil 35421.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 35431.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 35441.1Skamil 35451.77Skamil validate_status_stopped(status, sigval2); 35461.77Skamil 35471.77Skamil DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child"); 35481.77Skamil SYSCALL_REQUIRE( 35491.77Skamil ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 35501.77Skamil 35511.77Skamil DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 35521.77Skamil DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 35531.77Skamil info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 35541.77Skamil info.psi_siginfo.si_errno); 35551.77Skamil 35561.77Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval2); 35571.77Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 35581.77Skamil 35591.77Skamil memset(&lwp, 0, sizeof(lwp)); 35601.77Skamil 35611.77Skamil for (n = 0; n <= threads; n++) { 35621.77Skamil DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n"); 35631.77Skamil SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &lwp, sizeof(lwp)) != -1); 35641.77Skamil DPRINTF("LWP=%d\n", lwp.pl_lwpid); 35651.77Skamil 35661.77Skamil DPRINTF("Assert that the thread exists\n"); 35671.77Skamil ATF_REQUIRE(lwp.pl_lwpid > 0); 35681.77Skamil 35691.77Skamil DPRINTF("Assert that lwp thread %d received expected event\n", 35701.77Skamil lwp.pl_lwpid); 35711.77Skamil FORKEE_ASSERT_EQ(lwp.pl_event, info.psi_lwpid == lwp.pl_lwpid ? 35721.77Skamil PL_EVENT_SIGNAL : PL_EVENT_NONE); 35731.77Skamil } 35741.77Skamil DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n"); 35751.77Skamil SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &lwp, sizeof(lwp)) != -1); 35761.77Skamil DPRINTF("LWP=%d\n", lwp.pl_lwpid); 35771.77Skamil 35781.77Skamil DPRINTF("Assert that there are no more threads\n"); 35791.77Skamil ATF_REQUIRE_EQ(lwp.pl_lwpid, 0); 35801.77Skamil 35811.77Skamil DPRINTF("Before resuming the child process where it left off and " 35821.77Skamil "without signal to be sent\n"); 35831.77Skamil SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, SIGKILL) != -1); 35841.77Skamil 35851.77Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 35861.77Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 35871.77Skamil 35881.77Skamil validate_status_signaled(status, SIGKILL, 0); 35891.1Skamil 35901.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 35911.1Skamil TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 35921.1Skamil} 35931.1Skamil 35941.77Skamil#define TRACEME_LWPINFO(test, threads) \ 35951.77SkamilATF_TC(test); \ 35961.77SkamilATF_TC_HEAD(test, tc) \ 35971.77Skamil{ \ 35981.77Skamil atf_tc_set_md_var(tc, "descr", \ 35991.77Skamil "Verify LWPINFO with the child with " #threads \ 36001.77Skamil " spawned extra threads"); \ 36011.77Skamil} \ 36021.77Skamil \ 36031.77SkamilATF_TC_BODY(test, tc) \ 36041.77Skamil{ \ 36051.77Skamil \ 36061.77Skamil traceme_lwpinfo(threads); \ 36071.1Skamil} 36081.1Skamil 36091.77SkamilTRACEME_LWPINFO(traceme_lwpinfo0, 0) 36101.77SkamilTRACEME_LWPINFO(traceme_lwpinfo1, 1) 36111.77SkamilTRACEME_LWPINFO(traceme_lwpinfo2, 2) 36121.77SkamilTRACEME_LWPINFO(traceme_lwpinfo3, 3) 36131.77Skamil 36141.77Skamil/// ---------------------------------------------------------------------------- 36151.77Skamil 36161.77Skamil#if defined(TWAIT_HAVE_PID) 36171.77Skamilstatic void 36181.77Skamilattach_lwpinfo(const int threads) 36191.1Skamil{ 36201.77Skamil const int sigval = SIGINT; 36211.1Skamil struct msg_fds parent_tracee, parent_tracer; 36221.1Skamil const int exitval_tracer = 10; 36231.1Skamil pid_t tracee, tracer, wpid; 36241.1Skamil uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */ 36251.1Skamil#if defined(TWAIT_HAVE_STATUS) 36261.1Skamil int status; 36271.1Skamil#endif 36281.77Skamil struct ptrace_lwpinfo lwp = {0, 0}; 36291.77Skamil struct ptrace_siginfo info; 36301.77Skamil 36311.77Skamil /* Maximum number of supported threads in this test */ 36321.77Skamil pthread_t t[3]; 36331.77Skamil int n, rv; 36341.1Skamil 36351.13Schristos DPRINTF("Spawn tracee\n"); 36361.13Schristos SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0); 36371.13Schristos SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0); 36381.1Skamil tracee = atf_utils_fork(); 36391.1Skamil if (tracee == 0) { 36401.1Skamil /* Wait for message from the parent */ 36411.1Skamil CHILD_TO_PARENT("tracee ready", parent_tracee, msg); 36421.1Skamil 36431.77Skamil CHILD_FROM_PARENT("spawn threads", parent_tracee, msg); 36441.77Skamil 36451.77Skamil for (n = 0; n < threads; n++) { 36461.77Skamil rv = pthread_create(&t[n], NULL, infinite_thread, NULL); 36471.77Skamil FORKEE_ASSERT(rv == 0); 36481.77Skamil } 36491.77Skamil 36501.77Skamil CHILD_TO_PARENT("tracee exit", parent_tracee, msg); 36511.77Skamil 36521.77Skamil DPRINTF("Before raising %s from child\n", strsignal(sigval)); 36531.77Skamil FORKEE_ASSERT(raise(sigval) == 0); 36541.77Skamil 36551.77Skamil /* NOTREACHED */ 36561.77Skamil FORKEE_ASSERTX(0 && "Not reached"); 36571.1Skamil } 36581.1Skamil PARENT_FROM_CHILD("tracee ready", parent_tracee, msg); 36591.1Skamil 36601.13Schristos DPRINTF("Spawn debugger\n"); 36611.1Skamil tracer = atf_utils_fork(); 36621.1Skamil if (tracer == 0) { 36631.1Skamil /* No IPC to communicate with the child */ 36641.13Schristos DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid()); 36651.1Skamil FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1); 36661.1Skamil 36671.1Skamil /* Wait for tracee and assert that it was stopped w/ SIGSTOP */ 36681.1Skamil FORKEE_REQUIRE_SUCCESS( 36691.1Skamil wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 36701.1Skamil 36711.1Skamil forkee_status_stopped(status, SIGSTOP); 36721.1Skamil 36731.77Skamil DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for " 36741.77Skamil "tracee"); 36751.77Skamil FORKEE_ASSERT( 36761.77Skamil ptrace(PT_GET_SIGINFO, tracee, &info, sizeof(info)) != -1); 36771.77Skamil 36781.77Skamil DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 36791.77Skamil DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 36801.77Skamil "si_errno=%#x\n", 36811.77Skamil info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 36821.77Skamil info.psi_siginfo.si_errno); 36831.77Skamil 36841.77Skamil FORKEE_ASSERT_EQ(info.psi_siginfo.si_signo, SIGSTOP); 36851.77Skamil FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, SI_USER); 36861.77Skamil 36871.13Schristos DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n"); 36881.77Skamil FORKEE_ASSERT(ptrace(PT_LWPINFO, tracee, &lwp, sizeof(lwp)) 36891.1Skamil != -1); 36901.1Skamil 36911.13Schristos DPRINTF("Assert that there exists a thread\n"); 36921.77Skamil FORKEE_ASSERTX(lwp.pl_lwpid > 0); 36931.1Skamil 36941.13Schristos DPRINTF("Assert that lwp thread %d received event " 36951.77Skamil "PL_EVENT_SIGNAL\n", lwp.pl_lwpid); 36961.77Skamil FORKEE_ASSERT_EQ(lwp.pl_event, PL_EVENT_SIGNAL); 36971.1Skamil 36981.77Skamil DPRINTF("Before calling ptrace(2) with PT_LWPINFO for " 36991.77Skamil "tracee\n"); 37001.77Skamil FORKEE_ASSERT(ptrace(PT_LWPINFO, tracee, &lwp, sizeof(lwp)) 37011.1Skamil != -1); 37021.1Skamil 37031.77Skamil DPRINTF("Assert that there are no more lwp threads in " 37041.77Skamil "tracee\n"); 37051.77Skamil FORKEE_ASSERT_EQ(lwp.pl_lwpid, 0); 37061.1Skamil 37071.1Skamil /* Resume tracee with PT_CONTINUE */ 37081.1Skamil FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1); 37091.1Skamil 37101.1Skamil /* Inform parent that tracer has attached to tracee */ 37111.1Skamil CHILD_TO_PARENT("tracer ready", parent_tracer, msg); 37121.77Skamil 37131.1Skamil /* Wait for parent */ 37141.1Skamil CHILD_FROM_PARENT("tracer wait", parent_tracer, msg); 37151.1Skamil 37161.77Skamil /* Wait for tracee and assert that it raised a signal */ 37171.77Skamil FORKEE_REQUIRE_SUCCESS( 37181.77Skamil wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 37191.77Skamil 37201.77Skamil forkee_status_stopped(status, SIGINT); 37211.77Skamil 37221.77Skamil DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for " 37231.77Skamil "child"); 37241.77Skamil FORKEE_ASSERT( 37251.77Skamil ptrace(PT_GET_SIGINFO, tracee, &info, sizeof(info)) != -1); 37261.77Skamil 37271.77Skamil DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 37281.77Skamil DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 37291.77Skamil "si_errno=%#x\n", 37301.77Skamil info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 37311.77Skamil info.psi_siginfo.si_errno); 37321.77Skamil 37331.77Skamil FORKEE_ASSERT_EQ(info.psi_siginfo.si_signo, sigval); 37341.77Skamil FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, SI_LWP); 37351.77Skamil 37361.77Skamil memset(&lwp, 0, sizeof(lwp)); 37371.77Skamil 37381.77Skamil for (n = 0; n <= threads; n++) { 37391.77Skamil DPRINTF("Before calling ptrace(2) with PT_LWPINFO for " 37401.77Skamil "child\n"); 37411.77Skamil FORKEE_ASSERT(ptrace(PT_LWPINFO, tracee, &lwp, 37421.77Skamil sizeof(lwp)) != -1); 37431.77Skamil DPRINTF("LWP=%d\n", lwp.pl_lwpid); 37441.77Skamil 37451.77Skamil DPRINTF("Assert that the thread exists\n"); 37461.77Skamil FORKEE_ASSERT(lwp.pl_lwpid > 0); 37471.77Skamil 37481.77Skamil DPRINTF("Assert that lwp thread %d received expected " 37491.77Skamil "event\n", lwp.pl_lwpid); 37501.77Skamil FORKEE_ASSERT_EQ(lwp.pl_event, 37511.77Skamil info.psi_lwpid == lwp.pl_lwpid ? 37521.77Skamil PL_EVENT_SIGNAL : PL_EVENT_NONE); 37531.77Skamil } 37541.77Skamil DPRINTF("Before calling ptrace(2) with PT_LWPINFO for " 37551.77Skamil "tracee\n"); 37561.77Skamil FORKEE_ASSERT(ptrace(PT_LWPINFO, tracee, &lwp, sizeof(lwp)) 37571.77Skamil != -1); 37581.77Skamil DPRINTF("LWP=%d\n", lwp.pl_lwpid); 37591.77Skamil 37601.77Skamil DPRINTF("Assert that there are no more threads\n"); 37611.77Skamil FORKEE_ASSERT_EQ(lwp.pl_lwpid, 0); 37621.77Skamil 37631.77Skamil DPRINTF("Before resuming the child process where it left off " 37641.77Skamil "and without signal to be sent\n"); 37651.77Skamil FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, SIGKILL) 37661.77Skamil != -1); 37671.77Skamil 37681.1Skamil /* Wait for tracee and assert that it exited */ 37691.1Skamil FORKEE_REQUIRE_SUCCESS( 37701.1Skamil wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 37711.1Skamil 37721.77Skamil forkee_status_signaled(status, SIGKILL, 0); 37731.1Skamil 37741.13Schristos DPRINTF("Before exiting of the tracer process\n"); 37751.1Skamil _exit(exitval_tracer); 37761.1Skamil } 37771.1Skamil 37781.13Schristos DPRINTF("Wait for the tracer to attach to the tracee\n"); 37791.1Skamil PARENT_FROM_CHILD("tracer ready", parent_tracer, msg); 37801.1Skamil 37811.77Skamil DPRINTF("Resume the tracee and spawn threads\n"); 37821.77Skamil PARENT_TO_CHILD("spawn threads", parent_tracee, msg); 37831.77Skamil 37841.13Schristos DPRINTF("Resume the tracee and let it exit\n"); 37851.77Skamil PARENT_FROM_CHILD("tracee exit", parent_tracee, msg); 37861.1Skamil 37871.77Skamil DPRINTF("Resume the tracer and let it detect multiple threads\n"); 37881.1Skamil PARENT_TO_CHILD("tracer wait", parent_tracer, msg); 37891.1Skamil 37901.13Schristos DPRINTF("Wait for tracer to finish its job and exit - calling %s()\n", 37911.1Skamil TWAIT_FNAME); 37921.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0), 37931.1Skamil tracer); 37941.1Skamil 37951.1Skamil validate_status_exited(status, exitval_tracer); 37961.1Skamil 37971.13Schristos DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n", 37981.1Skamil TWAIT_FNAME); 37991.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 38001.1Skamil tracee); 38011.1Skamil 38021.77Skamil validate_status_signaled(status, SIGKILL, 0); 38031.1Skamil 38041.1Skamil msg_close(&parent_tracer); 38051.1Skamil msg_close(&parent_tracee); 38061.1Skamil} 38071.77Skamil 38081.77Skamil#define ATTACH_LWPINFO(test, threads) \ 38091.77SkamilATF_TC(test); \ 38101.77SkamilATF_TC_HEAD(test, tc) \ 38111.77Skamil{ \ 38121.77Skamil atf_tc_set_md_var(tc, "descr", \ 38131.77Skamil "Verify LWPINFO with the child with " #threads \ 38141.77Skamil " spawned extra threads (tracer is not the original " \ 38151.77Skamil "parent)"); \ 38161.77Skamil} \ 38171.77Skamil \ 38181.77SkamilATF_TC_BODY(test, tc) \ 38191.77Skamil{ \ 38201.77Skamil \ 38211.77Skamil attach_lwpinfo(threads); \ 38221.77Skamil} 38231.77Skamil 38241.77SkamilATTACH_LWPINFO(attach_lwpinfo0, 0) 38251.77SkamilATTACH_LWPINFO(attach_lwpinfo1, 1) 38261.77SkamilATTACH_LWPINFO(attach_lwpinfo2, 2) 38271.77SkamilATTACH_LWPINFO(attach_lwpinfo3, 3) 38281.1Skamil#endif 38291.1Skamil 38301.77Skamil/// ---------------------------------------------------------------------------- 38311.77Skamil 38321.1Skamilstatic void 38331.79Skamilptrace_siginfo(bool faked, void (*sah)(int a, siginfo_t *b, void *c), int *signal_caught) 38341.1Skamil{ 38351.1Skamil const int exitval = 5; 38361.1Skamil const int sigval = SIGINT; 38371.1Skamil const int sigfaked = SIGTRAP; 38381.1Skamil const int sicodefaked = TRAP_BRKPT; 38391.1Skamil pid_t child, wpid; 38401.1Skamil struct sigaction sa; 38411.1Skamil#if defined(TWAIT_HAVE_STATUS) 38421.1Skamil int status; 38431.1Skamil#endif 38441.1Skamil struct ptrace_siginfo info; 38451.1Skamil memset(&info, 0, sizeof(info)); 38461.1Skamil 38471.13Schristos DPRINTF("Before forking process PID=%d\n", getpid()); 38481.13Schristos SYSCALL_REQUIRE((child = fork()) != -1); 38491.1Skamil if (child == 0) { 38501.13Schristos DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 38511.1Skamil FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 38521.1Skamil 38531.79Skamil sa.sa_sigaction = sah; 38541.1Skamil sa.sa_flags = SA_SIGINFO; 38551.1Skamil sigemptyset(&sa.sa_mask); 38561.1Skamil 38571.79Skamil FORKEE_ASSERT(sigaction(faked ? sigfaked : sigval, &sa, NULL) 38581.79Skamil != -1); 38591.1Skamil 38601.13Schristos DPRINTF("Before raising %s from child\n", strsignal(sigval)); 38611.1Skamil FORKEE_ASSERT(raise(sigval) == 0); 38621.1Skamil 38631.79Skamil FORKEE_ASSERT_EQ(*signal_caught, 1); 38641.1Skamil 38651.13Schristos DPRINTF("Before exiting of the child process\n"); 38661.1Skamil _exit(exitval); 38671.1Skamil } 38681.13Schristos DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 38691.1Skamil 38701.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 38711.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 38721.1Skamil 38731.1Skamil validate_status_stopped(status, sigval); 38741.1Skamil 38751.13Schristos DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 38761.61Skre SYSCALL_REQUIRE( 38771.61Skre ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 38781.1Skamil 38791.13Schristos DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 38801.13Schristos DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 38811.1Skamil info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 38821.1Skamil info.psi_siginfo.si_errno); 38831.1Skamil 38841.79Skamil if (faked) { 38851.79Skamil DPRINTF("Before setting new faked signal to signo=%d " 38861.79Skamil "si_code=%d\n", sigfaked, sicodefaked); 38871.79Skamil info.psi_siginfo.si_signo = sigfaked; 38881.79Skamil info.psi_siginfo.si_code = sicodefaked; 38891.79Skamil } 38901.1Skamil 38911.13Schristos DPRINTF("Before calling ptrace(2) with PT_SET_SIGINFO for child\n"); 38921.61Skre SYSCALL_REQUIRE( 38931.61Skre ptrace(PT_SET_SIGINFO, child, &info, sizeof(info)) != -1); 38941.1Skamil 38951.79Skamil if (faked) { 38961.79Skamil DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for " 38971.79Skamil "child\n"); 38981.79Skamil SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, 38991.79Skamil sizeof(info)) != -1); 39001.1Skamil 39011.79Skamil DPRINTF("Before checking siginfo_t\n"); 39021.79Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigfaked); 39031.79Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_code, sicodefaked); 39041.79Skamil } 39051.1Skamil 39061.13Schristos DPRINTF("Before resuming the child process where it left off and " 39071.1Skamil "without signal to be sent\n"); 39081.79Skamil SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 39091.79Skamil faked ? sigfaked : sigval) != -1); 39101.1Skamil 39111.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 39121.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 39131.1Skamil 39141.1Skamil validate_status_exited(status, exitval); 39151.1Skamil 39161.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 39171.1Skamil TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 39181.1Skamil} 39191.1Skamil 39201.79Skamil#define PTRACE_SIGINFO(test, faked) \ 39211.79SkamilATF_TC(test); \ 39221.79SkamilATF_TC_HEAD(test, tc) \ 39231.79Skamil{ \ 39241.79Skamil atf_tc_set_md_var(tc, "descr", \ 39251.79Skamil "Verify basic PT_GET_SIGINFO and PT_SET_SIGINFO calls" \ 39261.79Skamil "with%s setting signal to new value", faked ? "" : "out"); \ 39271.79Skamil} \ 39281.79Skamil \ 39291.79Skamilstatic int test##_caught = 0; \ 39301.79Skamil \ 39311.79Skamilstatic void \ 39321.79Skamiltest##_sighandler(int sig, siginfo_t *info, void *ctx) \ 39331.79Skamil{ \ 39341.79Skamil if (faked) { \ 39351.79Skamil FORKEE_ASSERT_EQ(sig, SIGTRAP); \ 39361.79Skamil FORKEE_ASSERT_EQ(info->si_signo, SIGTRAP); \ 39371.79Skamil FORKEE_ASSERT_EQ(info->si_code, TRAP_BRKPT); \ 39381.79Skamil } else { \ 39391.79Skamil FORKEE_ASSERT_EQ(sig, SIGINT); \ 39401.79Skamil FORKEE_ASSERT_EQ(info->si_signo, SIGINT); \ 39411.79Skamil FORKEE_ASSERT_EQ(info->si_code, SI_LWP); \ 39421.79Skamil } \ 39431.79Skamil \ 39441.79Skamil ++ test##_caught; \ 39451.79Skamil} \ 39461.79Skamil \ 39471.79SkamilATF_TC_BODY(test, tc) \ 39481.79Skamil{ \ 39491.79Skamil \ 39501.79Skamil ptrace_siginfo(faked, test##_sighandler, & test##_caught); \ 39511.79Skamil} 39521.79Skamil 39531.79SkamilPTRACE_SIGINFO(siginfo_set_unmodified, false) 39541.79SkamilPTRACE_SIGINFO(siginfo_set_faked, true) 39551.79Skamil 39561.79Skamil/// ---------------------------------------------------------------------------- 39571.79Skamil 39581.82SkamilATF_TC(traceme_exec); 39591.82SkamilATF_TC_HEAD(traceme_exec, tc) 39601.1Skamil{ 39611.1Skamil atf_tc_set_md_var(tc, "descr", 39621.1Skamil "Detect SIGTRAP TRAP_EXEC from tracee"); 39631.1Skamil} 39641.1Skamil 39651.82SkamilATF_TC_BODY(traceme_exec, tc) 39661.1Skamil{ 39671.1Skamil const int sigval = SIGTRAP; 39681.1Skamil pid_t child, wpid; 39691.1Skamil#if defined(TWAIT_HAVE_STATUS) 39701.1Skamil int status; 39711.1Skamil#endif 39721.1Skamil 39731.1Skamil struct ptrace_siginfo info; 39741.1Skamil memset(&info, 0, sizeof(info)); 39751.1Skamil 39761.13Schristos DPRINTF("Before forking process PID=%d\n", getpid()); 39771.13Schristos SYSCALL_REQUIRE((child = fork()) != -1); 39781.1Skamil if (child == 0) { 39791.13Schristos DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 39801.1Skamil FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 39811.1Skamil 39821.13Schristos DPRINTF("Before calling execve(2) from child\n"); 39831.1Skamil execlp("/bin/echo", "/bin/echo", NULL); 39841.1Skamil 39851.1Skamil FORKEE_ASSERT(0 && "Not reached"); 39861.1Skamil } 39871.13Schristos DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 39881.1Skamil 39891.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 39901.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 39911.1Skamil 39921.1Skamil validate_status_stopped(status, sigval); 39931.1Skamil 39941.13Schristos DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 39951.61Skre SYSCALL_REQUIRE( 39961.61Skre ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 39971.1Skamil 39981.13Schristos DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 39991.13Schristos DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 40001.1Skamil info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 40011.1Skamil info.psi_siginfo.si_errno); 40021.1Skamil 40031.1Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 40041.1Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_EXEC); 40051.1Skamil 40061.13Schristos DPRINTF("Before resuming the child process where it left off and " 40071.1Skamil "without signal to be sent\n"); 40081.13Schristos SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 40091.1Skamil 40101.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 40111.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 40121.1Skamil 40131.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 40141.1Skamil TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 40151.1Skamil} 40161.1Skamil 40171.82Skamil/// ---------------------------------------------------------------------------- 40181.82Skamil 40191.83Skamilstatic volatile int done; 40201.1Skamil 40211.83Skamilstatic void * 40221.83Skamiltrace_threads_cb(void *arg __unused) 40231.1Skamil{ 40241.1Skamil 40251.83Skamil done++; 40261.83Skamil 40271.83Skamil while (done < 3) 40281.83Skamil continue; 40291.83Skamil 40301.83Skamil return NULL; 40311.1Skamil} 40321.1Skamil 40331.83Skamilstatic void 40341.83Skamiltrace_threads(bool trace_create, bool trace_exit) 40351.1Skamil{ 40361.1Skamil const int sigval = SIGSTOP; 40371.1Skamil pid_t child, wpid; 40381.1Skamil#if defined(TWAIT_HAVE_STATUS) 40391.1Skamil int status; 40401.1Skamil#endif 40411.1Skamil ptrace_state_t state; 40421.1Skamil const int slen = sizeof(state); 40431.1Skamil ptrace_event_t event; 40441.1Skamil const int elen = sizeof(event); 40451.83Skamil struct ptrace_siginfo info; 40461.83Skamil 40471.83Skamil pthread_t t[3]; 40481.83Skamil int rv; 40491.83Skamil size_t n; 40501.1Skamil lwpid_t lid; 40511.83Skamil 40521.83Skamil /* Track created and exited threads */ 40531.83Skamil bool traced_lwps[__arraycount(t)]; 40541.83Skamil 40551.83Skamil atf_tc_skip("PR kern/51995"); 40561.1Skamil 40571.13Schristos DPRINTF("Before forking process PID=%d\n", getpid()); 40581.13Schristos SYSCALL_REQUIRE((child = fork()) != -1); 40591.1Skamil if (child == 0) { 40601.13Schristos DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 40611.1Skamil FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 40621.1Skamil 40631.13Schristos DPRINTF("Before raising %s from child\n", strsignal(sigval)); 40641.1Skamil FORKEE_ASSERT(raise(sigval) == 0); 40651.1Skamil 40661.83Skamil for (n = 0; n < __arraycount(t); n++) { 40671.83Skamil rv = pthread_create(&t[n], NULL, trace_threads_cb, 40681.83Skamil NULL); 40691.83Skamil FORKEE_ASSERT(rv == 0); 40701.83Skamil } 40711.1Skamil 40721.83Skamil for (n = 0; n < __arraycount(t); n++) { 40731.83Skamil rv = pthread_join(t[n], NULL); 40741.83Skamil FORKEE_ASSERT(rv == 0); 40751.83Skamil } 40761.1Skamil 40771.83Skamil /* 40781.83Skamil * There is race between _exit() and pthread_join() detaching 40791.83Skamil * a thread. For simplicity kill the process after detecting 40801.83Skamil * LWP events. 40811.83Skamil */ 40821.83Skamil while (true) 40831.83Skamil continue; 40841.1Skamil 40851.83Skamil FORKEE_ASSERT(0 && "Not reached"); 40861.1Skamil } 40871.13Schristos DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 40881.1Skamil 40891.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 40901.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 40911.1Skamil 40921.1Skamil validate_status_stopped(status, sigval); 40931.1Skamil 40941.83Skamil DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 40951.83Skamil SYSCALL_REQUIRE( 40961.83Skamil ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 40971.1Skamil 40981.83Skamil DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 40991.83Skamil DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 41001.83Skamil info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 41011.83Skamil info.psi_siginfo.si_errno); 41021.1Skamil 41031.83Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 41041.83Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 41051.1Skamil 41061.83Skamil DPRINTF("Set LWP event mask for the child %d\n", child); 41071.83Skamil memset(&event, 0, sizeof(event)); 41081.83Skamil if (trace_create) 41091.83Skamil event.pe_set_event |= PTRACE_LWP_CREATE; 41101.83Skamil if (trace_exit) 41111.83Skamil event.pe_set_event |= PTRACE_LWP_EXIT; 41121.83Skamil SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); 41131.1Skamil 41141.13Schristos DPRINTF("Before resuming the child process where it left off and " 41151.1Skamil "without signal to be sent\n"); 41161.13Schristos SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 41171.1Skamil 41181.83Skamil memset(traced_lwps, 0, sizeof(traced_lwps)); 41191.1Skamil 41201.83Skamil for (n = 0; n < (trace_create ? __arraycount(t) : 0); n++) { 41211.83Skamil DPRINTF("Before calling %s() for the child - expected stopped " 41221.83Skamil "SIGTRAP\n", TWAIT_FNAME); 41231.83Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), 41241.83Skamil child); 41251.1Skamil 41261.83Skamil validate_status_stopped(status, SIGTRAP); 41271.1Skamil 41281.83Skamil DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for " 41291.83Skamil "child\n"); 41301.83Skamil SYSCALL_REQUIRE( 41311.83Skamil ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 41321.1Skamil 41331.83Skamil DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 41341.83Skamil DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 41351.83Skamil "si_errno=%#x\n", 41361.83Skamil info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 41371.83Skamil info.psi_siginfo.si_errno); 41381.1Skamil 41391.83Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); 41401.83Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_LWP); 41411.1Skamil 41421.83Skamil SYSCALL_REQUIRE( 41431.83Skamil ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 41441.1Skamil 41451.83Skamil ATF_REQUIRE_EQ_MSG(state.pe_report_event, PTRACE_LWP_CREATE, 41461.83Skamil "%d != %d", state.pe_report_event, PTRACE_LWP_CREATE); 41471.1Skamil 41481.83Skamil lid = state.pe_lwp; 41491.83Skamil DPRINTF("Reported PTRACE_LWP_CREATE event with lid %d\n", lid); 41501.1Skamil 41511.83Skamil traced_lwps[lid - 1] = true; 41521.1Skamil 41531.83Skamil DPRINTF("Before resuming the child process where it left off " 41541.83Skamil "and without signal to be sent\n"); 41551.83Skamil SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 41561.83Skamil } 41571.1Skamil 41581.83Skamil for (n = 0; n < (trace_exit ? __arraycount(t) : 0); n++) { 41591.83Skamil DPRINTF("Before calling %s() for the child - expected stopped " 41601.83Skamil "SIGTRAP\n", TWAIT_FNAME); 41611.83Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), 41621.83Skamil child); 41631.1Skamil 41641.83Skamil validate_status_stopped(status, SIGTRAP); 41651.1Skamil 41661.83Skamil DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for " 41671.83Skamil "child\n"); 41681.83Skamil SYSCALL_REQUIRE( 41691.83Skamil ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 41701.1Skamil 41711.83Skamil DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 41721.83Skamil DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 41731.83Skamil "si_errno=%#x\n", 41741.83Skamil info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 41751.83Skamil info.psi_siginfo.si_errno); 41761.1Skamil 41771.83Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); 41781.83Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_LWP); 41791.1Skamil 41801.83Skamil SYSCALL_REQUIRE( 41811.83Skamil ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 41821.1Skamil 41831.83Skamil ATF_REQUIRE_EQ_MSG(state.pe_report_event, PTRACE_LWP_EXIT, 41841.83Skamil "%d != %d", state.pe_report_event, PTRACE_LWP_EXIT); 41851.1Skamil 41861.83Skamil lid = state.pe_lwp; 41871.83Skamil DPRINTF("Reported PTRACE_LWP_EXIT event with lid %d\n", lid); 41881.1Skamil 41891.83Skamil if (trace_create) { 41901.83Skamil ATF_REQUIRE(traced_lwps[lid - 1] == true); 41911.83Skamil traced_lwps[lid - 1] = false; 41921.83Skamil } 41931.1Skamil 41941.83Skamil DPRINTF("Before resuming the child process where it left off " 41951.83Skamil "and without signal to be sent\n"); 41961.83Skamil SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 41971.83Skamil } 41981.1Skamil 41991.83Skamil kill(child, SIGKILL); 42001.1Skamil 42011.13Schristos DPRINTF("Before calling %s() for the child - expected exited\n", 42021.1Skamil TWAIT_FNAME); 42031.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 42041.1Skamil 42051.83Skamil validate_status_signaled(status, SIGKILL, 0); 42061.1Skamil 42071.13Schristos DPRINTF("Before calling %s() for the child - expected no process\n", 42081.1Skamil TWAIT_FNAME); 42091.1Skamil TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 42101.1Skamil} 42111.1Skamil 42121.83Skamil#define TRACE_THREADS(test, trace_create, trace_exit) \ 42131.83SkamilATF_TC(test); \ 42141.83SkamilATF_TC_HEAD(test, tc) \ 42151.83Skamil{ \ 42161.83Skamil atf_tc_set_md_var(tc, "descr", \ 42171.83Skamil "Verify spawning threads with%s tracing LWP create and" \ 42181.83Skamil "with%s tracing LWP exit", trace_create ? "" : "out", \ 42191.83Skamil trace_exit ? "" : "out"); \ 42201.83Skamil} \ 42211.83Skamil \ 42221.83SkamilATF_TC_BODY(test, tc) \ 42231.83Skamil{ \ 42241.83Skamil \ 42251.83Skamil trace_threads(trace_create, trace_exit); \ 42261.83Skamil} 42271.83Skamil 42281.83SkamilTRACE_THREADS(trace_thread1, false, false) 42291.83SkamilTRACE_THREADS(trace_thread2, false, true) 42301.83SkamilTRACE_THREADS(trace_thread3, true, false) 42311.83SkamilTRACE_THREADS(trace_thread4, true, true) 42321.83Skamil 42331.83Skamil/// ---------------------------------------------------------------------------- 42341.83Skamil 42351.84SkamilATF_TC(signal_mask_unrelated); 42361.84SkamilATF_TC_HEAD(signal_mask_unrelated, tc) 42371.1Skamil{ 42381.1Skamil atf_tc_set_md_var(tc, "descr", 42391.1Skamil "Verify that masking single unrelated signal does not stop tracer " 42401.1Skamil "from catching other signals"); 42411.1Skamil} 42421.1Skamil 42431.84SkamilATF_TC_BODY(signal_mask_unrelated, tc) 42441.1Skamil{ 42451.1Skamil const int exitval = 5; 42461.1Skamil const int sigval = SIGSTOP; 42471.1Skamil const int sigmasked = SIGTRAP; 42481.1Skamil const int signotmasked = SIGINT; 42491.1Skamil pid_t child, wpid; 42501.1Skamil#if defined(TWAIT_HAVE_STATUS) 42511.1Skamil int status; 42521.1Skamil#endif 42531.1Skamil sigset_t intmask; 42541.1Skamil 42551.13Schristos DPRINTF("Before forking process PID=%d\n", getpid()); 42561.13Schristos SYSCALL_REQUIRE((child = fork()) != -1); 42571.1Skamil if (child == 0) { 42581.13Schristos DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 42591.1Skamil FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 42601.1Skamil 42611.1Skamil sigemptyset(&intmask); 42621.1Skamil sigaddset(&intmask, sigmasked); 42631.1Skamil sigprocmask(SIG_BLOCK, &intmask, NULL); 42641.1Skamil 42651.13Schristos DPRINTF("Before raising %s from child\n", strsignal(sigval)); 42661.1Skamil FORKEE_ASSERT(raise(sigval) == 0); 42671.1Skamil 42681.13Schristos DPRINTF("Before raising %s from child\n", 42691.1Skamil strsignal(signotmasked)); 42701.1Skamil FORKEE_ASSERT(raise(signotmasked) == 0); 42711.1Skamil 42721.13Schristos DPRINTF("Before exiting of the child process\n"); 42731.1Skamil _exit(exitval); 42741.1Skamil } 42751.13Schristos DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 42761.1Skamil 42771.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 42781.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 42791.1Skamil 42801.1Skamil validate_status_stopped(status, sigval); 42811.1Skamil 42821.13Schristos DPRINTF("Before resuming the child process where it left off and " 42831.1Skamil "without signal to be sent\n"); 42841.13Schristos SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 42851.1Skamil 42861.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 42871.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 42881.1Skamil 42891.1Skamil validate_status_stopped(status, signotmasked); 42901.1Skamil 42911.13Schristos DPRINTF("Before resuming the child process where it left off and " 42921.1Skamil "without signal to be sent\n"); 42931.13Schristos SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 42941.1Skamil 42951.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 42961.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 42971.1Skamil 42981.1Skamil validate_status_exited(status, exitval); 42991.1Skamil 43001.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 43011.1Skamil TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 43021.1Skamil} 43031.1Skamil 43041.84Skamil/// ---------------------------------------------------------------------------- 43051.84Skamil 43061.1SkamilATF_TC(signal3); 43071.1SkamilATF_TC_HEAD(signal3, tc) 43081.1Skamil{ 43091.7Skamil atf_tc_set_md_var(tc, "timeout", "5"); 43101.1Skamil atf_tc_set_md_var(tc, "descr", 43111.1Skamil "Verify that masking SIGTRAP in tracee does not stop tracer from " 43121.1Skamil "catching software breakpoints"); 43131.1Skamil} 43141.1Skamil 43151.1SkamilATF_TC_BODY(signal3, tc) 43161.1Skamil{ 43171.1Skamil const int exitval = 5; 43181.1Skamil const int sigval = SIGSTOP; 43191.1Skamil const int sigmasked = SIGTRAP; 43201.1Skamil pid_t child, wpid; 43211.1Skamil#if defined(TWAIT_HAVE_STATUS) 43221.1Skamil int status; 43231.1Skamil#endif 43241.1Skamil sigset_t intmask; 43251.1Skamil 43261.13Schristos DPRINTF("Before forking process PID=%d\n", getpid()); 43271.13Schristos SYSCALL_REQUIRE((child = fork()) != -1); 43281.1Skamil if (child == 0) { 43291.13Schristos DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 43301.1Skamil FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 43311.1Skamil 43321.1Skamil sigemptyset(&intmask); 43331.1Skamil sigaddset(&intmask, sigmasked); 43341.1Skamil sigprocmask(SIG_BLOCK, &intmask, NULL); 43351.1Skamil 43361.13Schristos DPRINTF("Before raising %s from child\n", strsignal(sigval)); 43371.1Skamil FORKEE_ASSERT(raise(sigval) == 0); 43381.1Skamil 43391.13Schristos DPRINTF("Before raising software breakpoint from child\n"); 43401.52Skamil trigger_trap(); 43411.1Skamil 43421.13Schristos DPRINTF("Before exiting of the child process\n"); 43431.1Skamil _exit(exitval); 43441.1Skamil } 43451.13Schristos DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 43461.1Skamil 43471.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 43481.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 43491.1Skamil 43501.1Skamil validate_status_stopped(status, sigval); 43511.1Skamil 43521.13Schristos DPRINTF("Before resuming the child process where it left off and " 43531.1Skamil "without signal to be sent\n"); 43541.13Schristos SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 43551.1Skamil 43561.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 43571.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 43581.1Skamil 43591.1Skamil validate_status_stopped(status, sigmasked); 43601.1Skamil 43611.13Schristos DPRINTF("Before resuming the child process where it left off and " 43621.1Skamil "without signal to be sent\n"); 43631.49Skamil SYSCALL_REQUIRE(ptrace(PT_KILL, child, NULL, 0) != -1); 43641.1Skamil 43651.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 43661.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 43671.1Skamil 43681.49Skamil validate_status_signaled(status, SIGKILL, 0); 43691.1Skamil 43701.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 43711.1Skamil TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 43721.1Skamil} 43731.1Skamil 43741.1Skamil#if defined(PT_STEP) 43751.1SkamilATF_TC(signal4); 43761.1SkamilATF_TC_HEAD(signal4, tc) 43771.1Skamil{ 43781.1Skamil atf_tc_set_md_var(tc, "descr", 43791.1Skamil "Verify that masking SIGTRAP in tracee does not stop tracer from " 43801.1Skamil "catching single step trap"); 43811.1Skamil} 43821.1Skamil 43831.1SkamilATF_TC_BODY(signal4, tc) 43841.1Skamil{ 43851.1Skamil const int exitval = 5; 43861.1Skamil const int sigval = SIGSTOP; 43871.1Skamil const int sigmasked = SIGTRAP; 43881.1Skamil pid_t child, wpid; 43891.1Skamil#if defined(TWAIT_HAVE_STATUS) 43901.1Skamil int status; 43911.1Skamil#endif 43921.1Skamil sigset_t intmask; 43931.1Skamil int happy; 43941.1Skamil 43951.1Skamil#if defined(__arm__) 43961.5Skamil /* PT_STEP not supported on arm 32-bit */ 43971.5Skamil atf_tc_expect_fail("PR kern/51918 PR kern/52119"); 43981.1Skamil#endif 43991.1Skamil 44001.13Schristos DPRINTF("Before forking process PID=%d\n", getpid()); 44011.13Schristos SYSCALL_REQUIRE((child = fork()) != -1); 44021.1Skamil if (child == 0) { 44031.13Schristos DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 44041.1Skamil FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 44051.1Skamil 44061.1Skamil happy = check_happy(100); 44071.1Skamil 44081.1Skamil sigemptyset(&intmask); 44091.1Skamil sigaddset(&intmask, sigmasked); 44101.1Skamil sigprocmask(SIG_BLOCK, &intmask, NULL); 44111.1Skamil 44121.13Schristos DPRINTF("Before raising %s from child\n", strsignal(sigval)); 44131.1Skamil FORKEE_ASSERT(raise(sigval) == 0); 44141.1Skamil 44151.1Skamil FORKEE_ASSERT_EQ(happy, check_happy(100)); 44161.1Skamil 44171.13Schristos DPRINTF("Before exiting of the child process\n"); 44181.1Skamil _exit(exitval); 44191.1Skamil } 44201.13Schristos DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 44211.1Skamil 44221.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 44231.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 44241.1Skamil 44251.1Skamil validate_status_stopped(status, sigval); 44261.1Skamil 44271.13Schristos DPRINTF("Before resuming the child process where it left off and " 44281.1Skamil "without signal to be sent\n"); 44291.13Schristos SYSCALL_REQUIRE(ptrace(PT_STEP, child, (void *)1, 0) != -1); 44301.1Skamil 44311.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 44321.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 44331.1Skamil 44341.1Skamil validate_status_stopped(status, sigmasked); 44351.1Skamil 44361.13Schristos DPRINTF("Before resuming the child process where it left off and " 44371.1Skamil "without signal to be sent\n"); 44381.13Schristos SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 44391.1Skamil 44401.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 44411.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 44421.1Skamil 44431.1Skamil validate_status_exited(status, exitval); 44441.1Skamil 44451.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 44461.1Skamil TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 44471.1Skamil} 44481.1Skamil#endif 44491.1Skamil 44501.1SkamilATF_TC(signal5); 44511.1SkamilATF_TC_HEAD(signal5, tc) 44521.1Skamil{ 44531.1Skamil atf_tc_set_md_var(tc, "descr", 44541.1Skamil "Verify that masking SIGTRAP in tracee does not stop tracer from " 44551.1Skamil "catching exec() breakpoint"); 44561.1Skamil} 44571.1Skamil 44581.1SkamilATF_TC_BODY(signal5, tc) 44591.1Skamil{ 44601.1Skamil const int sigval = SIGSTOP; 44611.1Skamil const int sigmasked = SIGTRAP; 44621.1Skamil pid_t child, wpid; 44631.1Skamil#if defined(TWAIT_HAVE_STATUS) 44641.1Skamil int status; 44651.1Skamil#endif 44661.58Skamil struct ptrace_siginfo info; 44671.1Skamil sigset_t intmask; 44681.1Skamil 44691.58Skamil memset(&info, 0, sizeof(info)); 44701.14Schristos 44711.13Schristos DPRINTF("Before forking process PID=%d\n", getpid()); 44721.13Schristos SYSCALL_REQUIRE((child = fork()) != -1); 44731.1Skamil if (child == 0) { 44741.13Schristos DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 44751.1Skamil FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 44761.1Skamil 44771.1Skamil sigemptyset(&intmask); 44781.1Skamil sigaddset(&intmask, sigmasked); 44791.1Skamil sigprocmask(SIG_BLOCK, &intmask, NULL); 44801.1Skamil 44811.13Schristos DPRINTF("Before raising %s from child\n", strsignal(sigval)); 44821.1Skamil FORKEE_ASSERT(raise(sigval) == 0); 44831.1Skamil 44841.13Schristos DPRINTF("Before calling execve(2) from child\n"); 44851.1Skamil execlp("/bin/echo", "/bin/echo", NULL); 44861.1Skamil 44871.58Skamil /* NOTREACHED */ 44881.58Skamil FORKEE_ASSERTX(0 && "Not reached"); 44891.1Skamil } 44901.13Schristos DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 44911.1Skamil 44921.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 44931.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 44941.1Skamil 44951.1Skamil validate_status_stopped(status, sigval); 44961.1Skamil 44971.13Schristos DPRINTF("Before resuming the child process where it left off and " 44981.1Skamil "without signal to be sent\n"); 44991.13Schristos SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 45001.1Skamil 45011.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 45021.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 45031.1Skamil 45041.1Skamil validate_status_stopped(status, sigmasked); 45051.1Skamil 45061.58Skamil DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 45071.61Skre SYSCALL_REQUIRE( 45081.61Skre ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 45091.58Skamil 45101.58Skamil DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 45111.58Skamil DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 45121.58Skamil info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 45131.58Skamil info.psi_siginfo.si_errno); 45141.58Skamil 45151.58Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigmasked); 45161.58Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_EXEC); 45171.58Skamil 45181.13Schristos DPRINTF("Before resuming the child process where it left off and " 45191.1Skamil "without signal to be sent\n"); 45201.13Schristos SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 45211.1Skamil 45221.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 45231.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 45241.1Skamil 45251.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 45261.1Skamil TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 45271.1Skamil} 45281.1Skamil 45291.1Skamil#if defined(TWAIT_HAVE_PID) 45301.1SkamilATF_TC(signal6); 45311.1SkamilATF_TC_HEAD(signal6, tc) 45321.1Skamil{ 45331.1Skamil atf_tc_set_md_var(tc, "timeout", "5"); 45341.1Skamil atf_tc_set_md_var(tc, "descr", 45351.1Skamil "Verify that masking SIGTRAP in tracee does not stop tracer from " 45361.1Skamil "catching PTRACE_FORK breakpoint"); 45371.1Skamil} 45381.1Skamil 45391.1SkamilATF_TC_BODY(signal6, tc) 45401.1Skamil{ 45411.1Skamil const int exitval = 5; 45421.1Skamil const int exitval2 = 15; 45431.1Skamil const int sigval = SIGSTOP; 45441.1Skamil const int sigmasked = SIGTRAP; 45451.1Skamil pid_t child, child2, wpid; 45461.1Skamil#if defined(TWAIT_HAVE_STATUS) 45471.1Skamil int status; 45481.1Skamil#endif 45491.1Skamil sigset_t intmask; 45501.1Skamil ptrace_state_t state; 45511.1Skamil const int slen = sizeof(state); 45521.1Skamil ptrace_event_t event; 45531.1Skamil const int elen = sizeof(event); 45541.1Skamil 45551.38Skamil atf_tc_expect_fail("PR kern/51918"); 45561.14Schristos 45571.13Schristos DPRINTF("Before forking process PID=%d\n", getpid()); 45581.13Schristos SYSCALL_REQUIRE((child = fork()) != -1); 45591.1Skamil if (child == 0) { 45601.13Schristos DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 45611.1Skamil FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 45621.1Skamil 45631.1Skamil sigemptyset(&intmask); 45641.1Skamil sigaddset(&intmask, sigmasked); 45651.1Skamil sigprocmask(SIG_BLOCK, &intmask, NULL); 45661.1Skamil 45671.13Schristos DPRINTF("Before raising %s from child\n", strsignal(sigval)); 45681.1Skamil FORKEE_ASSERT(raise(sigval) == 0); 45691.1Skamil 45701.1Skamil FORKEE_ASSERT((child2 = fork()) != -1); 45711.1Skamil 45721.1Skamil if (child2 == 0) 45731.1Skamil _exit(exitval2); 45741.1Skamil 45751.1Skamil FORKEE_REQUIRE_SUCCESS 45761.1Skamil (wpid = TWAIT_GENERIC(child2, &status, 0), child2); 45771.1Skamil 45781.1Skamil forkee_status_exited(status, exitval2); 45791.1Skamil 45801.13Schristos DPRINTF("Before exiting of the child process\n"); 45811.1Skamil _exit(exitval); 45821.1Skamil } 45831.13Schristos DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 45841.1Skamil 45851.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 45861.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 45871.1Skamil 45881.1Skamil validate_status_stopped(status, sigval); 45891.1Skamil 45901.13Schristos DPRINTF("Enable PTRACE_FORK in EVENT_MASK for the child %d\n", child); 45911.1Skamil event.pe_set_event = PTRACE_FORK; 45921.13Schristos SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); 45931.1Skamil 45941.13Schristos DPRINTF("Before resuming the child process where it left off and " 45951.1Skamil "without signal to be sent\n"); 45961.13Schristos SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 45971.1Skamil 45981.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 45991.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 46001.1Skamil 46011.1Skamil validate_status_stopped(status, sigmasked); 46021.1Skamil 46031.13Schristos SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 46041.1Skamil ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_FORK); 46051.1Skamil 46061.1Skamil child2 = state.pe_other_pid; 46071.13Schristos DPRINTF("Reported PTRACE_FORK event with forkee %d\n", child2); 46081.1Skamil 46091.13Schristos DPRINTF("Before calling %s() for the child2\n", TWAIT_FNAME); 46101.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0), 46111.1Skamil child2); 46121.1Skamil 46131.1Skamil validate_status_stopped(status, SIGTRAP); 46141.1Skamil 46151.13Schristos SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1); 46161.1Skamil ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_FORK); 46171.1Skamil ATF_REQUIRE_EQ(state.pe_other_pid, child); 46181.1Skamil 46191.13Schristos DPRINTF("Before resuming the forkee process where it left off and " 46201.1Skamil "without signal to be sent\n"); 46211.13Schristos SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1); 46221.1Skamil 46231.13Schristos DPRINTF("Before resuming the child process where it left off and " 46241.1Skamil "without signal to be sent\n"); 46251.13Schristos SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 46261.1Skamil 46271.13Schristos DPRINTF("Before calling %s() for the forkee - expected exited\n", 46281.1Skamil TWAIT_FNAME); 46291.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0), 46301.57Skamil child2); 46311.1Skamil 46321.1Skamil validate_status_exited(status, exitval2); 46331.1Skamil 46341.13Schristos DPRINTF("Before calling %s() for the forkee - expected no process\n", 46351.1Skamil TWAIT_FNAME); 46361.1Skamil TWAIT_REQUIRE_FAILURE(ECHILD, 46371.1Skamil wpid = TWAIT_GENERIC(child2, &status, 0)); 46381.1Skamil 46391.13Schristos DPRINTF("Before calling %s() for the child - expected stopped " 46401.1Skamil "SIGCHLD\n", TWAIT_FNAME); 46411.57Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 46421.1Skamil 46431.1Skamil validate_status_stopped(status, SIGCHLD); 46441.1Skamil 46451.57Skamil DPRINTF("Before resuming the child process where it left off and " 46461.1Skamil "without signal to be sent\n"); 46471.13Schristos SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 46481.1Skamil 46491.13Schristos DPRINTF("Before calling %s() for the child - expected exited\n", 46501.1Skamil TWAIT_FNAME); 46511.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 46521.1Skamil 46531.1Skamil validate_status_exited(status, exitval); 46541.1Skamil 46551.13Schristos DPRINTF("Before calling %s() for the child - expected no process\n", 46561.57Skamil TWAIT_FNAME); 46571.1Skamil TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 46581.1Skamil} 46591.1Skamil#endif 46601.1Skamil 46611.1Skamil#if defined(TWAIT_HAVE_PID) 46621.1SkamilATF_TC(signal7); 46631.1SkamilATF_TC_HEAD(signal7, tc) 46641.1Skamil{ 46651.1Skamil atf_tc_set_md_var(tc, "descr", 46661.1Skamil "Verify that masking SIGTRAP in tracee does not stop tracer from " 46671.1Skamil "catching PTRACE_VFORK breakpoint"); 46681.1Skamil} 46691.1Skamil 46701.1SkamilATF_TC_BODY(signal7, tc) 46711.1Skamil{ 46721.1Skamil const int exitval = 5; 46731.1Skamil const int exitval2 = 15; 46741.1Skamil const int sigval = SIGSTOP; 46751.1Skamil const int sigmasked = SIGTRAP; 46761.1Skamil pid_t child, child2, wpid; 46771.1Skamil#if defined(TWAIT_HAVE_STATUS) 46781.1Skamil int status; 46791.1Skamil#endif 46801.1Skamil sigset_t intmask; 46811.1Skamil ptrace_state_t state; 46821.1Skamil const int slen = sizeof(state); 46831.1Skamil ptrace_event_t event; 46841.1Skamil const int elen = sizeof(event); 46851.1Skamil 46861.38Skamil atf_tc_expect_fail("PR kern/51918"); 46871.14Schristos 46881.13Schristos DPRINTF("Before forking process PID=%d\n", getpid()); 46891.13Schristos SYSCALL_REQUIRE((child = fork()) != -1); 46901.1Skamil if (child == 0) { 46911.13Schristos DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 46921.1Skamil FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 46931.1Skamil 46941.1Skamil sigemptyset(&intmask); 46951.1Skamil sigaddset(&intmask, sigmasked); 46961.1Skamil sigprocmask(SIG_BLOCK, &intmask, NULL); 46971.1Skamil 46981.13Schristos DPRINTF("Before raising %s from child\n", strsignal(sigval)); 46991.1Skamil FORKEE_ASSERT(raise(sigval) == 0); 47001.1Skamil 47011.1Skamil FORKEE_ASSERT((child2 = fork()) != -1); 47021.1Skamil 47031.1Skamil if (child2 == 0) 47041.1Skamil _exit(exitval2); 47051.1Skamil 47061.1Skamil FORKEE_REQUIRE_SUCCESS 47071.1Skamil (wpid = TWAIT_GENERIC(child2, &status, 0), child2); 47081.1Skamil 47091.1Skamil forkee_status_exited(status, exitval2); 47101.1Skamil 47111.13Schristos DPRINTF("Before exiting of the child process\n"); 47121.1Skamil _exit(exitval); 47131.1Skamil } 47141.13Schristos DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 47151.1Skamil 47161.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 47171.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 47181.1Skamil 47191.1Skamil validate_status_stopped(status, sigval); 47201.1Skamil 47211.13Schristos DPRINTF("Enable PTRACE_VFORK in EVENT_MASK for the child %d\n", child); 47221.1Skamil event.pe_set_event = PTRACE_VFORK; 47231.61Skre SYSCALL_REQUIRE( 47241.61Skre ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1 || 47251.61Skre errno == ENOTSUP); 47261.1Skamil 47271.13Schristos DPRINTF("Before resuming the child process where it left off and " 47281.1Skamil "without signal to be sent\n"); 47291.13Schristos SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 47301.1Skamil 47311.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 47321.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 47331.1Skamil 47341.1Skamil validate_status_stopped(status, sigmasked); 47351.1Skamil 47361.61Skre SYSCALL_REQUIRE( 47371.61Skre ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 47381.1Skamil ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK); 47391.1Skamil 47401.1Skamil child2 = state.pe_other_pid; 47411.13Schristos DPRINTF("Reported PTRACE_VFORK event with forkee %d\n", child2); 47421.1Skamil 47431.13Schristos DPRINTF("Before calling %s() for the child2\n", TWAIT_FNAME); 47441.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0), 47451.1Skamil child2); 47461.1Skamil 47471.1Skamil validate_status_stopped(status, SIGTRAP); 47481.1Skamil 47491.61Skre SYSCALL_REQUIRE( 47501.61Skre ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1); 47511.1Skamil ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK); 47521.1Skamil ATF_REQUIRE_EQ(state.pe_other_pid, child); 47531.1Skamil 47541.13Schristos DPRINTF("Before resuming the forkee process where it left off and " 47551.1Skamil "without signal to be sent\n"); 47561.13Schristos SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1); 47571.1Skamil 47581.13Schristos DPRINTF("Before resuming the child process where it left off and " 47591.1Skamil "without signal to be sent\n"); 47601.13Schristos SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 47611.1Skamil 47621.13Schristos DPRINTF("Before calling %s() for the forkee - expected exited\n", 47631.1Skamil TWAIT_FNAME); 47641.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0), 47651.57Skamil child2); 47661.1Skamil 47671.1Skamil validate_status_exited(status, exitval2); 47681.1Skamil 47691.13Schristos DPRINTF("Before calling %s() for the forkee - expected no process\n", 47701.1Skamil TWAIT_FNAME); 47711.1Skamil TWAIT_REQUIRE_FAILURE(ECHILD, 47721.1Skamil wpid = TWAIT_GENERIC(child2, &status, 0)); 47731.1Skamil 47741.13Schristos DPRINTF("Before calling %s() for the child - expected stopped " 47751.1Skamil "SIGCHLD\n", TWAIT_FNAME); 47761.57Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 47771.1Skamil 47781.1Skamil validate_status_stopped(status, SIGCHLD); 47791.1Skamil 47801.57Skamil DPRINTF("Before resuming the child process where it left off and " 47811.1Skamil "without signal to be sent\n"); 47821.13Schristos SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 47831.1Skamil 47841.13Schristos DPRINTF("Before calling %s() for the child - expected exited\n", 47851.1Skamil TWAIT_FNAME); 47861.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 47871.1Skamil 47881.1Skamil validate_status_exited(status, exitval); 47891.1Skamil 47901.13Schristos DPRINTF("Before calling %s() for the child - expected no process\n", 47911.57Skamil TWAIT_FNAME); 47921.1Skamil TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 47931.1Skamil} 47941.1Skamil#endif 47951.1Skamil 47961.1SkamilATF_TC(signal8); 47971.1SkamilATF_TC_HEAD(signal8, tc) 47981.1Skamil{ 47991.1Skamil atf_tc_set_md_var(tc, "descr", 48001.1Skamil "Verify that masking SIGTRAP in tracee does not stop tracer from " 48011.1Skamil "catching PTRACE_VFORK_DONE breakpoint"); 48021.1Skamil} 48031.1Skamil 48041.1SkamilATF_TC_BODY(signal8, tc) 48051.1Skamil{ 48061.1Skamil const int exitval = 5; 48071.1Skamil const int exitval2 = 15; 48081.1Skamil const int sigval = SIGSTOP; 48091.1Skamil const int sigmasked = SIGTRAP; 48101.1Skamil pid_t child, child2, wpid; 48111.1Skamil#if defined(TWAIT_HAVE_STATUS) 48121.1Skamil int status; 48131.1Skamil#endif 48141.1Skamil sigset_t intmask; 48151.1Skamil ptrace_state_t state; 48161.1Skamil const int slen = sizeof(state); 48171.1Skamil ptrace_event_t event; 48181.1Skamil const int elen = sizeof(event); 48191.1Skamil 48201.14Schristos atf_tc_expect_fail("PR kern/51918"); 48211.14Schristos 48221.13Schristos DPRINTF("Before forking process PID=%d\n", getpid()); 48231.13Schristos SYSCALL_REQUIRE((child = fork()) != -1); 48241.1Skamil if (child == 0) { 48251.13Schristos DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 48261.1Skamil FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 48271.1Skamil 48281.1Skamil sigemptyset(&intmask); 48291.1Skamil sigaddset(&intmask, sigmasked); 48301.1Skamil sigprocmask(SIG_BLOCK, &intmask, NULL); 48311.1Skamil 48321.13Schristos DPRINTF("Before raising %s from child\n", strsignal(sigval)); 48331.1Skamil FORKEE_ASSERT(raise(sigval) == 0); 48341.1Skamil 48351.1Skamil FORKEE_ASSERT((child2 = vfork()) != -1); 48361.1Skamil 48371.1Skamil if (child2 == 0) 48381.1Skamil _exit(exitval2); 48391.1Skamil 48401.1Skamil FORKEE_REQUIRE_SUCCESS 48411.1Skamil (wpid = TWAIT_GENERIC(child2, &status, 0), child2); 48421.1Skamil 48431.1Skamil forkee_status_exited(status, exitval2); 48441.1Skamil 48451.13Schristos DPRINTF("Before exiting of the child process\n"); 48461.1Skamil _exit(exitval); 48471.1Skamil } 48481.13Schristos DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 48491.1Skamil 48501.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 48511.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 48521.1Skamil 48531.1Skamil validate_status_stopped(status, sigval); 48541.1Skamil 48551.13Schristos DPRINTF("Enable PTRACE_VFORK_DONE in EVENT_MASK for the child %d\n", 48561.1Skamil child); 48571.1Skamil event.pe_set_event = PTRACE_VFORK_DONE; 48581.13Schristos SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); 48591.1Skamil 48601.13Schristos DPRINTF("Before resuming the child process where it left off and " 48611.1Skamil "without signal to be sent\n"); 48621.13Schristos SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 48631.1Skamil 48641.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 48651.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 48661.1Skamil 48671.1Skamil validate_status_stopped(status, sigmasked); 48681.1Skamil 48691.61Skre SYSCALL_REQUIRE( 48701.61Skre ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 48711.1Skamil ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK_DONE); 48721.1Skamil 48731.1Skamil child2 = state.pe_other_pid; 48741.13Schristos DPRINTF("Reported PTRACE_VFORK_DONE event with forkee %d\n", child2); 48751.1Skamil 48761.13Schristos DPRINTF("Before resuming the child process where it left off and " 48771.1Skamil "without signal to be sent\n"); 48781.13Schristos SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 48791.1Skamil 48801.13Schristos DPRINTF("Before calling %s() for the child - expected stopped " 48811.1Skamil "SIGCHLD\n", TWAIT_FNAME); 48821.57Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 48831.1Skamil 48841.1Skamil validate_status_stopped(status, SIGCHLD); 48851.1Skamil 48861.57Skamil DPRINTF("Before resuming the child process where it left off and " 48871.1Skamil "without signal to be sent\n"); 48881.13Schristos SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 48891.1Skamil 48901.13Schristos DPRINTF("Before calling %s() for the child - expected exited\n", 48911.1Skamil TWAIT_FNAME); 48921.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 48931.1Skamil 48941.1Skamil validate_status_exited(status, exitval); 48951.1Skamil 48961.13Schristos DPRINTF("Before calling %s() for the child - expected no process\n", 48971.57Skamil TWAIT_FNAME); 48981.1Skamil TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 48991.1Skamil} 49001.1Skamil 49011.83Skamilvolatile lwpid_t the_lwp_id = 0; 49021.83Skamil 49031.83Skamilstatic void 49041.83Skamillwp_main_func(void *arg) 49051.83Skamil{ 49061.83Skamil the_lwp_id = _lwp_self(); 49071.83Skamil _lwp_exit(); 49081.83Skamil} 49091.83Skamil 49101.1SkamilATF_TC(signal9); 49111.1SkamilATF_TC_HEAD(signal9, tc) 49121.1Skamil{ 49131.1Skamil atf_tc_set_md_var(tc, "descr", 49141.1Skamil "Verify that masking SIGTRAP in tracee does not stop tracer from " 49151.1Skamil "catching PTRACE_LWP_CREATE breakpoint"); 49161.1Skamil} 49171.1Skamil 49181.1SkamilATF_TC_BODY(signal9, tc) 49191.1Skamil{ 49201.1Skamil const int exitval = 5; 49211.1Skamil const int sigval = SIGSTOP; 49221.1Skamil const int sigmasked = SIGTRAP; 49231.1Skamil pid_t child, wpid; 49241.1Skamil#if defined(TWAIT_HAVE_STATUS) 49251.1Skamil int status; 49261.1Skamil#endif 49271.1Skamil sigset_t intmask; 49281.1Skamil ptrace_state_t state; 49291.1Skamil const int slen = sizeof(state); 49301.1Skamil ptrace_event_t event; 49311.1Skamil const int elen = sizeof(event); 49321.1Skamil ucontext_t uc; 49331.1Skamil lwpid_t lid; 49341.1Skamil static const size_t ssize = 16*1024; 49351.1Skamil void *stack; 49361.1Skamil 49371.14Schristos atf_tc_expect_fail("PR kern/51918"); 49381.14Schristos 49391.13Schristos DPRINTF("Before forking process PID=%d\n", getpid()); 49401.13Schristos SYSCALL_REQUIRE((child = fork()) != -1); 49411.1Skamil if (child == 0) { 49421.13Schristos DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 49431.1Skamil FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 49441.1Skamil 49451.1Skamil sigemptyset(&intmask); 49461.1Skamil sigaddset(&intmask, sigmasked); 49471.1Skamil sigprocmask(SIG_BLOCK, &intmask, NULL); 49481.1Skamil 49491.13Schristos DPRINTF("Before raising %s from child\n", strsignal(sigval)); 49501.1Skamil FORKEE_ASSERT(raise(sigval) == 0); 49511.1Skamil 49521.13Schristos DPRINTF("Before allocating memory for stack in child\n"); 49531.1Skamil FORKEE_ASSERT((stack = malloc(ssize)) != NULL); 49541.1Skamil 49551.13Schristos DPRINTF("Before making context for new lwp in child\n"); 49561.1Skamil _lwp_makecontext(&uc, lwp_main_func, NULL, NULL, stack, ssize); 49571.1Skamil 49581.13Schristos DPRINTF("Before creating new in child\n"); 49591.1Skamil FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0); 49601.1Skamil 49611.13Schristos DPRINTF("Before waiting for lwp %d to exit\n", lid); 49621.1Skamil FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0); 49631.1Skamil 49641.13Schristos DPRINTF("Before verifying that reported %d and running lid %d " 49651.1Skamil "are the same\n", lid, the_lwp_id); 49661.1Skamil FORKEE_ASSERT_EQ(lid, the_lwp_id); 49671.1Skamil 49681.13Schristos DPRINTF("Before exiting of the child process\n"); 49691.1Skamil _exit(exitval); 49701.1Skamil } 49711.13Schristos DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 49721.1Skamil 49731.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 49741.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 49751.1Skamil 49761.1Skamil validate_status_stopped(status, sigval); 49771.1Skamil 49781.13Schristos DPRINTF("Set empty EVENT_MASK for the child %d\n", child); 49791.1Skamil event.pe_set_event = PTRACE_LWP_CREATE; 49801.13Schristos SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); 49811.1Skamil 49821.13Schristos DPRINTF("Before resuming the child process where it left off and " 49831.1Skamil "without signal to be sent\n"); 49841.13Schristos SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 49851.1Skamil 49861.13Schristos DPRINTF("Before calling %s() for the child - expected stopped " 49871.1Skamil "SIGTRAP\n", TWAIT_FNAME); 49881.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 49891.1Skamil 49901.1Skamil validate_status_stopped(status, sigmasked); 49911.1Skamil 49921.13Schristos SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 49931.1Skamil 49941.1Skamil ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_LWP_CREATE); 49951.1Skamil 49961.1Skamil lid = state.pe_lwp; 49971.13Schristos DPRINTF("Reported PTRACE_LWP_CREATE event with lid %d\n", lid); 49981.1Skamil 49991.13Schristos DPRINTF("Before resuming the child process where it left off and " 50001.1Skamil "without signal to be sent\n"); 50011.13Schristos SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 50021.1Skamil 50031.13Schristos DPRINTF("Before calling %s() for the child - expected exited\n", 50041.1Skamil TWAIT_FNAME); 50051.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 50061.1Skamil 50071.1Skamil validate_status_exited(status, exitval); 50081.1Skamil 50091.13Schristos DPRINTF("Before calling %s() for the child - expected no process\n", 50101.1Skamil TWAIT_FNAME); 50111.1Skamil TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 50121.1Skamil} 50131.1Skamil 50141.1SkamilATF_TC(signal10); 50151.1SkamilATF_TC_HEAD(signal10, tc) 50161.1Skamil{ 50171.1Skamil atf_tc_set_md_var(tc, "descr", 50181.1Skamil "Verify that masking SIGTRAP in tracee does not stop tracer from " 50191.1Skamil "catching PTRACE_LWP_EXIT breakpoint"); 50201.1Skamil} 50211.1Skamil 50221.1SkamilATF_TC_BODY(signal10, tc) 50231.1Skamil{ 50241.1Skamil const int exitval = 5; 50251.1Skamil const int sigval = SIGSTOP; 50261.1Skamil const int sigmasked = SIGTRAP; 50271.1Skamil pid_t child, wpid; 50281.1Skamil#if defined(TWAIT_HAVE_STATUS) 50291.1Skamil int status; 50301.1Skamil#endif 50311.1Skamil sigset_t intmask; 50321.1Skamil ptrace_state_t state; 50331.1Skamil const int slen = sizeof(state); 50341.1Skamil ptrace_event_t event; 50351.1Skamil const int elen = sizeof(event); 50361.1Skamil ucontext_t uc; 50371.1Skamil lwpid_t lid; 50381.1Skamil static const size_t ssize = 16*1024; 50391.1Skamil void *stack; 50401.1Skamil 50411.14Schristos atf_tc_expect_fail("PR kern/51918"); 50421.14Schristos 50431.13Schristos DPRINTF("Before forking process PID=%d\n", getpid()); 50441.13Schristos SYSCALL_REQUIRE((child = fork()) != -1); 50451.1Skamil if (child == 0) { 50461.13Schristos DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 50471.1Skamil FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 50481.1Skamil 50491.1Skamil sigemptyset(&intmask); 50501.1Skamil sigaddset(&intmask, sigmasked); 50511.1Skamil sigprocmask(SIG_BLOCK, &intmask, NULL); 50521.1Skamil 50531.13Schristos DPRINTF("Before raising %s from child\n", strsignal(sigval)); 50541.1Skamil FORKEE_ASSERT(raise(sigval) == 0); 50551.1Skamil 50561.13Schristos DPRINTF("Before allocating memory for stack in child\n"); 50571.1Skamil FORKEE_ASSERT((stack = malloc(ssize)) != NULL); 50581.1Skamil 50591.13Schristos DPRINTF("Before making context for new lwp in child\n"); 50601.1Skamil _lwp_makecontext(&uc, lwp_main_func, NULL, NULL, stack, ssize); 50611.1Skamil 50621.13Schristos DPRINTF("Before creating new in child\n"); 50631.1Skamil FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0); 50641.1Skamil 50651.13Schristos DPRINTF("Before waiting for lwp %d to exit\n", lid); 50661.1Skamil FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0); 50671.1Skamil 50681.13Schristos DPRINTF("Before verifying that reported %d and running lid %d " 50691.1Skamil "are the same\n", lid, the_lwp_id); 50701.1Skamil FORKEE_ASSERT_EQ(lid, the_lwp_id); 50711.1Skamil 50721.13Schristos DPRINTF("Before exiting of the child process\n"); 50731.1Skamil _exit(exitval); 50741.1Skamil } 50751.13Schristos DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 50761.1Skamil 50771.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 50781.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 50791.1Skamil 50801.1Skamil validate_status_stopped(status, sigval); 50811.1Skamil 50821.13Schristos DPRINTF("Set empty EVENT_MASK for the child %d\n", child); 50831.1Skamil event.pe_set_event = PTRACE_LWP_EXIT; 50841.13Schristos SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); 50851.1Skamil 50861.13Schristos DPRINTF("Before resuming the child process where it left off and " 50871.1Skamil "without signal to be sent\n"); 50881.13Schristos SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 50891.1Skamil 50901.13Schristos DPRINTF("Before calling %s() for the child - expected stopped " 50911.1Skamil "SIGTRAP\n", TWAIT_FNAME); 50921.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 50931.1Skamil 50941.1Skamil validate_status_stopped(status, sigmasked); 50951.1Skamil 50961.13Schristos SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 50971.1Skamil 50981.1Skamil ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_LWP_EXIT); 50991.1Skamil 51001.1Skamil lid = state.pe_lwp; 51011.13Schristos DPRINTF("Reported PTRACE_LWP_EXIT event with lid %d\n", lid); 51021.1Skamil 51031.13Schristos DPRINTF("Before resuming the child process where it left off and " 51041.1Skamil "without signal to be sent\n"); 51051.13Schristos SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 51061.1Skamil 51071.13Schristos DPRINTF("Before calling %s() for the child - expected exited\n", 51081.1Skamil TWAIT_FNAME); 51091.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 51101.1Skamil 51111.1Skamil validate_status_exited(status, exitval); 51121.1Skamil 51131.13Schristos DPRINTF("Before calling %s() for the child - expected no process\n", 51141.1Skamil TWAIT_FNAME); 51151.1Skamil TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 51161.1Skamil} 51171.1Skamil 51181.1Skamilstatic void 51191.1Skamillwp_main_stop(void *arg) 51201.1Skamil{ 51211.1Skamil the_lwp_id = _lwp_self(); 51221.1Skamil 51231.1Skamil raise(SIGTRAP); 51241.1Skamil 51251.1Skamil _lwp_exit(); 51261.1Skamil} 51271.1Skamil 51281.1SkamilATF_TC(suspend1); 51291.1SkamilATF_TC_HEAD(suspend1, tc) 51301.1Skamil{ 51311.1Skamil atf_tc_set_md_var(tc, "descr", 51321.1Skamil "Verify that a thread can be suspended by a debugger and later " 51331.1Skamil "resumed by a tracee"); 51341.1Skamil} 51351.1Skamil 51361.1SkamilATF_TC_BODY(suspend1, tc) 51371.1Skamil{ 51381.1Skamil const int exitval = 5; 51391.1Skamil const int sigval = SIGSTOP; 51401.1Skamil pid_t child, wpid; 51411.1Skamil#if defined(TWAIT_HAVE_STATUS) 51421.1Skamil int status; 51431.1Skamil#endif 51441.1Skamil ucontext_t uc; 51451.1Skamil lwpid_t lid; 51461.1Skamil static const size_t ssize = 16*1024; 51471.1Skamil void *stack; 51481.1Skamil struct ptrace_lwpinfo pl; 51491.1Skamil struct ptrace_siginfo psi; 51501.1Skamil volatile int go = 0; 51511.1Skamil 51521.17Skamil // Feature pending for refactoring 51531.17Skamil atf_tc_expect_fail("PR kern/51995"); 51541.17Skamil 51551.16Skamil // Hangs with qemu 51561.16Skamil ATF_REQUIRE(0 && "In order to get reliable failure, abort"); 51571.16Skamil 51581.13Schristos DPRINTF("Before forking process PID=%d\n", getpid()); 51591.13Schristos SYSCALL_REQUIRE((child = fork()) != -1); 51601.1Skamil if (child == 0) { 51611.13Schristos DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 51621.1Skamil FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 51631.1Skamil 51641.13Schristos DPRINTF("Before raising %s from child\n", strsignal(sigval)); 51651.1Skamil FORKEE_ASSERT(raise(sigval) == 0); 51661.1Skamil 51671.13Schristos DPRINTF("Before allocating memory for stack in child\n"); 51681.1Skamil FORKEE_ASSERT((stack = malloc(ssize)) != NULL); 51691.1Skamil 51701.13Schristos DPRINTF("Before making context for new lwp in child\n"); 51711.1Skamil _lwp_makecontext(&uc, lwp_main_stop, NULL, NULL, stack, ssize); 51721.1Skamil 51731.13Schristos DPRINTF("Before creating new in child\n"); 51741.1Skamil FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0); 51751.1Skamil 51761.1Skamil while (go == 0) 51771.1Skamil continue; 51781.1Skamil 51791.1Skamil raise(SIGINT); 51801.1Skamil 51811.1Skamil FORKEE_ASSERT(_lwp_continue(lid) == 0); 51821.1Skamil 51831.13Schristos DPRINTF("Before waiting for lwp %d to exit\n", lid); 51841.1Skamil FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0); 51851.1Skamil 51861.13Schristos DPRINTF("Before verifying that reported %d and running lid %d " 51871.1Skamil "are the same\n", lid, the_lwp_id); 51881.1Skamil FORKEE_ASSERT_EQ(lid, the_lwp_id); 51891.1Skamil 51901.13Schristos DPRINTF("Before exiting of the child process\n"); 51911.1Skamil _exit(exitval); 51921.1Skamil } 51931.13Schristos DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 51941.1Skamil 51951.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 51961.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 51971.1Skamil 51981.1Skamil validate_status_stopped(status, sigval); 51991.1Skamil 52001.13Schristos DPRINTF("Before resuming the child process where it left off and " 52011.1Skamil "without signal to be sent\n"); 52021.13Schristos SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 52031.1Skamil 52041.13Schristos DPRINTF("Before calling %s() for the child - expected stopped " 52051.1Skamil "SIGTRAP\n", TWAIT_FNAME); 52061.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 52071.1Skamil 52081.1Skamil validate_status_stopped(status, SIGTRAP); 52091.1Skamil 52101.13Schristos DPRINTF("Before reading siginfo and lwpid_t\n"); 52111.13Schristos SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &psi, sizeof(psi)) != -1); 52121.1Skamil 52131.13Schristos DPRINTF("Before suspending LWP %d\n", psi.psi_lwpid); 52141.13Schristos SYSCALL_REQUIRE(ptrace(PT_SUSPEND, child, NULL, psi.psi_lwpid) != -1); 52151.1Skamil 52161.13Schristos DPRINTF("Write new go to tracee (PID=%d) from tracer (PID=%d)\n", 52171.1Skamil child, getpid()); 52181.13Schristos SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, __UNVOLATILE(&go), 1) != -1); 52191.1Skamil 52201.13Schristos DPRINTF("Before resuming the child process where it left off and " 52211.1Skamil "without signal to be sent\n"); 52221.13Schristos SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 52231.1Skamil 52241.13Schristos DPRINTF("Before calling %s() for the child - expected stopped " 52251.1Skamil "SIGINT\n", TWAIT_FNAME); 52261.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 52271.1Skamil 52281.1Skamil validate_status_stopped(status, SIGINT); 52291.1Skamil 52301.1Skamil pl.pl_lwpid = 0; 52311.1Skamil 52321.13Schristos SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &pl, sizeof(pl)) != -1); 52331.1Skamil while (pl.pl_lwpid != 0) { 52341.1Skamil 52351.13Schristos SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &pl, sizeof(pl)) != -1); 52361.1Skamil switch (pl.pl_lwpid) { 52371.1Skamil case 1: 52381.1Skamil ATF_REQUIRE_EQ(pl.pl_event, PL_EVENT_SIGNAL); 52391.1Skamil break; 52401.1Skamil case 2: 52411.1Skamil ATF_REQUIRE_EQ(pl.pl_event, PL_EVENT_SUSPENDED); 52421.1Skamil break; 52431.1Skamil } 52441.1Skamil } 52451.1Skamil 52461.13Schristos DPRINTF("Before resuming the child process where it left off and " 52471.1Skamil "without signal to be sent\n"); 52481.13Schristos SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 52491.1Skamil 52501.13Schristos DPRINTF("Before calling %s() for the child - expected exited\n", 52511.1Skamil TWAIT_FNAME); 52521.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 52531.1Skamil 52541.1Skamil validate_status_exited(status, exitval); 52551.1Skamil 52561.13Schristos DPRINTF("Before calling %s() for the child - expected no process\n", 52571.1Skamil TWAIT_FNAME); 52581.1Skamil TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 52591.1Skamil} 52601.1Skamil 52611.1SkamilATF_TC(suspend2); 52621.1SkamilATF_TC_HEAD(suspend2, tc) 52631.1Skamil{ 52641.1Skamil atf_tc_set_md_var(tc, "descr", 52651.1Skamil "Verify that the while the only thread within a process is " 52661.1Skamil "suspended, the whole process cannot be unstopped"); 52671.1Skamil} 52681.1Skamil 52691.1SkamilATF_TC_BODY(suspend2, tc) 52701.1Skamil{ 52711.1Skamil const int exitval = 5; 52721.1Skamil const int sigval = SIGSTOP; 52731.1Skamil pid_t child, wpid; 52741.1Skamil#if defined(TWAIT_HAVE_STATUS) 52751.1Skamil int status; 52761.1Skamil#endif 52771.1Skamil struct ptrace_siginfo psi; 52781.1Skamil 52791.17Skamil // Feature pending for refactoring 52801.17Skamil atf_tc_expect_fail("PR kern/51995"); 52811.17Skamil 52821.16Skamil // Hangs with qemu 52831.16Skamil ATF_REQUIRE(0 && "In order to get reliable failure, abort"); 52841.16Skamil 52851.13Schristos DPRINTF("Before forking process PID=%d\n", getpid()); 52861.13Schristos SYSCALL_REQUIRE((child = fork()) != -1); 52871.1Skamil if (child == 0) { 52881.13Schristos DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 52891.1Skamil FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 52901.1Skamil 52911.13Schristos DPRINTF("Before raising %s from child\n", strsignal(sigval)); 52921.1Skamil FORKEE_ASSERT(raise(sigval) == 0); 52931.1Skamil 52941.13Schristos DPRINTF("Before exiting of the child process\n"); 52951.1Skamil _exit(exitval); 52961.1Skamil } 52971.13Schristos DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 52981.1Skamil 52991.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 53001.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 53011.1Skamil 53021.1Skamil validate_status_stopped(status, sigval); 53031.1Skamil 53041.13Schristos DPRINTF("Before reading siginfo and lwpid_t\n"); 53051.13Schristos SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &psi, sizeof(psi)) != -1); 53061.1Skamil 53071.13Schristos DPRINTF("Before suspending LWP %d\n", psi.psi_lwpid); 53081.13Schristos SYSCALL_REQUIRE(ptrace(PT_SUSPEND, child, NULL, psi.psi_lwpid) != -1); 53091.1Skamil 53101.13Schristos DPRINTF("Before resuming the child process where it left off and " 53111.1Skamil "without signal to be sent\n"); 53121.1Skamil ATF_REQUIRE_ERRNO(EDEADLK, 53131.1Skamil ptrace(PT_CONTINUE, child, (void *)1, 0) == -1); 53141.1Skamil 53151.13Schristos DPRINTF("Before resuming LWP %d\n", psi.psi_lwpid); 53161.13Schristos SYSCALL_REQUIRE(ptrace(PT_RESUME, child, NULL, psi.psi_lwpid) != -1); 53171.1Skamil 53181.13Schristos DPRINTF("Before resuming the child process where it left off and " 53191.1Skamil "without signal to be sent\n"); 53201.13Schristos SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 53211.1Skamil 53221.13Schristos DPRINTF("Before calling %s() for the child - expected exited\n", 53231.1Skamil TWAIT_FNAME); 53241.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 53251.1Skamil 53261.1Skamil validate_status_exited(status, exitval); 53271.1Skamil 53281.13Schristos DPRINTF("Before calling %s() for the child - expected no process\n", 53291.1Skamil TWAIT_FNAME); 53301.1Skamil TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 53311.1Skamil} 53321.1Skamil 53331.1SkamilATF_TC(resume1); 53341.1SkamilATF_TC_HEAD(resume1, tc) 53351.1Skamil{ 53361.1Skamil atf_tc_set_md_var(tc, "timeout", "5"); 53371.1Skamil atf_tc_set_md_var(tc, "descr", 53381.1Skamil "Verify that a thread can be suspended by a debugger and later " 53391.1Skamil "resumed by the debugger"); 53401.1Skamil} 53411.1Skamil 53421.1SkamilATF_TC_BODY(resume1, tc) 53431.1Skamil{ 53441.1Skamil struct msg_fds fds; 53451.1Skamil const int exitval = 5; 53461.1Skamil const int sigval = SIGSTOP; 53471.1Skamil pid_t child, wpid; 53481.1Skamil uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */ 53491.1Skamil#if defined(TWAIT_HAVE_STATUS) 53501.1Skamil int status; 53511.1Skamil#endif 53521.1Skamil ucontext_t uc; 53531.1Skamil lwpid_t lid; 53541.1Skamil static const size_t ssize = 16*1024; 53551.1Skamil void *stack; 53561.1Skamil struct ptrace_lwpinfo pl; 53571.1Skamil struct ptrace_siginfo psi; 53581.1Skamil 53591.17Skamil // Feature pending for refactoring 53601.17Skamil atf_tc_expect_fail("PR kern/51995"); 53611.17Skamil 53621.15Schristos // Hangs with qemu 53631.15Schristos ATF_REQUIRE(0 && "In order to get reliable failure, abort"); 53641.1Skamil 53651.13Schristos SYSCALL_REQUIRE(msg_open(&fds) == 0); 53661.1Skamil 53671.13Schristos DPRINTF("Before forking process PID=%d\n", getpid()); 53681.13Schristos SYSCALL_REQUIRE((child = fork()) != -1); 53691.1Skamil if (child == 0) { 53701.13Schristos DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 53711.1Skamil FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 53721.1Skamil 53731.13Schristos DPRINTF("Before raising %s from child\n", strsignal(sigval)); 53741.1Skamil FORKEE_ASSERT(raise(sigval) == 0); 53751.1Skamil 53761.13Schristos DPRINTF("Before allocating memory for stack in child\n"); 53771.1Skamil FORKEE_ASSERT((stack = malloc(ssize)) != NULL); 53781.1Skamil 53791.13Schristos DPRINTF("Before making context for new lwp in child\n"); 53801.1Skamil _lwp_makecontext(&uc, lwp_main_stop, NULL, NULL, stack, ssize); 53811.1Skamil 53821.13Schristos DPRINTF("Before creating new in child\n"); 53831.1Skamil FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0); 53841.1Skamil 53851.1Skamil CHILD_TO_PARENT("Message", fds, msg); 53861.1Skamil 53871.1Skamil raise(SIGINT); 53881.1Skamil 53891.13Schristos DPRINTF("Before waiting for lwp %d to exit\n", lid); 53901.1Skamil FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0); 53911.1Skamil 53921.13Schristos DPRINTF("Before verifying that reported %d and running lid %d " 53931.1Skamil "are the same\n", lid, the_lwp_id); 53941.1Skamil FORKEE_ASSERT_EQ(lid, the_lwp_id); 53951.1Skamil 53961.13Schristos DPRINTF("Before exiting of the child process\n"); 53971.1Skamil _exit(exitval); 53981.1Skamil } 53991.13Schristos DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 54001.1Skamil 54011.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 54021.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 54031.1Skamil 54041.1Skamil validate_status_stopped(status, sigval); 54051.1Skamil 54061.13Schristos DPRINTF("Before resuming the child process where it left off and " 54071.1Skamil "without signal to be sent\n"); 54081.13Schristos SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 54091.1Skamil 54101.13Schristos DPRINTF("Before calling %s() for the child - expected stopped " 54111.1Skamil "SIGTRAP\n", TWAIT_FNAME); 54121.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 54131.1Skamil 54141.1Skamil validate_status_stopped(status, SIGTRAP); 54151.1Skamil 54161.13Schristos DPRINTF("Before reading siginfo and lwpid_t\n"); 54171.13Schristos SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &psi, sizeof(psi)) != -1); 54181.1Skamil 54191.13Schristos DPRINTF("Before suspending LWP %d\n", psi.psi_lwpid); 54201.13Schristos SYSCALL_REQUIRE(ptrace(PT_SUSPEND, child, NULL, psi.psi_lwpid) != -1); 54211.1Skamil 54221.1Skamil PARENT_FROM_CHILD("Message", fds, msg); 54231.1Skamil 54241.13Schristos DPRINTF("Before resuming the child process where it left off and " 54251.1Skamil "without signal to be sent\n"); 54261.13Schristos SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 54271.1Skamil 54281.13Schristos DPRINTF("Before calling %s() for the child - expected stopped " 54291.1Skamil "SIGINT\n", TWAIT_FNAME); 54301.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 54311.1Skamil 54321.1Skamil validate_status_stopped(status, SIGINT); 54331.1Skamil 54341.1Skamil pl.pl_lwpid = 0; 54351.1Skamil 54361.13Schristos SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &pl, sizeof(pl)) != -1); 54371.1Skamil while (pl.pl_lwpid != 0) { 54381.13Schristos SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &pl, sizeof(pl)) != -1); 54391.1Skamil switch (pl.pl_lwpid) { 54401.1Skamil case 1: 54411.1Skamil ATF_REQUIRE_EQ(pl.pl_event, PL_EVENT_SIGNAL); 54421.1Skamil break; 54431.1Skamil case 2: 54441.1Skamil ATF_REQUIRE_EQ(pl.pl_event, PL_EVENT_SUSPENDED); 54451.1Skamil break; 54461.1Skamil } 54471.1Skamil } 54481.1Skamil 54491.13Schristos DPRINTF("Before resuming LWP %d\n", psi.psi_lwpid); 54501.13Schristos SYSCALL_REQUIRE(ptrace(PT_RESUME, child, NULL, psi.psi_lwpid) != -1); 54511.1Skamil 54521.13Schristos DPRINTF("Before resuming the child process where it left off and " 54531.1Skamil "without signal to be sent\n"); 54541.13Schristos SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 54551.1Skamil 54561.13Schristos DPRINTF("Before calling %s() for the child - expected exited\n", 54571.1Skamil TWAIT_FNAME); 54581.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 54591.1Skamil 54601.1Skamil validate_status_exited(status, exitval); 54611.1Skamil 54621.13Schristos DPRINTF("Before calling %s() for the child - expected no process\n", 54631.1Skamil TWAIT_FNAME); 54641.1Skamil TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 54651.1Skamil 54661.1Skamil msg_close(&fds); 54671.1Skamil 54681.13Schristos DPRINTF("XXX: Test worked this time but for consistency timeout it\n"); 54691.1Skamil sleep(10); 54701.1Skamil} 54711.1Skamil 54721.1SkamilATF_TC(syscall1); 54731.1SkamilATF_TC_HEAD(syscall1, tc) 54741.1Skamil{ 54751.1Skamil atf_tc_set_md_var(tc, "descr", 54761.1Skamil "Verify that getpid(2) can be traced with PT_SYSCALL"); 54771.1Skamil} 54781.1Skamil 54791.1SkamilATF_TC_BODY(syscall1, tc) 54801.1Skamil{ 54811.1Skamil const int exitval = 5; 54821.1Skamil const int sigval = SIGSTOP; 54831.1Skamil pid_t child, wpid; 54841.1Skamil#if defined(TWAIT_HAVE_STATUS) 54851.1Skamil int status; 54861.1Skamil#endif 54871.1Skamil struct ptrace_siginfo info; 54881.1Skamil memset(&info, 0, sizeof(info)); 54891.1Skamil 54901.13Schristos DPRINTF("Before forking process PID=%d\n", getpid()); 54911.13Schristos SYSCALL_REQUIRE((child = fork()) != -1); 54921.1Skamil if (child == 0) { 54931.13Schristos DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 54941.1Skamil FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 54951.1Skamil 54961.13Schristos DPRINTF("Before raising %s from child\n", strsignal(sigval)); 54971.1Skamil FORKEE_ASSERT(raise(sigval) == 0); 54981.1Skamil 54991.1Skamil syscall(SYS_getpid); 55001.1Skamil 55011.13Schristos DPRINTF("Before exiting of the child process\n"); 55021.1Skamil _exit(exitval); 55031.1Skamil } 55041.13Schristos DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 55051.1Skamil 55061.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 55071.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 55081.1Skamil 55091.1Skamil validate_status_stopped(status, sigval); 55101.1Skamil 55111.13Schristos DPRINTF("Before resuming the child process where it left off and " 55121.1Skamil "without signal to be sent\n"); 55131.13Schristos SYSCALL_REQUIRE(ptrace(PT_SYSCALL, child, (void *)1, 0) != -1); 55141.1Skamil 55151.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 55161.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 55171.1Skamil 55181.1Skamil validate_status_stopped(status, SIGTRAP); 55191.1Skamil 55201.13Schristos DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 55211.13Schristos SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 55221.1Skamil 55231.38Skamil DPRINTF("Before checking siginfo_t and lwpid\n"); 55241.38Skamil ATF_REQUIRE_EQ(info.psi_lwpid, 1); 55251.1Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); 55261.1Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_SCE); 55271.1Skamil 55281.13Schristos DPRINTF("Before resuming the child process where it left off and " 55291.1Skamil "without signal to be sent\n"); 55301.13Schristos SYSCALL_REQUIRE(ptrace(PT_SYSCALL, child, (void *)1, 0) != -1); 55311.1Skamil 55321.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 55331.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 55341.1Skamil 55351.1Skamil validate_status_stopped(status, SIGTRAP); 55361.1Skamil 55371.13Schristos DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 55381.13Schristos SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 55391.1Skamil 55401.38Skamil DPRINTF("Before checking siginfo_t and lwpid\n"); 55411.38Skamil ATF_REQUIRE_EQ(info.psi_lwpid, 1); 55421.1Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); 55431.1Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_SCX); 55441.1Skamil 55451.13Schristos DPRINTF("Before resuming the child process where it left off and " 55461.1Skamil "without signal to be sent\n"); 55471.13Schristos SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 55481.1Skamil 55491.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 55501.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 55511.1Skamil 55521.1Skamil validate_status_exited(status, exitval); 55531.1Skamil 55541.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 55551.1Skamil TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 55561.1Skamil} 55571.1Skamil 55581.1SkamilATF_TC(syscallemu1); 55591.1SkamilATF_TC_HEAD(syscallemu1, tc) 55601.1Skamil{ 55611.1Skamil atf_tc_set_md_var(tc, "descr", 55621.1Skamil "Verify that exit(2) can be intercepted with PT_SYSCALLEMU"); 55631.1Skamil} 55641.1Skamil 55651.1SkamilATF_TC_BODY(syscallemu1, tc) 55661.1Skamil{ 55671.1Skamil const int exitval = 5; 55681.1Skamil const int sigval = SIGSTOP; 55691.1Skamil pid_t child, wpid; 55701.1Skamil#if defined(TWAIT_HAVE_STATUS) 55711.1Skamil int status; 55721.1Skamil#endif 55731.1Skamil 55741.6Skamil#if defined(__sparc__) && !defined(__sparc64__) 55751.6Skamil /* syscallemu does not work on sparc (32-bit) */ 55761.6Skamil atf_tc_expect_fail("PR kern/52166"); 55771.6Skamil#endif 55781.6Skamil 55791.13Schristos DPRINTF("Before forking process PID=%d\n", getpid()); 55801.13Schristos SYSCALL_REQUIRE((child = fork()) != -1); 55811.1Skamil if (child == 0) { 55821.13Schristos DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 55831.1Skamil FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 55841.1Skamil 55851.13Schristos DPRINTF("Before raising %s from child\n", strsignal(sigval)); 55861.1Skamil FORKEE_ASSERT(raise(sigval) == 0); 55871.1Skamil 55881.1Skamil syscall(SYS_exit, 100); 55891.1Skamil 55901.13Schristos DPRINTF("Before exiting of the child process\n"); 55911.1Skamil _exit(exitval); 55921.1Skamil } 55931.13Schristos DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 55941.1Skamil 55951.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 55961.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 55971.1Skamil 55981.1Skamil validate_status_stopped(status, sigval); 55991.1Skamil 56001.13Schristos DPRINTF("Before resuming the child process where it left off and " 56011.1Skamil "without signal to be sent\n"); 56021.13Schristos SYSCALL_REQUIRE(ptrace(PT_SYSCALL, child, (void *)1, 0) != -1); 56031.1Skamil 56041.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 56051.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 56061.1Skamil 56071.1Skamil validate_status_stopped(status, SIGTRAP); 56081.1Skamil 56091.13Schristos DPRINTF("Set SYSCALLEMU for intercepted syscall\n"); 56101.13Schristos SYSCALL_REQUIRE(ptrace(PT_SYSCALLEMU, child, (void *)1, 0) != -1); 56111.1Skamil 56121.13Schristos DPRINTF("Before resuming the child process where it left off and " 56131.1Skamil "without signal to be sent\n"); 56141.13Schristos SYSCALL_REQUIRE(ptrace(PT_SYSCALL, child, (void *)1, 0) != -1); 56151.1Skamil 56161.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 56171.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 56181.1Skamil 56191.1Skamil validate_status_stopped(status, SIGTRAP); 56201.1Skamil 56211.13Schristos DPRINTF("Before resuming the child process where it left off and " 56221.1Skamil "without signal to be sent\n"); 56231.13Schristos SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 56241.1Skamil 56251.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 56261.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 56271.1Skamil 56281.1Skamil validate_status_exited(status, exitval); 56291.1Skamil 56301.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 56311.1Skamil TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 56321.1Skamil} 56331.1Skamil 56341.1Skamil#include "t_ptrace_amd64_wait.h" 56351.1Skamil#include "t_ptrace_i386_wait.h" 56361.1Skamil#include "t_ptrace_x86_wait.h" 56371.1Skamil 56381.1SkamilATF_TP_ADD_TCS(tp) 56391.1Skamil{ 56401.1Skamil setvbuf(stdout, NULL, _IONBF, 0); 56411.1Skamil setvbuf(stderr, NULL, _IONBF, 0); 56421.33Skamil 56431.36Skamil ATF_TP_ADD_TC(tp, traceme_raise1); 56441.33Skamil ATF_TP_ADD_TC(tp, traceme_raise2); 56451.33Skamil ATF_TP_ADD_TC(tp, traceme_raise3); 56461.33Skamil ATF_TP_ADD_TC(tp, traceme_raise4); 56471.33Skamil ATF_TP_ADD_TC(tp, traceme_raise5); 56481.85Skamil ATF_TP_ADD_TC(tp, traceme_raise6); 56491.85Skamil ATF_TP_ADD_TC(tp, traceme_raise7); 56501.85Skamil ATF_TP_ADD_TC(tp, traceme_raise8); 56511.85Skamil ATF_TP_ADD_TC(tp, traceme_raise9); 56521.85Skamil ATF_TP_ADD_TC(tp, traceme_raise10); 56531.33Skamil 56541.87Skamil ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored1); 56551.87Skamil ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored2); 56561.87Skamil ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored3); 56571.87Skamil ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored4); 56581.87Skamil ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored5); 56591.87Skamil ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored6); 56601.87Skamil ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored7); 56611.87Skamil ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored8); 56621.87Skamil 56631.86Skamil ATF_TP_ADD_TC(tp, traceme_raisesignal_masked1); 56641.86Skamil ATF_TP_ADD_TC(tp, traceme_raisesignal_masked2); 56651.86Skamil ATF_TP_ADD_TC(tp, traceme_raisesignal_masked3); 56661.86Skamil ATF_TP_ADD_TC(tp, traceme_raisesignal_masked4); 56671.86Skamil ATF_TP_ADD_TC(tp, traceme_raisesignal_masked5); 56681.86Skamil ATF_TP_ADD_TC(tp, traceme_raisesignal_masked6); 56691.86Skamil ATF_TP_ADD_TC(tp, traceme_raisesignal_masked7); 56701.86Skamil ATF_TP_ADD_TC(tp, traceme_raisesignal_masked8); 56711.86Skamil 56721.59Skamil ATF_TP_ADD_TC(tp, traceme_crash_trap); 56731.59Skamil ATF_TP_ADD_TC(tp, traceme_crash_segv); 56741.71Skamil ATF_TP_ADD_TC(tp, traceme_crash_ill); 56751.59Skamil ATF_TP_ADD_TC(tp, traceme_crash_fpe); 56761.59Skamil ATF_TP_ADD_TC(tp, traceme_crash_bus); 56771.59Skamil 56781.88Skamil ATF_TP_ADD_TC(tp, traceme_signalmasked_crash_trap); 56791.88Skamil ATF_TP_ADD_TC(tp, traceme_signalmasked_crash_segv); 56801.88Skamil ATF_TP_ADD_TC(tp, traceme_signalmasked_crash_ill); 56811.88Skamil ATF_TP_ADD_TC(tp, traceme_signalmasked_crash_fpe); 56821.88Skamil ATF_TP_ADD_TC(tp, traceme_signalmasked_crash_bus); 56831.88Skamil 56841.88Skamil ATF_TP_ADD_TC(tp, traceme_signalignored_crash_trap); 56851.88Skamil ATF_TP_ADD_TC(tp, traceme_signalignored_crash_segv); 56861.88Skamil ATF_TP_ADD_TC(tp, traceme_signalignored_crash_ill); 56871.88Skamil ATF_TP_ADD_TC(tp, traceme_signalignored_crash_fpe); 56881.88Skamil ATF_TP_ADD_TC(tp, traceme_signalignored_crash_bus); 56891.88Skamil 56901.50Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_handle1); 56911.50Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_handle2); 56921.50Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_handle3); 56931.85Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_handle4); 56941.85Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_handle5); 56951.85Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_handle6); 56961.85Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_handle7); 56971.85Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_handle8); 56981.50Skamil 56991.50Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_masked1); 57001.50Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_masked2); 57011.50Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_masked3); 57021.85Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_masked4); 57031.85Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_masked5); 57041.85Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_masked6); 57051.85Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_masked7); 57061.85Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_masked8); 57071.50Skamil 57081.50Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored1); 57091.50Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored2); 57101.50Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored3); 57111.85Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored4); 57121.85Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored5); 57131.85Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored6); 57141.85Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored7); 57151.85Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored8); 57161.50Skamil 57171.50Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_simple1); 57181.50Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_simple2); 57191.50Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_simple3); 57201.50Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_simple4); 57211.50Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_simple5); 57221.85Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_simple6); 57231.85Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_simple7); 57241.85Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_simple8); 57251.85Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_simple9); 57261.85Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_simple10); 57271.1Skamil 57281.37Skamil ATF_TP_ADD_TC(tp, traceme_pid1_parent); 57291.37Skamil 57301.40Skamil ATF_TP_ADD_TC(tp, traceme_vfork_raise1); 57311.46Skamil ATF_TP_ADD_TC(tp, traceme_vfork_raise2); 57321.40Skamil ATF_TP_ADD_TC(tp, traceme_vfork_raise3); 57331.40Skamil ATF_TP_ADD_TC(tp, traceme_vfork_raise4); 57341.40Skamil ATF_TP_ADD_TC(tp, traceme_vfork_raise5); 57351.47Skamil ATF_TP_ADD_TC(tp, traceme_vfork_raise6); 57361.47Skamil ATF_TP_ADD_TC(tp, traceme_vfork_raise7); 57371.47Skamil ATF_TP_ADD_TC(tp, traceme_vfork_raise8); 57381.85Skamil ATF_TP_ADD_TC(tp, traceme_vfork_raise9); 57391.85Skamil ATF_TP_ADD_TC(tp, traceme_vfork_raise10); 57401.85Skamil ATF_TP_ADD_TC(tp, traceme_vfork_raise11); 57411.85Skamil ATF_TP_ADD_TC(tp, traceme_vfork_raise12); 57421.85Skamil ATF_TP_ADD_TC(tp, traceme_vfork_raise13); 57431.40Skamil 57441.52Skamil ATF_TP_ADD_TC(tp, traceme_vfork_crash_trap); 57451.52Skamil ATF_TP_ADD_TC(tp, traceme_vfork_crash_segv); 57461.71Skamil ATF_TP_ADD_TC(tp, traceme_vfork_crash_ill); 57471.52Skamil ATF_TP_ADD_TC(tp, traceme_vfork_crash_fpe); 57481.52Skamil ATF_TP_ADD_TC(tp, traceme_vfork_crash_bus); 57491.41Skamil 57501.43Skamil ATF_TP_ADD_TC(tp, traceme_vfork_exec); 57511.43Skamil 57521.59Skamil ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_sees_crash_trap); 57531.59Skamil ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_sees_crash_segv); 57541.71Skamil ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_sees_crash_ill); 57551.59Skamil ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_sees_crash_fpe); 57561.59Skamil ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_sees_crash_bus); 57571.59Skamil 57581.51Skamil ATF_TP_ADD_TC_HAVE_PID(tp, tracer_sees_terminaton_before_the_parent); 57591.51Skamil ATF_TP_ADD_TC_HAVE_PID(tp, tracer_sysctl_lookup_without_duplicates); 57601.61Skre ATF_TP_ADD_TC_HAVE_PID(tp, 57611.61Skre unrelated_tracer_sees_terminaton_before_the_parent); 57621.67Skamil ATF_TP_ADD_TC_HAVE_PID(tp, tracer_attach_to_unrelated_stopped_process); 57631.51Skamil 57641.51Skamil ATF_TP_ADD_TC(tp, parent_attach_to_its_child); 57651.66Skamil ATF_TP_ADD_TC(tp, parent_attach_to_its_stopped_child); 57661.51Skamil 57671.51Skamil ATF_TP_ADD_TC(tp, child_attach_to_its_parent); 57681.65Skamil ATF_TP_ADD_TC(tp, child_attach_to_its_stopped_parent); 57691.51Skamil 57701.51Skamil ATF_TP_ADD_TC_HAVE_PID(tp, 57711.51Skamil tracee_sees_its_original_parent_getppid); 57721.51Skamil ATF_TP_ADD_TC_HAVE_PID(tp, 57731.51Skamil tracee_sees_its_original_parent_sysctl_kinfo_proc2); 57741.51Skamil ATF_TP_ADD_TC_HAVE_PID(tp, 57751.51Skamil tracee_sees_its_original_parent_procfs_status); 57761.1Skamil 57771.53Skamil ATF_TP_ADD_TC(tp, eventmask_preserved_empty); 57781.53Skamil ATF_TP_ADD_TC(tp, eventmask_preserved_fork); 57791.53Skamil ATF_TP_ADD_TC(tp, eventmask_preserved_vfork); 57801.53Skamil ATF_TP_ADD_TC(tp, eventmask_preserved_vfork_done); 57811.53Skamil ATF_TP_ADD_TC(tp, eventmask_preserved_lwp_create); 57821.53Skamil ATF_TP_ADD_TC(tp, eventmask_preserved_lwp_exit); 57831.1Skamil 57841.31Skamil ATF_TP_ADD_TC(tp, fork1); 57851.31Skamil ATF_TP_ADD_TC_HAVE_PID(tp, fork2); 57861.31Skamil ATF_TP_ADD_TC_HAVE_PID(tp, fork3); 57871.31Skamil ATF_TP_ADD_TC_HAVE_PID(tp, fork4); 57881.31Skamil ATF_TP_ADD_TC(tp, fork5); 57891.31Skamil ATF_TP_ADD_TC_HAVE_PID(tp, fork6); 57901.31Skamil ATF_TP_ADD_TC_HAVE_PID(tp, fork7); 57911.31Skamil ATF_TP_ADD_TC_HAVE_PID(tp, fork8); 57921.31Skamil 57931.31Skamil ATF_TP_ADD_TC(tp, vfork1); 57941.31Skamil ATF_TP_ADD_TC_HAVE_PID(tp, vfork2); 57951.31Skamil ATF_TP_ADD_TC_HAVE_PID(tp, vfork3); 57961.31Skamil ATF_TP_ADD_TC_HAVE_PID(tp, vfork4); 57971.31Skamil ATF_TP_ADD_TC(tp, vfork5); 57981.31Skamil ATF_TP_ADD_TC_HAVE_PID(tp, vfork6); 57991.64Smartin// thes tests hang on SMP machines, disable them for now 58001.64Smartin// ATF_TP_ADD_TC_HAVE_PID(tp, vfork7); 58011.64Smartin// ATF_TP_ADD_TC_HAVE_PID(tp, vfork8); 58021.1Skamil 58031.54Skamil ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_8); 58041.54Skamil ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_16); 58051.54Skamil ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_32); 58061.54Skamil ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_64); 58071.54Skamil 58081.54Skamil ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_8); 58091.54Skamil ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_16); 58101.54Skamil ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_32); 58111.54Skamil ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_64); 58121.54Skamil 58131.54Skamil ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_8); 58141.54Skamil ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_16); 58151.54Skamil ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_32); 58161.54Skamil ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_64); 58171.54Skamil 58181.54Skamil ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_8); 58191.54Skamil ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_16); 58201.54Skamil ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_32); 58211.54Skamil ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_64); 58221.54Skamil 58231.54Skamil ATF_TP_ADD_TC(tp, bytes_transfer_read_d); 58241.54Skamil ATF_TP_ADD_TC(tp, bytes_transfer_read_i); 58251.54Skamil ATF_TP_ADD_TC(tp, bytes_transfer_write_d); 58261.54Skamil ATF_TP_ADD_TC(tp, bytes_transfer_write_i); 58271.54Skamil 58281.54Skamil ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_8_text); 58291.54Skamil ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_16_text); 58301.54Skamil ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_32_text); 58311.54Skamil ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_64_text); 58321.54Skamil 58331.54Skamil ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_8_text); 58341.54Skamil ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_16_text); 58351.54Skamil ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_32_text); 58361.54Skamil ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_64_text); 58371.54Skamil 58381.54Skamil ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_8_text); 58391.54Skamil ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_16_text); 58401.54Skamil ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_32_text); 58411.54Skamil ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_64_text); 58421.54Skamil 58431.54Skamil ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_8_text); 58441.54Skamil ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_16_text); 58451.54Skamil ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_32_text); 58461.54Skamil ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_64_text); 58471.54Skamil 58481.54Skamil ATF_TP_ADD_TC(tp, bytes_transfer_read_d_text); 58491.54Skamil ATF_TP_ADD_TC(tp, bytes_transfer_read_i_text); 58501.54Skamil ATF_TP_ADD_TC(tp, bytes_transfer_write_d_text); 58511.54Skamil ATF_TP_ADD_TC(tp, bytes_transfer_write_i_text); 58521.1Skamil 58531.54Skamil ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_auxv); 58541.1Skamil 58551.72Skamil ATF_TP_ADD_TC_HAVE_GPREGS(tp, access_regs1); 58561.72Skamil ATF_TP_ADD_TC_HAVE_GPREGS(tp, access_regs2); 58571.72Skamil ATF_TP_ADD_TC_HAVE_GPREGS(tp, access_regs3); 58581.72Skamil ATF_TP_ADD_TC_HAVE_GPREGS(tp, access_regs4); 58591.72Skamil ATF_TP_ADD_TC_HAVE_GPREGS(tp, access_regs5); 58601.72Skamil ATF_TP_ADD_TC_HAVE_GPREGS(tp, access_regs6); 58611.1Skamil 58621.72Skamil ATF_TP_ADD_TC_HAVE_FPREGS(tp, access_fpregs1); 58631.72Skamil ATF_TP_ADD_TC_HAVE_FPREGS(tp, access_fpregs2); 58641.1Skamil 58651.1Skamil ATF_TP_ADD_TC_PT_STEP(tp, step1); 58661.1Skamil ATF_TP_ADD_TC_PT_STEP(tp, step2); 58671.1Skamil ATF_TP_ADD_TC_PT_STEP(tp, step3); 58681.1Skamil ATF_TP_ADD_TC_PT_STEP(tp, step4); 58691.1Skamil 58701.2Skamil ATF_TP_ADD_TC_PT_STEP(tp, setstep1); 58711.2Skamil ATF_TP_ADD_TC_PT_STEP(tp, setstep2); 58721.2Skamil ATF_TP_ADD_TC_PT_STEP(tp, setstep3); 58731.2Skamil ATF_TP_ADD_TC_PT_STEP(tp, setstep4); 58741.2Skamil 58751.1Skamil ATF_TP_ADD_TC(tp, kill1); 58761.1Skamil ATF_TP_ADD_TC(tp, kill2); 58771.75Skamil ATF_TP_ADD_TC(tp, kill3); 58781.1Skamil 58791.77Skamil ATF_TP_ADD_TC(tp, traceme_lwpinfo0); 58801.77Skamil ATF_TP_ADD_TC(tp, traceme_lwpinfo1); 58811.77Skamil ATF_TP_ADD_TC(tp, traceme_lwpinfo2); 58821.77Skamil ATF_TP_ADD_TC(tp, traceme_lwpinfo3); 58831.77Skamil 58841.77Skamil ATF_TP_ADD_TC_HAVE_PID(tp, attach_lwpinfo0); 58851.77Skamil ATF_TP_ADD_TC_HAVE_PID(tp, attach_lwpinfo1); 58861.77Skamil ATF_TP_ADD_TC_HAVE_PID(tp, attach_lwpinfo2); 58871.77Skamil ATF_TP_ADD_TC_HAVE_PID(tp, attach_lwpinfo3); 58881.1Skamil 58891.79Skamil ATF_TP_ADD_TC(tp, siginfo_set_unmodified); 58901.79Skamil ATF_TP_ADD_TC(tp, siginfo_set_faked); 58911.79Skamil 58921.82Skamil ATF_TP_ADD_TC(tp, traceme_exec); 58931.1Skamil 58941.83Skamil ATF_TP_ADD_TC(tp, trace_thread1); 58951.83Skamil ATF_TP_ADD_TC(tp, trace_thread2); 58961.83Skamil ATF_TP_ADD_TC(tp, trace_thread3); 58971.83Skamil ATF_TP_ADD_TC(tp, trace_thread4); 58981.1Skamil 58991.84Skamil ATF_TP_ADD_TC(tp, signal_mask_unrelated); 59001.84Skamil 59011.1Skamil ATF_TP_ADD_TC(tp, signal3); 59021.1Skamil ATF_TP_ADD_TC_PT_STEP(tp, signal4); 59031.1Skamil ATF_TP_ADD_TC(tp, signal5); 59041.1Skamil ATF_TP_ADD_TC_HAVE_PID(tp, signal6); 59051.1Skamil ATF_TP_ADD_TC_HAVE_PID(tp, signal7); 59061.1Skamil ATF_TP_ADD_TC(tp, signal8); 59071.1Skamil ATF_TP_ADD_TC(tp, signal9); 59081.1Skamil ATF_TP_ADD_TC(tp, signal10); 59091.1Skamil 59101.1Skamil ATF_TP_ADD_TC(tp, suspend1); 59111.1Skamil ATF_TP_ADD_TC(tp, suspend2); 59121.1Skamil 59131.1Skamil ATF_TP_ADD_TC(tp, resume1); 59141.1Skamil 59151.1Skamil ATF_TP_ADD_TC(tp, syscall1); 59161.1Skamil 59171.1Skamil ATF_TP_ADD_TC(tp, syscallemu1); 59181.1Skamil 59191.1Skamil ATF_TP_ADD_TCS_PTRACE_WAIT_AMD64(); 59201.1Skamil ATF_TP_ADD_TCS_PTRACE_WAIT_I386(); 59211.1Skamil ATF_TP_ADD_TCS_PTRACE_WAIT_X86(); 59221.1Skamil 59231.1Skamil return atf_no_error(); 59241.1Skamil} 5925