t_ptrace_wait.c revision 1.92
11.92Skamil/* $NetBSD: t_ptrace_wait.c,v 1.92 2019/02/17 09:29:35 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.92Skamil__RCSID("$NetBSD: t_ptrace_wait.c,v 1.92 2019/02/17 09:29:35 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.89Skamil const int sigval = SIGSTOP; 5171.88Skamil pid_t child, wpid; 5181.88Skamil#if defined(TWAIT_HAVE_STATUS) 5191.88Skamil int status; 5201.88Skamil#endif 5211.88Skamil struct ptrace_siginfo info; 5221.88Skamil sigset_t intmask; 5231.89Skamil struct kinfo_proc2 kp; 5241.89Skamil size_t len = sizeof(kp); 5251.89Skamil 5261.89Skamil int name[6]; 5271.89Skamil const size_t namelen = __arraycount(name); 5281.89Skamil ki_sigset_t kp_sigmask; 5291.88Skamil 5301.88Skamil#ifndef PTRACE_ILLEGAL_ASM 5311.88Skamil if (sig == SIGILL) 5321.88Skamil atf_tc_skip("PTRACE_ILLEGAL_ASM not defined"); 5331.88Skamil#endif 5341.88Skamil 5351.88Skamil memset(&info, 0, sizeof(info)); 5361.88Skamil 5371.89Skamil atf_tc_expect_fail("Unexpected sigmask reset on crash under debugger"); 5381.89Skamil 5391.88Skamil DPRINTF("Before forking process PID=%d\n", getpid()); 5401.88Skamil SYSCALL_REQUIRE((child = fork()) != -1); 5411.88Skamil if (child == 0) { 5421.88Skamil DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 5431.88Skamil FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 5441.88Skamil 5451.88Skamil sigemptyset(&intmask); 5461.88Skamil sigaddset(&intmask, sig); 5471.88Skamil sigprocmask(SIG_BLOCK, &intmask, NULL); 5481.88Skamil 5491.89Skamil DPRINTF("Before raising %s from child\n", strsignal(sigval)); 5501.89Skamil FORKEE_ASSERT(raise(sigval) == 0); 5511.89Skamil 5521.88Skamil DPRINTF("Before executing a trap\n"); 5531.88Skamil switch (sig) { 5541.88Skamil case SIGTRAP: 5551.88Skamil trigger_trap(); 5561.88Skamil break; 5571.88Skamil case SIGSEGV: 5581.88Skamil trigger_segv(); 5591.88Skamil break; 5601.88Skamil case SIGILL: 5611.88Skamil trigger_ill(); 5621.88Skamil break; 5631.88Skamil case SIGFPE: 5641.88Skamil trigger_fpe(); 5651.88Skamil break; 5661.88Skamil case SIGBUS: 5671.88Skamil trigger_bus(); 5681.88Skamil break; 5691.88Skamil default: 5701.88Skamil /* NOTREACHED */ 5711.88Skamil FORKEE_ASSERTX(0 && "This shall not be reached"); 5721.88Skamil } 5731.88Skamil 5741.88Skamil /* NOTREACHED */ 5751.88Skamil FORKEE_ASSERTX(0 && "This shall not be reached"); 5761.88Skamil } 5771.88Skamil DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 5781.88Skamil 5791.88Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 5801.88Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5811.88Skamil 5821.89Skamil validate_status_stopped(status, sigval); 5831.89Skamil 5841.89Skamil name[0] = CTL_KERN, 5851.89Skamil name[1] = KERN_PROC2, 5861.89Skamil name[2] = KERN_PROC_PID; 5871.89Skamil name[3] = child; 5881.89Skamil name[4] = sizeof(kp); 5891.89Skamil name[5] = 1; 5901.89Skamil 5911.89Skamil ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0); 5921.89Skamil 5931.89Skamil kp_sigmask = kp.p_sigmask; 5941.89Skamil 5951.89Skamil DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 5961.89Skamil SYSCALL_REQUIRE( 5971.89Skamil ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 5981.89Skamil 5991.89Skamil DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 6001.89Skamil DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 6011.89Skamil info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 6021.89Skamil info.psi_siginfo.si_errno); 6031.89Skamil 6041.89Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 6051.89Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 6061.89Skamil 6071.89Skamil DPRINTF("Before resuming the child process where it left off and " 6081.89Skamil "without signal to be sent\n"); 6091.89Skamil SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 6101.89Skamil 6111.89Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 6121.89Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 6131.89Skamil 6141.88Skamil validate_status_stopped(status, sig); 6151.88Skamil 6161.88Skamil DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child"); 6171.88Skamil SYSCALL_REQUIRE( 6181.88Skamil ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 6191.88Skamil 6201.88Skamil DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 6211.88Skamil DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 6221.88Skamil info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 6231.88Skamil info.psi_siginfo.si_errno); 6241.88Skamil 6251.89Skamil ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0); 6261.89Skamil 6271.89Skamil DPRINTF("kp_sigmask=" 6281.89Skamil "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n", 6291.89Skamil kp_sigmask.__bits[0], kp_sigmask.__bits[1], kp_sigmask.__bits[2], 6301.89Skamil kp_sigmask.__bits[3]); 6311.89Skamil 6321.89Skamil DPRINTF("kp.p_sigmask=" 6331.89Skamil "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n", 6341.89Skamil kp.p_sigmask.__bits[0], kp.p_sigmask.__bits[1], 6351.89Skamil kp.p_sigmask.__bits[2], kp.p_sigmask.__bits[3]); 6361.89Skamil 6371.89Skamil ATF_REQUIRE(!memcmp(&kp_sigmask, &kp.p_sigmask, sizeof(kp_sigmask))); 6381.89Skamil 6391.88Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sig); 6401.88Skamil switch (sig) { 6411.88Skamil case SIGTRAP: 6421.88Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_BRKPT); 6431.88Skamil break; 6441.88Skamil case SIGSEGV: 6451.88Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SEGV_MAPERR); 6461.88Skamil break; 6471.88Skamil case SIGILL: 6481.88Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_code, ILL_PRVOPC); 6491.88Skamil break; 6501.88Skamil case SIGFPE: 6511.88Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_code, FPE_INTDIV); 6521.88Skamil break; 6531.88Skamil case SIGBUS: 6541.88Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_code, BUS_ADRERR); 6551.88Skamil break; 6561.88Skamil } 6571.88Skamil 6581.88Skamil SYSCALL_REQUIRE(ptrace(PT_KILL, child, NULL, 0) != -1); 6591.88Skamil 6601.88Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 6611.88Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 6621.88Skamil 6631.88Skamil validate_status_signaled(status, SIGKILL, 0); 6641.88Skamil 6651.88Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 6661.88Skamil TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 6671.88Skamil} 6681.88Skamil 6691.88Skamil#define TRACEME_SIGNALMASKED_CRASH(test, sig) \ 6701.88SkamilATF_TC(test); \ 6711.88SkamilATF_TC_HEAD(test, tc) \ 6721.88Skamil{ \ 6731.88Skamil atf_tc_set_md_var(tc, "descr", \ 6741.88Skamil "Verify masked crash signal " #sig " in a child after " \ 6751.88Skamil "PT_TRACE_ME is delivered to its tracer"); \ 6761.88Skamil} \ 6771.88Skamil \ 6781.88SkamilATF_TC_BODY(test, tc) \ 6791.88Skamil{ \ 6801.88Skamil \ 6811.88Skamil traceme_signalmasked_crash(sig); \ 6821.88Skamil} 6831.88Skamil 6841.88SkamilTRACEME_SIGNALMASKED_CRASH(traceme_signalmasked_crash_trap, SIGTRAP) 6851.88SkamilTRACEME_SIGNALMASKED_CRASH(traceme_signalmasked_crash_segv, SIGSEGV) 6861.88SkamilTRACEME_SIGNALMASKED_CRASH(traceme_signalmasked_crash_ill, SIGILL) 6871.88SkamilTRACEME_SIGNALMASKED_CRASH(traceme_signalmasked_crash_fpe, SIGFPE) 6881.88SkamilTRACEME_SIGNALMASKED_CRASH(traceme_signalmasked_crash_bus, SIGBUS) 6891.88Skamil 6901.88Skamil/// ---------------------------------------------------------------------------- 6911.88Skamil 6921.88Skamilstatic void 6931.88Skamiltraceme_signalignored_crash(int sig) 6941.88Skamil{ 6951.90Skamil const int sigval = SIGSTOP; 6961.88Skamil pid_t child, wpid; 6971.88Skamil#if defined(TWAIT_HAVE_STATUS) 6981.88Skamil int status; 6991.88Skamil#endif 7001.88Skamil struct sigaction sa; 7011.88Skamil struct ptrace_siginfo info; 7021.90Skamil struct kinfo_proc2 kp; 7031.90Skamil size_t len = sizeof(kp); 7041.90Skamil 7051.90Skamil int name[6]; 7061.90Skamil const size_t namelen = __arraycount(name); 7071.90Skamil ki_sigset_t kp_sigignore; 7081.88Skamil 7091.88Skamil#ifndef PTRACE_ILLEGAL_ASM 7101.88Skamil if (sig == SIGILL) 7111.88Skamil atf_tc_skip("PTRACE_ILLEGAL_ASM not defined"); 7121.88Skamil#endif 7131.88Skamil 7141.90Skamil atf_tc_expect_fail("Unexpected sigmask reset on crash under debugger"); 7151.90Skamil 7161.88Skamil memset(&info, 0, sizeof(info)); 7171.88Skamil 7181.88Skamil DPRINTF("Before forking process PID=%d\n", getpid()); 7191.88Skamil SYSCALL_REQUIRE((child = fork()) != -1); 7201.88Skamil if (child == 0) { 7211.88Skamil DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 7221.88Skamil FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 7231.88Skamil 7241.88Skamil memset(&sa, 0, sizeof(sa)); 7251.88Skamil sa.sa_handler = SIG_IGN; 7261.88Skamil sigemptyset(&sa.sa_mask); 7271.88Skamil 7281.88Skamil FORKEE_ASSERT(sigaction(sig, &sa, NULL) != -1); 7291.88Skamil 7301.90Skamil DPRINTF("Before raising %s from child\n", strsignal(sigval)); 7311.90Skamil FORKEE_ASSERT(raise(sigval) == 0); 7321.90Skamil 7331.88Skamil DPRINTF("Before executing a trap\n"); 7341.88Skamil switch (sig) { 7351.88Skamil case SIGTRAP: 7361.88Skamil trigger_trap(); 7371.88Skamil break; 7381.88Skamil case SIGSEGV: 7391.88Skamil trigger_segv(); 7401.88Skamil break; 7411.88Skamil case SIGILL: 7421.88Skamil trigger_ill(); 7431.88Skamil break; 7441.88Skamil case SIGFPE: 7451.88Skamil trigger_fpe(); 7461.88Skamil break; 7471.88Skamil case SIGBUS: 7481.88Skamil trigger_bus(); 7491.88Skamil break; 7501.88Skamil default: 7511.88Skamil /* NOTREACHED */ 7521.88Skamil FORKEE_ASSERTX(0 && "This shall not be reached"); 7531.88Skamil } 7541.88Skamil 7551.88Skamil /* NOTREACHED */ 7561.88Skamil FORKEE_ASSERTX(0 && "This shall not be reached"); 7571.88Skamil } 7581.88Skamil DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 7591.88Skamil 7601.88Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 7611.88Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 7621.88Skamil 7631.90Skamil validate_status_stopped(status, sigval); 7641.90Skamil 7651.90Skamil name[0] = CTL_KERN, 7661.90Skamil name[1] = KERN_PROC2, 7671.90Skamil name[2] = KERN_PROC_PID; 7681.90Skamil name[3] = child; 7691.90Skamil name[4] = sizeof(kp); 7701.90Skamil name[5] = 1; 7711.90Skamil 7721.90Skamil ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0); 7731.90Skamil 7741.90Skamil kp_sigignore = kp.p_sigignore; 7751.90Skamil 7761.90Skamil DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 7771.90Skamil SYSCALL_REQUIRE( 7781.90Skamil ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 7791.90Skamil 7801.90Skamil DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 7811.90Skamil DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 7821.90Skamil info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 7831.90Skamil info.psi_siginfo.si_errno); 7841.90Skamil 7851.90Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 7861.90Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 7871.90Skamil 7881.90Skamil DPRINTF("Before resuming the child process where it left off and " 7891.90Skamil "without signal to be sent\n"); 7901.90Skamil SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 7911.90Skamil 7921.90Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 7931.90Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 7941.90Skamil 7951.88Skamil validate_status_stopped(status, sig); 7961.88Skamil 7971.88Skamil DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child"); 7981.88Skamil SYSCALL_REQUIRE( 7991.88Skamil ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 8001.88Skamil 8011.88Skamil DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 8021.88Skamil DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 8031.88Skamil info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 8041.88Skamil info.psi_siginfo.si_errno); 8051.88Skamil 8061.90Skamil ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0); 8071.90Skamil 8081.90Skamil DPRINTF("kp_sigignore=" 8091.90Skamil "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n", 8101.90Skamil kp_sigignore.__bits[0], kp_sigignore.__bits[1], 8111.90Skamil kp_sigignore.__bits[2], kp_sigignore.__bits[3]); 8121.90Skamil 8131.90Skamil DPRINTF("kp.p_sigignore=" 8141.90Skamil "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n", 8151.90Skamil kp.p_sigignore.__bits[0], kp.p_sigignore.__bits[1], 8161.90Skamil kp.p_sigignore.__bits[2], kp.p_sigignore.__bits[3]); 8171.90Skamil 8181.90Skamil ATF_REQUIRE(!memcmp(&kp_sigignore, &kp.p_sigignore, sizeof(kp_sigignore))); 8191.90Skamil 8201.88Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sig); 8211.88Skamil switch (sig) { 8221.88Skamil case SIGTRAP: 8231.88Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_BRKPT); 8241.88Skamil break; 8251.88Skamil case SIGSEGV: 8261.88Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SEGV_MAPERR); 8271.88Skamil break; 8281.88Skamil case SIGILL: 8291.88Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_code, ILL_PRVOPC); 8301.88Skamil break; 8311.88Skamil case SIGFPE: 8321.88Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_code, FPE_INTDIV); 8331.88Skamil break; 8341.88Skamil case SIGBUS: 8351.88Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_code, BUS_ADRERR); 8361.88Skamil break; 8371.88Skamil } 8381.88Skamil 8391.88Skamil SYSCALL_REQUIRE(ptrace(PT_KILL, child, NULL, 0) != -1); 8401.88Skamil 8411.88Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 8421.88Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 8431.88Skamil 8441.88Skamil validate_status_signaled(status, SIGKILL, 0); 8451.88Skamil 8461.88Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 8471.88Skamil TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 8481.88Skamil} 8491.88Skamil 8501.88Skamil#define TRACEME_SIGNALIGNORED_CRASH(test, sig) \ 8511.88SkamilATF_TC(test); \ 8521.88SkamilATF_TC_HEAD(test, tc) \ 8531.88Skamil{ \ 8541.88Skamil atf_tc_set_md_var(tc, "descr", \ 8551.88Skamil "Verify ignored crash signal " #sig " in a child after " \ 8561.88Skamil "PT_TRACE_ME is delivered to its tracer"); \ 8571.88Skamil} \ 8581.88Skamil \ 8591.88SkamilATF_TC_BODY(test, tc) \ 8601.88Skamil{ \ 8611.88Skamil \ 8621.88Skamil traceme_signalignored_crash(sig); \ 8631.88Skamil} 8641.88Skamil 8651.88SkamilTRACEME_SIGNALIGNORED_CRASH(traceme_signalignored_crash_trap, SIGTRAP) 8661.88SkamilTRACEME_SIGNALIGNORED_CRASH(traceme_signalignored_crash_segv, SIGSEGV) 8671.88SkamilTRACEME_SIGNALIGNORED_CRASH(traceme_signalignored_crash_ill, SIGILL) 8681.88SkamilTRACEME_SIGNALIGNORED_CRASH(traceme_signalignored_crash_fpe, SIGFPE) 8691.88SkamilTRACEME_SIGNALIGNORED_CRASH(traceme_signalignored_crash_bus, SIGBUS) 8701.88Skamil 8711.88Skamil/// ---------------------------------------------------------------------------- 8721.88Skamil 8731.88Skamilstatic void 8741.50Skamiltraceme_sendsignal_handle(int sigsent, void (*sah)(int a), int *traceme_caught) 8751.1Skamil{ 8761.1Skamil const int exitval = 5; 8771.34Skamil const int sigval = SIGSTOP; 8781.1Skamil pid_t child, wpid; 8791.1Skamil struct sigaction sa; 8801.1Skamil#if defined(TWAIT_HAVE_STATUS) 8811.1Skamil int status; 8821.1Skamil#endif 8831.61Skre struct ptrace_siginfo info; 8841.1Skamil 8851.45Skamil memset(&info, 0, sizeof(info)); 8861.45Skamil 8871.13Schristos DPRINTF("Before forking process PID=%d\n", getpid()); 8881.13Schristos SYSCALL_REQUIRE((child = fork()) != -1); 8891.1Skamil if (child == 0) { 8901.13Schristos DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 8911.1Skamil FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 8921.1Skamil 8931.34Skamil sa.sa_handler = sah; 8941.1Skamil sa.sa_flags = SA_SIGINFO; 8951.1Skamil sigemptyset(&sa.sa_mask); 8961.1Skamil 8971.1Skamil FORKEE_ASSERT(sigaction(sigsent, &sa, NULL) != -1); 8981.1Skamil 8991.13Schristos DPRINTF("Before raising %s from child\n", strsignal(sigval)); 9001.1Skamil FORKEE_ASSERT(raise(sigval) == 0); 9011.1Skamil 9021.34Skamil FORKEE_ASSERT_EQ(*traceme_caught, 1); 9031.1Skamil 9041.13Schristos DPRINTF("Before exiting of the child process\n"); 9051.1Skamil _exit(exitval); 9061.1Skamil } 9071.13Schristos DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 9081.1Skamil 9091.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 9101.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 9111.1Skamil 9121.1Skamil validate_status_stopped(status, sigval); 9131.1Skamil 9141.45Skamil DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 9151.61Skre SYSCALL_REQUIRE( 9161.61Skre ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 9171.45Skamil 9181.45Skamil DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 9191.45Skamil DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 9201.45Skamil info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 9211.45Skamil info.psi_siginfo.si_errno); 9221.45Skamil 9231.45Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 9241.45Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 9251.45Skamil 9261.13Schristos DPRINTF("Before resuming the child process where it left off and with " 9271.1Skamil "signal %s to be sent\n", strsignal(sigsent)); 9281.13Schristos SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigsent) != -1); 9291.1Skamil 9301.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 9311.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 9321.1Skamil 9331.1Skamil validate_status_exited(status, exitval); 9341.1Skamil 9351.13Schristos DPRINTF("Before calling %s() for the exited child\n", TWAIT_FNAME); 9361.1Skamil TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 9371.1Skamil} 9381.1Skamil 9391.61Skre#define TRACEME_SENDSIGNAL_HANDLE(test, sig) \ 9401.61SkreATF_TC(test); \ 9411.61SkreATF_TC_HEAD(test, tc) \ 9421.61Skre{ \ 9431.61Skre atf_tc_set_md_var(tc, "descr", \ 9441.61Skre "Verify that a signal " #sig " emitted by a tracer to a child is " \ 9451.61Skre "handled correctly and caught by a signal handler"); \ 9461.61Skre} \ 9471.61Skre \ 9481.61Skrestatic int test##_caught = 0; \ 9491.61Skre \ 9501.61Skrestatic void \ 9511.61Skretest##_sighandler(int arg) \ 9521.61Skre{ \ 9531.61Skre FORKEE_ASSERT_EQ(arg, sig); \ 9541.61Skre \ 9551.61Skre ++ test##_caught; \ 9561.61Skre} \ 9571.61Skre \ 9581.61SkreATF_TC_BODY(test, tc) \ 9591.61Skre{ \ 9601.61Skre \ 9611.61Skre traceme_sendsignal_handle(sig, test##_sighandler, & test##_caught); \ 9621.34Skamil} 9631.34Skamil 9641.34Skamil// A signal handler for SIGKILL and SIGSTOP cannot be registered. 9651.50SkamilTRACEME_SENDSIGNAL_HANDLE(traceme_sendsignal_handle1, SIGABRT) /* abort trap */ 9661.50SkamilTRACEME_SENDSIGNAL_HANDLE(traceme_sendsignal_handle2, SIGHUP) /* hangup */ 9671.50SkamilTRACEME_SENDSIGNAL_HANDLE(traceme_sendsignal_handle3, SIGCONT) /* continued? */ 9681.85SkamilTRACEME_SENDSIGNAL_HANDLE(traceme_sendsignal_handle4, SIGTRAP) /* crash sig. */ 9691.85SkamilTRACEME_SENDSIGNAL_HANDLE(traceme_sendsignal_handle5, SIGBUS) /* crash sig. */ 9701.85SkamilTRACEME_SENDSIGNAL_HANDLE(traceme_sendsignal_handle6, SIGILL) /* crash sig. */ 9711.85SkamilTRACEME_SENDSIGNAL_HANDLE(traceme_sendsignal_handle7, SIGFPE) /* crash sig. */ 9721.85SkamilTRACEME_SENDSIGNAL_HANDLE(traceme_sendsignal_handle8, SIGSEGV) /* crash sig. */ 9731.34Skamil 9741.34Skamil/// ---------------------------------------------------------------------------- 9751.34Skamil 9761.35Skamilstatic void 9771.50Skamiltraceme_sendsignal_masked(int sigsent) 9781.50Skamil{ 9791.50Skamil const int exitval = 5; 9801.50Skamil const int sigval = SIGSTOP; 9811.50Skamil pid_t child, wpid; 9821.50Skamil sigset_t set; 9831.50Skamil#if defined(TWAIT_HAVE_STATUS) 9841.50Skamil int status; 9851.50Skamil#endif 9861.61Skre struct ptrace_siginfo info; 9871.50Skamil 9881.50Skamil memset(&info, 0, sizeof(info)); 9891.50Skamil 9901.50Skamil DPRINTF("Before forking process PID=%d\n", getpid()); 9911.50Skamil SYSCALL_REQUIRE((child = fork()) != -1); 9921.50Skamil if (child == 0) { 9931.50Skamil DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 9941.50Skamil FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 9951.50Skamil 9961.50Skamil sigemptyset(&set); 9971.50Skamil sigaddset(&set, sigsent); 9981.50Skamil FORKEE_ASSERT(sigprocmask(SIG_BLOCK, &set, NULL) != -1); 9991.50Skamil 10001.50Skamil DPRINTF("Before raising %s from child\n", strsignal(sigval)); 10011.50Skamil FORKEE_ASSERT(raise(sigval) == 0); 10021.50Skamil 10031.50Skamil _exit(exitval); 10041.50Skamil } 10051.50Skamil DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 10061.50Skamil 10071.50Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 10081.50Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 10091.50Skamil 10101.50Skamil validate_status_stopped(status, sigval); 10111.50Skamil 10121.50Skamil DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 10131.61Skre SYSCALL_REQUIRE( 10141.61Skre ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 10151.50Skamil 10161.50Skamil DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 10171.50Skamil DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 10181.50Skamil info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 10191.50Skamil info.psi_siginfo.si_errno); 10201.50Skamil 10211.50Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 10221.50Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 10231.50Skamil 10241.50Skamil DPRINTF("Before resuming the child process where it left off and with " 10251.50Skamil "signal %s to be sent\n", strsignal(sigsent)); 10261.50Skamil SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigsent) != -1); 10271.50Skamil 10281.50Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 10291.50Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 10301.50Skamil 10311.50Skamil validate_status_exited(status, exitval); 10321.50Skamil 10331.50Skamil DPRINTF("Before calling %s() for the exited child\n", TWAIT_FNAME); 10341.50Skamil TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 10351.50Skamil} 10361.50Skamil 10371.61Skre#define TRACEME_SENDSIGNAL_MASKED(test, sig) \ 10381.61SkreATF_TC(test); \ 10391.61SkreATF_TC_HEAD(test, tc) \ 10401.61Skre{ \ 10411.61Skre atf_tc_set_md_var(tc, "descr", \ 10421.61Skre "Verify that a signal " #sig " emitted by a tracer to a child is " \ 10431.61Skre "handled correctly and the signal is masked by SIG_BLOCK"); \ 10441.61Skre} \ 10451.61Skre \ 10461.61SkreATF_TC_BODY(test, tc) \ 10471.61Skre{ \ 10481.61Skre \ 10491.61Skre traceme_sendsignal_masked(sig); \ 10501.50Skamil} 10511.50Skamil 10521.50Skamil// A signal handler for SIGKILL and SIGSTOP cannot be masked. 10531.50SkamilTRACEME_SENDSIGNAL_MASKED(traceme_sendsignal_masked1, SIGABRT) /* abort trap */ 10541.50SkamilTRACEME_SENDSIGNAL_MASKED(traceme_sendsignal_masked2, SIGHUP) /* hangup */ 10551.50SkamilTRACEME_SENDSIGNAL_MASKED(traceme_sendsignal_masked3, SIGCONT) /* continued? */ 10561.85SkamilTRACEME_SENDSIGNAL_MASKED(traceme_sendsignal_masked4, SIGTRAP) /* crash sig. */ 10571.85SkamilTRACEME_SENDSIGNAL_MASKED(traceme_sendsignal_masked5, SIGBUS) /* crash sig. */ 10581.85SkamilTRACEME_SENDSIGNAL_MASKED(traceme_sendsignal_masked6, SIGILL) /* crash sig. */ 10591.85SkamilTRACEME_SENDSIGNAL_MASKED(traceme_sendsignal_masked7, SIGFPE) /* crash sig. */ 10601.85SkamilTRACEME_SENDSIGNAL_MASKED(traceme_sendsignal_masked8, SIGSEGV) /* crash sig. */ 10611.50Skamil 10621.50Skamil/// ---------------------------------------------------------------------------- 10631.50Skamil 10641.50Skamilstatic void 10651.50Skamiltraceme_sendsignal_ignored(int sigsent) 10661.50Skamil{ 10671.50Skamil const int exitval = 5; 10681.50Skamil const int sigval = SIGSTOP; 10691.50Skamil pid_t child, wpid; 10701.50Skamil struct sigaction sa; 10711.50Skamil#if defined(TWAIT_HAVE_STATUS) 10721.50Skamil int status; 10731.50Skamil#endif 10741.61Skre struct ptrace_siginfo info; 10751.50Skamil 10761.50Skamil memset(&info, 0, sizeof(info)); 10771.50Skamil 10781.50Skamil DPRINTF("Before forking process PID=%d\n", getpid()); 10791.50Skamil SYSCALL_REQUIRE((child = fork()) != -1); 10801.50Skamil if (child == 0) { 10811.50Skamil DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 10821.61Skre 10831.50Skamil FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 10841.50Skamil 10851.50Skamil memset(&sa, 0, sizeof(sa)); 10861.50Skamil sa.sa_handler = SIG_IGN; 10871.50Skamil sigemptyset(&sa.sa_mask); 10881.50Skamil FORKEE_ASSERT(sigaction(sigsent, &sa, NULL) != -1); 10891.50Skamil 10901.50Skamil DPRINTF("Before raising %s from child\n", strsignal(sigval)); 10911.50Skamil FORKEE_ASSERT(raise(sigval) == 0); 10921.50Skamil 10931.50Skamil _exit(exitval); 10941.50Skamil } 10951.50Skamil DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 10961.50Skamil 10971.50Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 10981.50Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 10991.50Skamil 11001.50Skamil validate_status_stopped(status, sigval); 11011.50Skamil 11021.50Skamil DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 11031.61Skre SYSCALL_REQUIRE( 11041.61Skre ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 11051.50Skamil 11061.50Skamil DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 11071.50Skamil DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 11081.50Skamil info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 11091.50Skamil info.psi_siginfo.si_errno); 11101.50Skamil 11111.50Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 11121.50Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 11131.50Skamil 11141.50Skamil DPRINTF("Before resuming the child process where it left off and with " 11151.50Skamil "signal %s to be sent\n", strsignal(sigsent)); 11161.50Skamil SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigsent) != -1); 11171.50Skamil 11181.50Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 11191.50Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 11201.50Skamil 11211.50Skamil validate_status_exited(status, exitval); 11221.50Skamil 11231.50Skamil DPRINTF("Before calling %s() for the exited child\n", TWAIT_FNAME); 11241.50Skamil TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 11251.50Skamil} 11261.50Skamil 11271.61Skre#define TRACEME_SENDSIGNAL_IGNORED(test, sig) \ 11281.61SkreATF_TC(test); \ 11291.61SkreATF_TC_HEAD(test, tc) \ 11301.61Skre{ \ 11311.61Skre atf_tc_set_md_var(tc, "descr", \ 11321.61Skre "Verify that a signal " #sig " emitted by a tracer to a child is " \ 11331.61Skre "handled correctly and the signal is masked by SIG_IGN"); \ 11341.61Skre} \ 11351.61Skre \ 11361.61SkreATF_TC_BODY(test, tc) \ 11371.61Skre{ \ 11381.61Skre \ 11391.61Skre traceme_sendsignal_ignored(sig); \ 11401.50Skamil} 11411.50Skamil 11421.50Skamil// A signal handler for SIGKILL and SIGSTOP cannot be ignored. 11431.61SkreTRACEME_SENDSIGNAL_IGNORED(traceme_sendsignal_ignored1, SIGABRT) /* abort */ 11441.50SkamilTRACEME_SENDSIGNAL_IGNORED(traceme_sendsignal_ignored2, SIGHUP) /* hangup */ 11451.61SkreTRACEME_SENDSIGNAL_IGNORED(traceme_sendsignal_ignored3, SIGCONT) /* continued */ 11461.85SkamilTRACEME_SENDSIGNAL_IGNORED(traceme_sendsignal_ignored4, SIGTRAP) /* crash s. */ 11471.85SkamilTRACEME_SENDSIGNAL_IGNORED(traceme_sendsignal_ignored5, SIGBUS) /* crash s. */ 11481.85SkamilTRACEME_SENDSIGNAL_IGNORED(traceme_sendsignal_ignored6, SIGILL) /* crash s. */ 11491.85SkamilTRACEME_SENDSIGNAL_IGNORED(traceme_sendsignal_ignored7, SIGFPE) /* crash s. */ 11501.85SkamilTRACEME_SENDSIGNAL_IGNORED(traceme_sendsignal_ignored8, SIGSEGV) /* crash s. */ 11511.50Skamil 11521.50Skamil/// ---------------------------------------------------------------------------- 11531.50Skamil 11541.50Skamilstatic void 11551.50Skamiltraceme_sendsignal_simple(int sigsent) 11561.1Skamil{ 11571.35Skamil const int sigval = SIGSTOP; 11581.35Skamil int exitval = 0; 11591.1Skamil pid_t child, wpid; 11601.1Skamil#if defined(TWAIT_HAVE_STATUS) 11611.1Skamil int status; 11621.85Skamil int expect_core; 11631.85Skamil 11641.85Skamil switch (sigsent) { 11651.85Skamil case SIGABRT: 11661.85Skamil case SIGTRAP: 11671.85Skamil case SIGBUS: 11681.85Skamil case SIGILL: 11691.85Skamil case SIGFPE: 11701.85Skamil case SIGSEGV: 11711.85Skamil expect_core = 1; 11721.85Skamil break; 11731.85Skamil default: 11741.85Skamil expect_core = 0; 11751.85Skamil break; 11761.85Skamil } 11771.1Skamil#endif 11781.61Skre struct ptrace_siginfo info; 11791.1Skamil 11801.45Skamil memset(&info, 0, sizeof(info)); 11811.45Skamil 11821.13Schristos DPRINTF("Before forking process PID=%d\n", getpid()); 11831.13Schristos SYSCALL_REQUIRE((child = fork()) != -1); 11841.1Skamil if (child == 0) { 11851.13Schristos DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 11861.1Skamil FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 11871.1Skamil 11881.13Schristos DPRINTF("Before raising %s from child\n", strsignal(sigval)); 11891.1Skamil FORKEE_ASSERT(raise(sigval) == 0); 11901.1Skamil 11911.35Skamil switch (sigsent) { 11921.35Skamil case SIGCONT: 11931.48Skamil case SIGSTOP: 11941.35Skamil _exit(exitval); 11951.35Skamil default: 11961.35Skamil /* NOTREACHED */ 11971.35Skamil FORKEE_ASSERTX(0 && "This shall not be reached"); 11981.35Skamil } 11991.1Skamil } 12001.13Schristos DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 12011.1Skamil 12021.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 12031.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 12041.1Skamil 12051.1Skamil validate_status_stopped(status, sigval); 12061.1Skamil 12071.45Skamil DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 12081.61Skre SYSCALL_REQUIRE( 12091.61Skre ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 12101.45Skamil 12111.45Skamil DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 12121.45Skamil DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 12131.45Skamil info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 12141.45Skamil info.psi_siginfo.si_errno); 12151.45Skamil 12161.45Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 12171.45Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 12181.45Skamil 12191.13Schristos DPRINTF("Before resuming the child process where it left off and with " 12201.1Skamil "signal %s to be sent\n", strsignal(sigsent)); 12211.13Schristos SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigsent) != -1); 12221.1Skamil 12231.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 12241.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 12251.1Skamil 12261.35Skamil switch (sigsent) { 12271.48Skamil case SIGSTOP: 12281.48Skamil validate_status_stopped(status, sigsent); 12291.48Skamil DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for " 12301.61Skre "child\n"); 12311.48Skamil SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, 12321.61Skre sizeof(info)) != -1); 12331.48Skamil 12341.48Skamil DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 12351.48Skamil DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 12361.61Skre "si_errno=%#x\n", 12371.61Skre info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 12381.61Skre info.psi_siginfo.si_errno); 12391.48Skamil 12401.48Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 12411.48Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 12421.48Skamil 12431.48Skamil DPRINTF("Before resuming the child process where it left off " 12441.61Skre "and with signal %s to be sent\n", strsignal(sigsent)); 12451.48Skamil SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 12461.48Skamil 12471.48Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 12481.48Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), 12491.61Skre child); 12501.48Skamil /* FALLTHROUGH */ 12511.35Skamil case SIGCONT: 12521.35Skamil validate_status_exited(status, exitval); 12531.35Skamil break; 12541.35Skamil default: 12551.35Skamil validate_status_signaled(status, sigsent, expect_core); 12561.35Skamil break; 12571.35Skamil } 12581.1Skamil 12591.13Schristos DPRINTF("Before calling %s() for the exited child\n", TWAIT_FNAME); 12601.1Skamil TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 12611.1Skamil} 12621.1Skamil 12631.61Skre#define TRACEME_SENDSIGNAL_SIMPLE(test, sig) \ 12641.61SkreATF_TC(test); \ 12651.61SkreATF_TC_HEAD(test, tc) \ 12661.61Skre{ \ 12671.61Skre atf_tc_set_md_var(tc, "descr", \ 12681.61Skre "Verify that a signal " #sig " emitted by a tracer to a child is " \ 12691.61Skre "handled correctly in a child without a signal handler"); \ 12701.61Skre} \ 12711.61Skre \ 12721.61SkreATF_TC_BODY(test, tc) \ 12731.61Skre{ \ 12741.61Skre \ 12751.61Skre traceme_sendsignal_simple(sig); \ 12761.35Skamil} 12771.35Skamil 12781.61SkreTRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple1, SIGKILL) /* non-maskable*/ 12791.61SkreTRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple2, SIGSTOP) /* non-maskable*/ 12801.50SkamilTRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple3, SIGABRT) /* abort trap */ 12811.50SkamilTRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple4, SIGHUP) /* hangup */ 12821.50SkamilTRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple5, SIGCONT) /* continued? */ 12831.85SkamilTRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple6, SIGTRAP) /* crash sig. */ 12841.85SkamilTRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple7, SIGBUS) /* crash sig. */ 12851.85SkamilTRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple8, SIGILL) /* crash sig. */ 12861.85SkamilTRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple9, SIGFPE) /* crash sig. */ 12871.85SkamilTRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple10, SIGSEGV) /* crash sig. */ 12881.35Skamil 12891.35Skamil/// ---------------------------------------------------------------------------- 12901.35Skamil 12911.37SkamilATF_TC(traceme_pid1_parent); 12921.37SkamilATF_TC_HEAD(traceme_pid1_parent, tc) 12931.37Skamil{ 12941.37Skamil atf_tc_set_md_var(tc, "descr", 12951.37Skamil "Verify that PT_TRACE_ME is not allowed when our parent is PID1"); 12961.37Skamil} 12971.37Skamil 12981.37SkamilATF_TC_BODY(traceme_pid1_parent, tc) 12991.37Skamil{ 13001.37Skamil struct msg_fds parent_child; 13011.37Skamil int exitval_child1 = 1, exitval_child2 = 2; 13021.37Skamil pid_t child1, child2, wpid; 13031.37Skamil uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */ 13041.37Skamil#if defined(TWAIT_HAVE_STATUS) 13051.37Skamil int status; 13061.37Skamil#endif 13071.37Skamil 13081.37Skamil SYSCALL_REQUIRE(msg_open(&parent_child) == 0); 13091.37Skamil 13101.37Skamil DPRINTF("Before forking process PID=%d\n", getpid()); 13111.37Skamil SYSCALL_REQUIRE((child1 = fork()) != -1); 13121.37Skamil if (child1 == 0) { 13131.37Skamil DPRINTF("Before forking process PID=%d\n", getpid()); 13141.37Skamil SYSCALL_REQUIRE((child2 = fork()) != -1); 13151.37Skamil if (child2 != 0) { 13161.37Skamil DPRINTF("Parent process PID=%d, child2's PID=%d\n", 13171.61Skre getpid(), child2); 13181.37Skamil _exit(exitval_child1); 13191.37Skamil } 13201.37Skamil CHILD_FROM_PARENT("exit child1", parent_child, msg); 13211.37Skamil 13221.37Skamil DPRINTF("Assert that our parent is PID1 (initproc)\n"); 13231.37Skamil FORKEE_ASSERT_EQ(getppid(), 1); 13241.37Skamil 13251.37Skamil DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 13261.37Skamil FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) == -1); 13271.37Skamil SYSCALL_REQUIRE_ERRNO(errno, EPERM); 13281.37Skamil 13291.37Skamil CHILD_TO_PARENT("child2 exiting", parent_child, msg); 13301.37Skamil 13311.37Skamil _exit(exitval_child2); 13321.37Skamil } 13331.37Skamil DPRINTF("Parent process PID=%d, child1's PID=%d\n", getpid(), child1); 13341.37Skamil 13351.37Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 13361.61Skre TWAIT_REQUIRE_SUCCESS( 13371.61Skre wpid = TWAIT_GENERIC(child1, &status, WEXITED), child1); 13381.37Skamil 13391.37Skamil validate_status_exited(status, exitval_child1); 13401.37Skamil 13411.37Skamil DPRINTF("Notify that child1 is dead\n"); 13421.37Skamil PARENT_TO_CHILD("exit child1", parent_child, msg); 13431.37Skamil 13441.37Skamil DPRINTF("Wait for exiting of child2\n"); 13451.37Skamil PARENT_FROM_CHILD("child2 exiting", parent_child, msg); 13461.37Skamil} 13471.37Skamil 13481.37Skamil/// ---------------------------------------------------------------------------- 13491.37Skamil 13501.40Skamilstatic void 13511.40Skamiltraceme_vfork_raise(int sigval) 13521.40Skamil{ 13531.46Skamil const int exitval = 5, exitval_watcher = 10; 13541.46Skamil pid_t child, parent, watcher, wpid; 13551.46Skamil int rv; 13561.40Skamil#if defined(TWAIT_HAVE_STATUS) 13571.40Skamil int status; 13581.85Skamil 13591.85Skamil /* volatile workarounds GCC -Werror=clobbered */ 13601.85Skamil volatile int expect_core; 13611.85Skamil 13621.85Skamil switch (sigval) { 13631.85Skamil case SIGABRT: 13641.85Skamil case SIGTRAP: 13651.85Skamil case SIGBUS: 13661.85Skamil case SIGILL: 13671.85Skamil case SIGFPE: 13681.85Skamil case SIGSEGV: 13691.85Skamil expect_core = 1; 13701.85Skamil break; 13711.85Skamil default: 13721.85Skamil expect_core = 0; 13731.85Skamil break; 13741.85Skamil } 13751.40Skamil#endif 13761.40Skamil 13771.46Skamil /* 13781.46Skamil * Spawn a dedicated thread to watch for a stopped child and emit 13791.46Skamil * the SIGKILL signal to it. 13801.46Skamil * 13811.46Skamil * vfork(2) might clobber watcher, this means that it's safer and 13821.46Skamil * simpler to reparent this process to initproc and forget about it. 13831.46Skamil */ 13841.46Skamil if (sigval == SIGSTOP) { 13851.46Skamil parent = getpid(); 13861.46Skamil 13871.46Skamil watcher = fork(); 13881.46Skamil ATF_REQUIRE(watcher != 1); 13891.46Skamil if (watcher == 0) { 13901.46Skamil /* Double fork(2) trick to reparent to initproc */ 13911.46Skamil watcher = fork(); 13921.46Skamil FORKEE_ASSERT_NEQ(watcher, -1); 13931.46Skamil if (watcher != 0) 13941.46Skamil _exit(exitval_watcher); 13951.46Skamil 13961.46Skamil child = await_stopped_child(parent); 13971.46Skamil 13981.46Skamil errno = 0; 13991.46Skamil rv = kill(child, SIGKILL); 14001.46Skamil FORKEE_ASSERT_EQ(rv, 0); 14011.46Skamil FORKEE_ASSERT_EQ(errno, 0); 14021.46Skamil 14031.46Skamil /* This exit value will be collected by initproc */ 14041.46Skamil _exit(0); 14051.46Skamil } 14061.46Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 14071.46Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(watcher, &status, 0), 14081.61Skre watcher); 14091.46Skamil 14101.46Skamil validate_status_exited(status, exitval_watcher); 14111.46Skamil 14121.46Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 14131.61Skre TWAIT_REQUIRE_FAILURE(ECHILD, 14141.61Skre wpid = TWAIT_GENERIC(watcher, &status, 0)); 14151.46Skamil } 14161.46Skamil 14171.40Skamil DPRINTF("Before forking process PID=%d\n", getpid()); 14181.40Skamil SYSCALL_REQUIRE((child = vfork()) != -1); 14191.40Skamil if (child == 0) { 14201.40Skamil DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 14211.40Skamil FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 14221.40Skamil 14231.40Skamil DPRINTF("Before raising %s from child\n", strsignal(sigval)); 14241.40Skamil FORKEE_ASSERT(raise(sigval) == 0); 14251.40Skamil 14261.40Skamil switch (sigval) { 14271.46Skamil case SIGSTOP: 14281.40Skamil case SIGKILL: 14291.40Skamil case SIGABRT: 14301.40Skamil case SIGHUP: 14311.85Skamil case SIGTRAP: 14321.85Skamil case SIGBUS: 14331.85Skamil case SIGILL: 14341.85Skamil case SIGFPE: 14351.85Skamil case SIGSEGV: 14361.40Skamil /* NOTREACHED */ 14371.40Skamil FORKEE_ASSERTX(0 && "This shall not be reached"); 14381.70Smrg __unreachable(); 14391.40Skamil default: 14401.40Skamil DPRINTF("Before exiting of the child process\n"); 14411.40Skamil _exit(exitval); 14421.40Skamil } 14431.40Skamil } 14441.40Skamil DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 14451.40Skamil 14461.40Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 14471.40Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 14481.40Skamil 14491.40Skamil switch (sigval) { 14501.40Skamil case SIGKILL: 14511.40Skamil case SIGABRT: 14521.40Skamil case SIGHUP: 14531.85Skamil case SIGTRAP: 14541.85Skamil case SIGBUS: 14551.85Skamil case SIGILL: 14561.85Skamil case SIGFPE: 14571.85Skamil case SIGSEGV: 14581.40Skamil validate_status_signaled(status, sigval, expect_core); 14591.40Skamil break; 14601.40Skamil case SIGSTOP: 14611.46Skamil validate_status_signaled(status, SIGKILL, 0); 14621.46Skamil break; 14631.40Skamil case SIGCONT: 14641.47Skamil case SIGTSTP: 14651.47Skamil case SIGTTIN: 14661.47Skamil case SIGTTOU: 14671.40Skamil validate_status_exited(status, exitval); 14681.40Skamil break; 14691.40Skamil default: 14701.40Skamil /* NOTREACHED */ 14711.40Skamil ATF_REQUIRE(0 && "NOT IMPLEMENTED"); 14721.40Skamil break; 14731.40Skamil } 14741.40Skamil 14751.40Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 14761.40Skamil TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 14771.40Skamil} 14781.40Skamil 14791.61Skre#define TRACEME_VFORK_RAISE(test, sig) \ 14801.61SkreATF_TC(test); \ 14811.61SkreATF_TC_HEAD(test, tc) \ 14821.61Skre{ \ 14831.61Skre atf_tc_set_md_var(tc, "descr", \ 14841.61Skre "Verify PT_TRACE_ME followed by raise of " #sig " in a " \ 14851.61Skre "vfork(2)ed child"); \ 14861.61Skre} \ 14871.61Skre \ 14881.61SkreATF_TC_BODY(test, tc) \ 14891.61Skre{ \ 14901.61Skre \ 14911.61Skre traceme_vfork_raise(sig); \ 14921.40Skamil} 14931.40Skamil 14941.40SkamilTRACEME_VFORK_RAISE(traceme_vfork_raise1, SIGKILL) /* non-maskable */ 14951.46SkamilTRACEME_VFORK_RAISE(traceme_vfork_raise2, SIGSTOP) /* non-maskable */ 14961.47SkamilTRACEME_VFORK_RAISE(traceme_vfork_raise3, SIGTSTP) /* ignored in vfork(2) */ 14971.47SkamilTRACEME_VFORK_RAISE(traceme_vfork_raise4, SIGTTIN) /* ignored in vfork(2) */ 14981.47SkamilTRACEME_VFORK_RAISE(traceme_vfork_raise5, SIGTTOU) /* ignored in vfork(2) */ 14991.47SkamilTRACEME_VFORK_RAISE(traceme_vfork_raise6, SIGABRT) /* regular abort trap */ 15001.47SkamilTRACEME_VFORK_RAISE(traceme_vfork_raise7, SIGHUP) /* hangup */ 15011.47SkamilTRACEME_VFORK_RAISE(traceme_vfork_raise8, SIGCONT) /* continued? */ 15021.85SkamilTRACEME_VFORK_RAISE(traceme_vfork_raise9, SIGTRAP) /* crash signal */ 15031.85SkamilTRACEME_VFORK_RAISE(traceme_vfork_raise10, SIGBUS) /* crash signal */ 15041.85SkamilTRACEME_VFORK_RAISE(traceme_vfork_raise11, SIGILL) /* crash signal */ 15051.85SkamilTRACEME_VFORK_RAISE(traceme_vfork_raise12, SIGFPE) /* crash signal */ 15061.85SkamilTRACEME_VFORK_RAISE(traceme_vfork_raise13, SIGSEGV) /* crash signal */ 15071.40Skamil 15081.40Skamil/// ---------------------------------------------------------------------------- 15091.40Skamil 15101.52Skamilstatic void 15111.52Skamiltraceme_vfork_crash(int sig) 15121.41Skamil{ 15131.41Skamil pid_t child, wpid; 15141.41Skamil#if defined(TWAIT_HAVE_STATUS) 15151.41Skamil int status; 15161.41Skamil#endif 15171.41Skamil 15181.71Skamil#ifndef PTRACE_ILLEGAL_ASM 15191.71Skamil if (sig == SIGILL) 15201.71Skamil atf_tc_skip("PTRACE_ILLEGAL_ASM not defined"); 15211.71Skamil#endif 15221.71Skamil 15231.41Skamil DPRINTF("Before forking process PID=%d\n", getpid()); 15241.41Skamil SYSCALL_REQUIRE((child = vfork()) != -1); 15251.41Skamil if (child == 0) { 15261.41Skamil DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 15271.41Skamil FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 15281.41Skamil 15291.52Skamil DPRINTF("Before executing a trap\n"); 15301.52Skamil switch (sig) { 15311.52Skamil case SIGTRAP: 15321.52Skamil trigger_trap(); 15331.52Skamil break; 15341.52Skamil case SIGSEGV: 15351.52Skamil trigger_segv(); 15361.52Skamil break; 15371.52Skamil case SIGILL: 15381.52Skamil trigger_ill(); 15391.52Skamil break; 15401.52Skamil case SIGFPE: 15411.52Skamil trigger_fpe(); 15421.52Skamil break; 15431.52Skamil case SIGBUS: 15441.52Skamil trigger_bus(); 15451.52Skamil break; 15461.52Skamil default: 15471.52Skamil /* NOTREACHED */ 15481.52Skamil FORKEE_ASSERTX(0 && "This shall not be reached"); 15491.52Skamil } 15501.41Skamil 15511.41Skamil /* NOTREACHED */ 15521.41Skamil FORKEE_ASSERTX(0 && "This shall not be reached"); 15531.41Skamil } 15541.41Skamil DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 15551.41Skamil 15561.41Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 15571.41Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 15581.41Skamil 15591.52Skamil validate_status_signaled(status, sig, 1); 15601.41Skamil 15611.41Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 15621.41Skamil TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 15631.41Skamil} 15641.41Skamil 15651.61Skre#define TRACEME_VFORK_CRASH(test, sig) \ 15661.61SkreATF_TC(test); \ 15671.61SkreATF_TC_HEAD(test, tc) \ 15681.61Skre{ \ 15691.61Skre atf_tc_set_md_var(tc, "descr", \ 15701.61Skre "Verify PT_TRACE_ME followed by a crash signal " #sig " in a " \ 15711.61Skre "vfork(2)ed child"); \ 15721.61Skre} \ 15731.61Skre \ 15741.61SkreATF_TC_BODY(test, tc) \ 15751.61Skre{ \ 15761.61Skre \ 15771.61Skre traceme_vfork_crash(sig); \ 15781.52Skamil} 15791.52Skamil 15801.52SkamilTRACEME_VFORK_CRASH(traceme_vfork_crash_trap, SIGTRAP) 15811.52SkamilTRACEME_VFORK_CRASH(traceme_vfork_crash_segv, SIGSEGV) 15821.71SkamilTRACEME_VFORK_CRASH(traceme_vfork_crash_ill, SIGILL) 15831.52SkamilTRACEME_VFORK_CRASH(traceme_vfork_crash_fpe, SIGFPE) 15841.52SkamilTRACEME_VFORK_CRASH(traceme_vfork_crash_bus, SIGBUS) 15851.52Skamil 15861.41Skamil/// ---------------------------------------------------------------------------- 15871.41Skamil 15881.92Skamilstatic void 15891.92Skamiltraceme_vfork_signalmasked_crash(int sig) 15901.92Skamil{ 15911.92Skamil pid_t child, wpid; 15921.92Skamil#if defined(TWAIT_HAVE_STATUS) 15931.92Skamil int status; 15941.92Skamil#endif 15951.92Skamil sigset_t intmask; 15961.92Skamil 15971.92Skamil#ifndef PTRACE_ILLEGAL_ASM 15981.92Skamil if (sig == SIGILL) 15991.92Skamil atf_tc_skip("PTRACE_ILLEGAL_ASM not defined"); 16001.92Skamil#endif 16011.92Skamil 16021.92Skamil DPRINTF("Before forking process PID=%d\n", getpid()); 16031.92Skamil SYSCALL_REQUIRE((child = vfork()) != -1); 16041.92Skamil if (child == 0) { 16051.92Skamil DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 16061.92Skamil FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 16071.92Skamil 16081.92Skamil sigemptyset(&intmask); 16091.92Skamil sigaddset(&intmask, sig); 16101.92Skamil sigprocmask(SIG_BLOCK, &intmask, NULL); 16111.92Skamil 16121.92Skamil DPRINTF("Before executing a trap\n"); 16131.92Skamil switch (sig) { 16141.92Skamil case SIGTRAP: 16151.92Skamil trigger_trap(); 16161.92Skamil break; 16171.92Skamil case SIGSEGV: 16181.92Skamil trigger_segv(); 16191.92Skamil break; 16201.92Skamil case SIGILL: 16211.92Skamil trigger_ill(); 16221.92Skamil break; 16231.92Skamil case SIGFPE: 16241.92Skamil trigger_fpe(); 16251.92Skamil break; 16261.92Skamil case SIGBUS: 16271.92Skamil trigger_bus(); 16281.92Skamil break; 16291.92Skamil default: 16301.92Skamil /* NOTREACHED */ 16311.92Skamil FORKEE_ASSERTX(0 && "This shall not be reached"); 16321.92Skamil } 16331.92Skamil 16341.92Skamil /* NOTREACHED */ 16351.92Skamil FORKEE_ASSERTX(0 && "This shall not be reached"); 16361.92Skamil } 16371.92Skamil DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 16381.92Skamil 16391.92Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 16401.92Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 16411.92Skamil 16421.92Skamil validate_status_signaled(status, sig, 1); 16431.92Skamil 16441.92Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 16451.92Skamil TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 16461.92Skamil} 16471.92Skamil 16481.92Skamil#define TRACEME_VFORK_SIGNALMASKED_CRASH(test, sig) \ 16491.92SkamilATF_TC(test); \ 16501.92SkamilATF_TC_HEAD(test, tc) \ 16511.92Skamil{ \ 16521.92Skamil atf_tc_set_md_var(tc, "descr", \ 16531.92Skamil "Verify PT_TRACE_ME followed by a crash signal " #sig " in a " \ 16541.92Skamil "vfork(2)ed child with a masked signal"); \ 16551.92Skamil} \ 16561.92Skamil \ 16571.92SkamilATF_TC_BODY(test, tc) \ 16581.92Skamil{ \ 16591.92Skamil \ 16601.92Skamil traceme_vfork_signalmasked_crash(sig); \ 16611.92Skamil} 16621.92Skamil 16631.92SkamilTRACEME_VFORK_SIGNALMASKED_CRASH(traceme_vfork_signalmasked_crash_trap, SIGTRAP) 16641.92SkamilTRACEME_VFORK_SIGNALMASKED_CRASH(traceme_vfork_signalmasked_crash_segv, SIGSEGV) 16651.92SkamilTRACEME_VFORK_SIGNALMASKED_CRASH(traceme_vfork_signalmasked_crash_ill, SIGILL) 16661.92SkamilTRACEME_VFORK_SIGNALMASKED_CRASH(traceme_vfork_signalmasked_crash_fpe, SIGFPE) 16671.92SkamilTRACEME_VFORK_SIGNALMASKED_CRASH(traceme_vfork_signalmasked_crash_bus, SIGBUS) 16681.92Skamil 16691.92Skamil/// ---------------------------------------------------------------------------- 16701.92Skamil 16711.92Skamilstatic void 16721.92Skamiltraceme_vfork_signalignored_crash(int sig) 16731.92Skamil{ 16741.92Skamil pid_t child, wpid; 16751.92Skamil#if defined(TWAIT_HAVE_STATUS) 16761.92Skamil int status; 16771.92Skamil#endif 16781.92Skamil struct sigaction sa; 16791.92Skamil 16801.92Skamil#ifndef PTRACE_ILLEGAL_ASM 16811.92Skamil if (sig == SIGILL) 16821.92Skamil atf_tc_skip("PTRACE_ILLEGAL_ASM not defined"); 16831.92Skamil#endif 16841.92Skamil 16851.92Skamil DPRINTF("Before forking process PID=%d\n", getpid()); 16861.92Skamil SYSCALL_REQUIRE((child = vfork()) != -1); 16871.92Skamil if (child == 0) { 16881.92Skamil DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 16891.92Skamil FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 16901.92Skamil 16911.92Skamil memset(&sa, 0, sizeof(sa)); 16921.92Skamil sa.sa_handler = SIG_IGN; 16931.92Skamil sigemptyset(&sa.sa_mask); 16941.92Skamil 16951.92Skamil FORKEE_ASSERT(sigaction(sig, &sa, NULL) != -1); 16961.92Skamil 16971.92Skamil DPRINTF("Before executing a trap\n"); 16981.92Skamil switch (sig) { 16991.92Skamil case SIGTRAP: 17001.92Skamil trigger_trap(); 17011.92Skamil break; 17021.92Skamil case SIGSEGV: 17031.92Skamil trigger_segv(); 17041.92Skamil break; 17051.92Skamil case SIGILL: 17061.92Skamil trigger_ill(); 17071.92Skamil break; 17081.92Skamil case SIGFPE: 17091.92Skamil trigger_fpe(); 17101.92Skamil break; 17111.92Skamil case SIGBUS: 17121.92Skamil trigger_bus(); 17131.92Skamil break; 17141.92Skamil default: 17151.92Skamil /* NOTREACHED */ 17161.92Skamil FORKEE_ASSERTX(0 && "This shall not be reached"); 17171.92Skamil } 17181.92Skamil 17191.92Skamil /* NOTREACHED */ 17201.92Skamil FORKEE_ASSERTX(0 && "This shall not be reached"); 17211.92Skamil } 17221.92Skamil DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 17231.92Skamil 17241.92Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 17251.92Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 17261.92Skamil 17271.92Skamil validate_status_signaled(status, sig, 1); 17281.92Skamil 17291.92Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 17301.92Skamil TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 17311.92Skamil} 17321.92Skamil 17331.92Skamil#define TRACEME_VFORK_SIGNALIGNORED_CRASH(test, sig) \ 17341.92SkamilATF_TC(test); \ 17351.92SkamilATF_TC_HEAD(test, tc) \ 17361.92Skamil{ \ 17371.92Skamil atf_tc_set_md_var(tc, "descr", \ 17381.92Skamil "Verify PT_TRACE_ME followed by a crash signal " #sig " in a " \ 17391.92Skamil "vfork(2)ed child with ignored signal"); \ 17401.92Skamil} \ 17411.92Skamil \ 17421.92SkamilATF_TC_BODY(test, tc) \ 17431.92Skamil{ \ 17441.92Skamil \ 17451.92Skamil traceme_vfork_signalignored_crash(sig); \ 17461.92Skamil} 17471.92Skamil 17481.92SkamilTRACEME_VFORK_SIGNALIGNORED_CRASH(traceme_vfork_signalignored_crash_trap, 17491.92Skamil SIGTRAP) 17501.92SkamilTRACEME_VFORK_SIGNALIGNORED_CRASH(traceme_vfork_signalignored_crash_segv, 17511.92Skamil SIGSEGV) 17521.92SkamilTRACEME_VFORK_SIGNALIGNORED_CRASH(traceme_vfork_signalignored_crash_ill, 17531.92Skamil SIGILL) 17541.92SkamilTRACEME_VFORK_SIGNALIGNORED_CRASH(traceme_vfork_signalignored_crash_fpe, 17551.92Skamil SIGFPE) 17561.92SkamilTRACEME_VFORK_SIGNALIGNORED_CRASH(traceme_vfork_signalignored_crash_bus, 17571.92Skamil SIGBUS) 17581.92Skamil 17591.92Skamil/// ---------------------------------------------------------------------------- 17601.92Skamil 17611.43SkamilATF_TC(traceme_vfork_exec); 17621.43SkamilATF_TC_HEAD(traceme_vfork_exec, tc) 17631.43Skamil{ 17641.43Skamil atf_tc_set_md_var(tc, "descr", 17651.43Skamil "Verify PT_TRACE_ME followed by exec(3) in a vfork(2)ed child"); 17661.43Skamil} 17671.43Skamil 17681.43SkamilATF_TC_BODY(traceme_vfork_exec, tc) 17691.43Skamil{ 17701.43Skamil const int sigval = SIGTRAP; 17711.43Skamil pid_t child, wpid; 17721.43Skamil#if defined(TWAIT_HAVE_STATUS) 17731.43Skamil int status; 17741.43Skamil#endif 17751.61Skre struct ptrace_siginfo info; 17761.43Skamil 17771.43Skamil memset(&info, 0, sizeof(info)); 17781.43Skamil 17791.43Skamil DPRINTF("Before forking process PID=%d\n", getpid()); 17801.43Skamil SYSCALL_REQUIRE((child = vfork()) != -1); 17811.43Skamil if (child == 0) { 17821.43Skamil DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 17831.43Skamil FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 17841.43Skamil 17851.43Skamil DPRINTF("Before calling execve(2) from child\n"); 17861.43Skamil execlp("/bin/echo", "/bin/echo", NULL); 17871.43Skamil 17881.43Skamil /* NOTREACHED */ 17891.43Skamil FORKEE_ASSERTX(0 && "Not reached"); 17901.43Skamil } 17911.43Skamil DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 17921.43Skamil 17931.43Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 17941.43Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 17951.43Skamil 17961.43Skamil validate_status_stopped(status, sigval); 17971.43Skamil 17981.43Skamil DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 17991.61Skre SYSCALL_REQUIRE( 18001.61Skre ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 18011.43Skamil 18021.43Skamil DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 18031.43Skamil DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 18041.43Skamil info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 18051.43Skamil info.psi_siginfo.si_errno); 18061.43Skamil 18071.43Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 18081.43Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_EXEC); 18091.43Skamil 18101.43Skamil DPRINTF("Before resuming the child process where it left off and " 18111.43Skamil "without signal to be sent\n"); 18121.43Skamil SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 18131.43Skamil 18141.43Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 18151.43Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 18161.43Skamil 18171.43Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 18181.43Skamil TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 18191.43Skamil} 18201.43Skamil 18211.43Skamil/// ---------------------------------------------------------------------------- 18221.43Skamil 18231.1Skamil#if defined(TWAIT_HAVE_PID) 18241.51Skamilstatic void 18251.59Skamilunrelated_tracer_sees_crash(int sig) 18261.59Skamil{ 18271.59Skamil struct msg_fds parent_tracee, parent_tracer; 18281.59Skamil const int exitval = 10; 18291.59Skamil pid_t tracee, tracer, wpid; 18301.59Skamil uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */ 18311.59Skamil#if defined(TWAIT_HAVE_STATUS) 18321.59Skamil int status; 18331.59Skamil#endif 18341.59Skamil struct ptrace_siginfo info; 18351.61Skre 18361.71Skamil#ifndef PTRACE_ILLEGAL_ASM 18371.71Skamil if (sig == SIGILL) 18381.71Skamil atf_tc_skip("PTRACE_ILLEGAL_ASM not defined"); 18391.71Skamil#endif 18401.71Skamil 18411.59Skamil memset(&info, 0, sizeof(info)); 18421.59Skamil 18431.59Skamil DPRINTF("Spawn tracee\n"); 18441.59Skamil SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0); 18451.59Skamil tracee = atf_utils_fork(); 18461.59Skamil if (tracee == 0) { 18471.59Skamil // Wait for parent to let us crash 18481.59Skamil CHILD_FROM_PARENT("exit tracee", parent_tracee, msg); 18491.61Skre 18501.59Skamil DPRINTF("Before executing a trap\n"); 18511.59Skamil switch (sig) { 18521.59Skamil case SIGTRAP: 18531.59Skamil trigger_trap(); 18541.59Skamil break; 18551.59Skamil case SIGSEGV: 18561.59Skamil trigger_segv(); 18571.59Skamil break; 18581.59Skamil case SIGILL: 18591.59Skamil trigger_ill(); 18601.59Skamil break; 18611.59Skamil case SIGFPE: 18621.59Skamil trigger_fpe(); 18631.59Skamil break; 18641.59Skamil case SIGBUS: 18651.59Skamil trigger_bus(); 18661.59Skamil break; 18671.59Skamil default: 18681.59Skamil /* NOTREACHED */ 18691.59Skamil FORKEE_ASSERTX(0 && "This shall not be reached"); 18701.59Skamil } 18711.59Skamil 18721.59Skamil /* NOTREACHED */ 18731.59Skamil FORKEE_ASSERTX(0 && "This shall not be reached"); 18741.59Skamil } 18751.59Skamil 18761.59Skamil DPRINTF("Spawn debugger\n"); 18771.59Skamil SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0); 18781.59Skamil tracer = atf_utils_fork(); 18791.59Skamil if (tracer == 0) { 18801.59Skamil /* Fork again and drop parent to reattach to PID 1 */ 18811.59Skamil tracer = atf_utils_fork(); 18821.59Skamil if (tracer != 0) 18831.61Skre _exit(exitval); 18841.59Skamil 18851.59Skamil DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid()); 18861.59Skamil FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1); 18871.59Skamil 18881.59Skamil /* Wait for tracee and assert that it was stopped w/ SIGSTOP */ 18891.59Skamil FORKEE_REQUIRE_SUCCESS( 18901.59Skamil wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 18911.59Skamil 18921.59Skamil forkee_status_stopped(status, SIGSTOP); 18931.59Skamil 18941.59Skamil /* Resume tracee with PT_CONTINUE */ 18951.59Skamil FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1); 18961.59Skamil 18971.59Skamil /* Inform parent that tracer has attached to tracee */ 18981.59Skamil CHILD_TO_PARENT("tracer ready", parent_tracer, msg); 18991.59Skamil 19001.59Skamil /* Wait for parent to tell use that tracee should have exited */ 19011.59Skamil CHILD_FROM_PARENT("wait for tracee exit", parent_tracer, msg); 19021.59Skamil 19031.59Skamil /* Wait for tracee and assert that it exited */ 19041.59Skamil FORKEE_REQUIRE_SUCCESS( 19051.59Skamil wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 19061.59Skamil 19071.59Skamil validate_status_stopped(status, sig); 19081.59Skamil 19091.59Skamil DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for the " 19101.61Skre "traced process\n"); 19111.61Skre SYSCALL_REQUIRE( 19121.61Skre ptrace(PT_GET_SIGINFO, tracee, &info, sizeof(info)) != -1); 19131.59Skamil 19141.59Skamil DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 19151.59Skamil DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 19161.61Skre "si_errno=%#x\n", info.psi_siginfo.si_signo, 19171.61Skre info.psi_siginfo.si_code, info.psi_siginfo.si_errno); 19181.59Skamil 19191.59Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sig); 19201.59Skamil switch (sig) { 19211.59Skamil case SIGTRAP: 19221.59Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_BRKPT); 19231.59Skamil break; 19241.59Skamil case SIGSEGV: 19251.59Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SEGV_MAPERR); 19261.59Skamil break; 19271.71Skamil case SIGILL: 19281.71Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_code, ILL_PRVOPC); 19291.71Skamil break; 19301.59Skamil case SIGFPE: 19311.59Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_code, FPE_INTDIV); 19321.59Skamil break; 19331.59Skamil case SIGBUS: 19341.59Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_code, BUS_ADRERR); 19351.59Skamil break; 19361.59Skamil } 19371.59Skamil 19381.59Skamil FORKEE_ASSERT(ptrace(PT_KILL, tracee, NULL, 0) != -1); 19391.59Skamil DPRINTF("Before calling %s() for the tracee\n", TWAIT_FNAME); 19401.61Skre TWAIT_REQUIRE_SUCCESS( 19411.61Skre wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 19421.59Skamil 19431.59Skamil validate_status_signaled(status, SIGKILL, 0); 19441.59Skamil 19451.59Skamil DPRINTF("Before calling %s() for tracee\n", TWAIT_FNAME); 19461.59Skamil TWAIT_REQUIRE_FAILURE(ECHILD, 19471.59Skamil wpid = TWAIT_GENERIC(tracee, &status, 0)); 19481.59Skamil 19491.71Skamil /* Inform parent that tracer is exiting normally */ 19501.71Skamil CHILD_TO_PARENT("tracer done", parent_tracer, msg); 19511.71Skamil 19521.59Skamil DPRINTF("Before exiting of the tracer process\n"); 19531.59Skamil _exit(0 /* collect by initproc */); 19541.59Skamil } 19551.59Skamil 19561.59Skamil DPRINTF("Wait for the tracer process (direct child) to exit " 19571.59Skamil "calling %s()\n", TWAIT_FNAME); 19581.59Skamil TWAIT_REQUIRE_SUCCESS( 19591.59Skamil wpid = TWAIT_GENERIC(tracer, &status, 0), tracer); 19601.59Skamil 19611.59Skamil validate_status_exited(status, exitval); 19621.59Skamil 19631.59Skamil DPRINTF("Wait for the non-exited tracee process with %s()\n", 19641.59Skamil TWAIT_FNAME); 19651.59Skamil TWAIT_REQUIRE_SUCCESS( 19661.59Skamil wpid = TWAIT_GENERIC(tracee, NULL, WNOHANG), 0); 19671.59Skamil 19681.59Skamil DPRINTF("Wait for the tracer to attach to the tracee\n"); 19691.59Skamil PARENT_FROM_CHILD("tracer ready", parent_tracer, msg); 19701.59Skamil 19711.59Skamil DPRINTF("Resume the tracee and let it crash\n"); 19721.59Skamil PARENT_TO_CHILD("exit tracee", parent_tracee, msg); 19731.59Skamil 19741.59Skamil DPRINTF("Resume the tracer and let it detect crashed tracee\n"); 19751.59Skamil PARENT_TO_CHILD("Message 2", parent_tracer, msg); 19761.59Skamil 19771.59Skamil DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n", 19781.59Skamil TWAIT_FNAME); 19791.59Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 19801.59Skamil 19811.59Skamil validate_status_signaled(status, SIGKILL, 0); 19821.59Skamil 19831.71Skamil DPRINTF("Await normal exit of tracer\n"); 19841.71Skamil PARENT_FROM_CHILD("tracer done", parent_tracer, msg); 19851.71Skamil 19861.59Skamil msg_close(&parent_tracer); 19871.59Skamil msg_close(&parent_tracee); 19881.59Skamil} 19891.59Skamil 19901.61Skre#define UNRELATED_TRACER_SEES_CRASH(test, sig) \ 19911.61SkreATF_TC(test); \ 19921.61SkreATF_TC_HEAD(test, tc) \ 19931.61Skre{ \ 19941.61Skre atf_tc_set_md_var(tc, "descr", \ 19951.61Skre "Assert that an unrelated tracer sees crash signal from the " \ 19961.61Skre "debuggee"); \ 19971.61Skre} \ 19981.61Skre \ 19991.61SkreATF_TC_BODY(test, tc) \ 20001.61Skre{ \ 20011.61Skre \ 20021.61Skre unrelated_tracer_sees_crash(sig); \ 20031.59Skamil} 20041.59Skamil 20051.59SkamilUNRELATED_TRACER_SEES_CRASH(unrelated_tracer_sees_crash_trap, SIGTRAP) 20061.59SkamilUNRELATED_TRACER_SEES_CRASH(unrelated_tracer_sees_crash_segv, SIGSEGV) 20071.71SkamilUNRELATED_TRACER_SEES_CRASH(unrelated_tracer_sees_crash_ill, SIGILL) 20081.59SkamilUNRELATED_TRACER_SEES_CRASH(unrelated_tracer_sees_crash_fpe, SIGFPE) 20091.59SkamilUNRELATED_TRACER_SEES_CRASH(unrelated_tracer_sees_crash_bus, SIGBUS) 20101.59Skamil#endif 20111.59Skamil 20121.59Skamil/// ---------------------------------------------------------------------------- 20131.59Skamil 20141.59Skamil#if defined(TWAIT_HAVE_PID) 20151.59Skamilstatic void 20161.67Skamiltracer_sees_terminaton_before_the_parent_raw(bool notimeout, bool unrelated, 20171.67Skamil bool stopped) 20181.1Skamil{ 20191.51Skamil /* 20201.51Skamil * notimeout - disable timeout in await zombie function 20211.51Skamil * unrelated - attach from unrelated tracer reparented to initproc 20221.67Skamil * stopped - attach to a stopped process 20231.51Skamil */ 20241.1Skamil 20251.1Skamil struct msg_fds parent_tracee, parent_tracer; 20261.1Skamil const int exitval_tracee = 5; 20271.1Skamil const int exitval_tracer = 10; 20281.1Skamil pid_t tracee, tracer, wpid; 20291.1Skamil uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */ 20301.1Skamil#if defined(TWAIT_HAVE_STATUS) 20311.1Skamil int status; 20321.1Skamil#endif 20331.1Skamil 20341.67Skamil /* 20351.67Skamil * Only a subset of options are supported. 20361.67Skamil */ 20371.67Skamil ATF_REQUIRE((!notimeout && !unrelated && !stopped) || 20381.67Skamil (!notimeout && unrelated && !stopped) || 20391.67Skamil (notimeout && !unrelated && !stopped) || 20401.67Skamil (!notimeout && unrelated && stopped)); 20411.67Skamil 20421.13Schristos DPRINTF("Spawn tracee\n"); 20431.13Schristos SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0); 20441.1Skamil tracee = atf_utils_fork(); 20451.1Skamil if (tracee == 0) { 20461.67Skamil if (stopped) { 20471.67Skamil DPRINTF("Stop self PID %d\n", getpid()); 20481.67Skamil raise(SIGSTOP); 20491.67Skamil } 20501.67Skamil 20511.1Skamil // Wait for parent to let us exit 20521.1Skamil CHILD_FROM_PARENT("exit tracee", parent_tracee, msg); 20531.1Skamil _exit(exitval_tracee); 20541.1Skamil } 20551.1Skamil 20561.13Schristos DPRINTF("Spawn debugger\n"); 20571.13Schristos SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0); 20581.1Skamil tracer = atf_utils_fork(); 20591.1Skamil if (tracer == 0) { 20601.51Skamil if(unrelated) { 20611.51Skamil /* Fork again and drop parent to reattach to PID 1 */ 20621.51Skamil tracer = atf_utils_fork(); 20631.51Skamil if (tracer != 0) 20641.51Skamil _exit(exitval_tracer); 20651.51Skamil } 20661.51Skamil 20671.67Skamil if (stopped) { 20681.67Skamil DPRINTF("Await for a stopped parent PID %d\n", tracee); 20691.67Skamil await_stopped(tracee); 20701.67Skamil } 20711.67Skamil 20721.13Schristos DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid()); 20731.1Skamil FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1); 20741.1Skamil 20751.1Skamil /* Wait for tracee and assert that it was stopped w/ SIGSTOP */ 20761.1Skamil FORKEE_REQUIRE_SUCCESS( 20771.1Skamil wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 20781.1Skamil 20791.1Skamil forkee_status_stopped(status, SIGSTOP); 20801.1Skamil 20811.1Skamil /* Resume tracee with PT_CONTINUE */ 20821.1Skamil FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1); 20831.1Skamil 20841.1Skamil /* Inform parent that tracer has attached to tracee */ 20851.1Skamil CHILD_TO_PARENT("tracer ready", parent_tracer, msg); 20861.1Skamil 20871.1Skamil /* Wait for parent to tell use that tracee should have exited */ 20881.1Skamil CHILD_FROM_PARENT("wait for tracee exit", parent_tracer, msg); 20891.1Skamil 20901.1Skamil /* Wait for tracee and assert that it exited */ 20911.1Skamil FORKEE_REQUIRE_SUCCESS( 20921.1Skamil wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 20931.1Skamil 20941.1Skamil forkee_status_exited(status, exitval_tracee); 20951.13Schristos DPRINTF("Tracee %d exited with %d\n", tracee, exitval_tracee); 20961.1Skamil 20971.13Schristos DPRINTF("Before exiting of the tracer process\n"); 20981.51Skamil _exit(unrelated ? 0 /* collect by initproc */ : exitval_tracer); 20991.51Skamil } 21001.51Skamil 21011.51Skamil if (unrelated) { 21021.51Skamil DPRINTF("Wait for the tracer process (direct child) to exit " 21031.51Skamil "calling %s()\n", TWAIT_FNAME); 21041.51Skamil TWAIT_REQUIRE_SUCCESS( 21051.51Skamil wpid = TWAIT_GENERIC(tracer, &status, 0), tracer); 21061.51Skamil 21071.51Skamil validate_status_exited(status, exitval_tracer); 21081.51Skamil 21091.51Skamil DPRINTF("Wait for the non-exited tracee process with %s()\n", 21101.51Skamil TWAIT_FNAME); 21111.51Skamil TWAIT_REQUIRE_SUCCESS( 21121.51Skamil wpid = TWAIT_GENERIC(tracee, NULL, WNOHANG), 0); 21131.1Skamil } 21141.1Skamil 21151.13Schristos DPRINTF("Wait for the tracer to attach to the tracee\n"); 21161.1Skamil PARENT_FROM_CHILD("tracer ready", parent_tracer, msg); 21171.1Skamil 21181.13Schristos DPRINTF("Resume the tracee and let it exit\n"); 21191.1Skamil PARENT_TO_CHILD("exit tracee", parent_tracee, msg); 21201.1Skamil 21211.13Schristos DPRINTF("Detect that tracee is zombie\n"); 21221.51Skamil if (notimeout) 21231.26Skamil await_zombie_raw(tracee, 0); 21241.26Skamil else 21251.26Skamil await_zombie(tracee); 21261.1Skamil 21271.13Schristos DPRINTF("Assert that there is no status about tracee %d - " 21281.1Skamil "Tracer must detect zombie first - calling %s()\n", tracee, 21291.1Skamil TWAIT_FNAME); 21301.1Skamil TWAIT_REQUIRE_SUCCESS( 21311.1Skamil wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0); 21321.1Skamil 21331.51Skamil if (unrelated) { 21341.51Skamil DPRINTF("Resume the tracer and let it detect exited tracee\n"); 21351.51Skamil PARENT_TO_CHILD("Message 2", parent_tracer, msg); 21361.51Skamil } else { 21371.51Skamil DPRINTF("Tell the tracer child should have exited\n"); 21381.51Skamil PARENT_TO_CHILD("wait for tracee exit", parent_tracer, msg); 21391.51Skamil DPRINTF("Wait for tracer to finish its job and exit - calling " 21401.59Skamil "%s()\n", TWAIT_FNAME); 21411.51Skamil 21421.51Skamil DPRINTF("Wait from tracer child to complete waiting for " 21431.59Skamil "tracee\n"); 21441.51Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0), 21451.51Skamil tracer); 21461.1Skamil 21471.51Skamil validate_status_exited(status, exitval_tracer); 21481.51Skamil } 21491.1Skamil 21501.13Schristos DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n", 21511.1Skamil TWAIT_FNAME); 21521.51Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 21531.1Skamil 21541.1Skamil validate_status_exited(status, exitval_tracee); 21551.1Skamil 21561.1Skamil msg_close(&parent_tracer); 21571.1Skamil msg_close(&parent_tracee); 21581.1Skamil} 21591.26Skamil 21601.51SkamilATF_TC(tracer_sees_terminaton_before_the_parent); 21611.51SkamilATF_TC_HEAD(tracer_sees_terminaton_before_the_parent, tc) 21621.51Skamil{ 21631.51Skamil atf_tc_set_md_var(tc, "descr", 21641.51Skamil "Assert that tracer sees process termination before the parent"); 21651.51Skamil} 21661.51Skamil 21671.51SkamilATF_TC_BODY(tracer_sees_terminaton_before_the_parent, tc) 21681.26Skamil{ 21691.26Skamil 21701.67Skamil tracer_sees_terminaton_before_the_parent_raw(false, false, false); 21711.26Skamil} 21721.26Skamil 21731.51SkamilATF_TC(tracer_sysctl_lookup_without_duplicates); 21741.51SkamilATF_TC_HEAD(tracer_sysctl_lookup_without_duplicates, tc) 21751.1Skamil{ 21761.1Skamil atf_tc_set_md_var(tc, "descr", 21771.51Skamil "Assert that await_zombie() in attach1 always finds a single " 21781.51Skamil "process and no other error is reported"); 21791.1Skamil} 21801.1Skamil 21811.51SkamilATF_TC_BODY(tracer_sysctl_lookup_without_duplicates, tc) 21821.1Skamil{ 21831.51Skamil time_t start, end; 21841.51Skamil double diff; 21851.51Skamil unsigned long N = 0; 21861.1Skamil 21871.51Skamil /* 21881.51Skamil * Reuse this test with tracer_sees_terminaton_before_the_parent_raw(). 21891.51Skamil * This test body isn't specific to this race, however it's just good 21901.51Skamil * enough for this purposes, no need to invent a dedicated code flow. 21911.51Skamil */ 21921.1Skamil 21931.51Skamil start = time(NULL); 21941.51Skamil while (true) { 21951.51Skamil DPRINTF("Step: %lu\n", N); 21961.67Skamil tracer_sees_terminaton_before_the_parent_raw(true, false, 21971.67Skamil false); 21981.51Skamil end = time(NULL); 21991.51Skamil diff = difftime(end, start); 22001.51Skamil if (diff >= 5.0) 22011.51Skamil break; 22021.51Skamil ++N; 22031.1Skamil } 22041.51Skamil DPRINTF("Iterations: %lu\n", N); 22051.51Skamil} 22061.1Skamil 22071.51SkamilATF_TC(unrelated_tracer_sees_terminaton_before_the_parent); 22081.51SkamilATF_TC_HEAD(unrelated_tracer_sees_terminaton_before_the_parent, tc) 22091.51Skamil{ 22101.51Skamil atf_tc_set_md_var(tc, "descr", 22111.51Skamil "Assert that tracer sees process termination before the parent"); 22121.51Skamil} 22131.1Skamil 22141.51SkamilATF_TC_BODY(unrelated_tracer_sees_terminaton_before_the_parent, tc) 22151.51Skamil{ 22161.1Skamil 22171.67Skamil tracer_sees_terminaton_before_the_parent_raw(false, true, false); 22181.67Skamil} 22191.67Skamil 22201.67SkamilATF_TC(tracer_attach_to_unrelated_stopped_process); 22211.67SkamilATF_TC_HEAD(tracer_attach_to_unrelated_stopped_process, tc) 22221.67Skamil{ 22231.67Skamil atf_tc_set_md_var(tc, "descr", 22241.67Skamil "Assert that tracer can attach to an unrelated stopped process"); 22251.67Skamil} 22261.67Skamil 22271.67SkamilATF_TC_BODY(tracer_attach_to_unrelated_stopped_process, tc) 22281.67Skamil{ 22291.67Skamil 22301.67Skamil tracer_sees_terminaton_before_the_parent_raw(false, true, true); 22311.1Skamil} 22321.1Skamil#endif 22331.1Skamil 22341.51Skamil/// ---------------------------------------------------------------------------- 22351.51Skamil 22361.66Skamilstatic void 22371.66Skamilparent_attach_to_its_child(bool stopped) 22381.1Skamil{ 22391.1Skamil struct msg_fds parent_tracee; 22401.1Skamil const int exitval_tracee = 5; 22411.1Skamil pid_t tracee, wpid; 22421.1Skamil uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */ 22431.1Skamil#if defined(TWAIT_HAVE_STATUS) 22441.1Skamil int status; 22451.1Skamil#endif 22461.1Skamil 22471.13Schristos DPRINTF("Spawn tracee\n"); 22481.13Schristos SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0); 22491.1Skamil tracee = atf_utils_fork(); 22501.1Skamil if (tracee == 0) { 22511.1Skamil CHILD_FROM_PARENT("Message 1", parent_tracee, msg); 22521.13Schristos DPRINTF("Parent should now attach to tracee\n"); 22531.1Skamil 22541.66Skamil if (stopped) { 22551.66Skamil DPRINTF("Stop self PID %d\n", getpid()); 22561.66Skamil SYSCALL_REQUIRE(raise(SIGSTOP) != -1); 22571.66Skamil } 22581.66Skamil 22591.1Skamil CHILD_FROM_PARENT("Message 2", parent_tracee, msg); 22601.1Skamil /* Wait for message from the parent */ 22611.1Skamil _exit(exitval_tracee); 22621.1Skamil } 22631.1Skamil PARENT_TO_CHILD("Message 1", parent_tracee, msg); 22641.57Skamil 22651.66Skamil if (stopped) { 22661.66Skamil DPRINTF("Await for a stopped tracee PID %d\n", tracee); 22671.66Skamil await_stopped(tracee); 22681.66Skamil } 22691.66Skamil 22701.13Schristos DPRINTF("Before calling PT_ATTACH for tracee %d\n", tracee); 22711.13Schristos SYSCALL_REQUIRE(ptrace(PT_ATTACH, tracee, NULL, 0) != -1); 22721.1Skamil 22731.13Schristos DPRINTF("Wait for the stopped tracee process with %s()\n", 22741.1Skamil TWAIT_FNAME); 22751.1Skamil TWAIT_REQUIRE_SUCCESS( 22761.1Skamil wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 22771.1Skamil 22781.1Skamil validate_status_stopped(status, SIGSTOP); 22791.1Skamil 22801.13Schristos DPRINTF("Resume tracee with PT_CONTINUE\n"); 22811.13Schristos SYSCALL_REQUIRE(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1); 22821.1Skamil 22831.13Schristos DPRINTF("Let the tracee exit now\n"); 22841.1Skamil PARENT_TO_CHILD("Message 2", parent_tracee, msg); 22851.1Skamil 22861.13Schristos DPRINTF("Wait for tracee to exit with %s()\n", TWAIT_FNAME); 22871.1Skamil TWAIT_REQUIRE_SUCCESS( 22881.1Skamil wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 22891.1Skamil 22901.1Skamil validate_status_exited(status, exitval_tracee); 22911.1Skamil 22921.13Schristos DPRINTF("Before calling %s() for tracee\n", TWAIT_FNAME); 22931.1Skamil TWAIT_REQUIRE_FAILURE(ECHILD, 22941.1Skamil wpid = TWAIT_GENERIC(tracee, &status, 0)); 22951.1Skamil 22961.1Skamil msg_close(&parent_tracee); 22971.1Skamil} 22981.1Skamil 22991.66SkamilATF_TC(parent_attach_to_its_child); 23001.66SkamilATF_TC_HEAD(parent_attach_to_its_child, tc) 23011.66Skamil{ 23021.66Skamil atf_tc_set_md_var(tc, "descr", 23031.66Skamil "Assert that tracer parent can PT_ATTACH to its child"); 23041.66Skamil} 23051.66Skamil 23061.66SkamilATF_TC_BODY(parent_attach_to_its_child, tc) 23071.66Skamil{ 23081.66Skamil 23091.66Skamil parent_attach_to_its_child(false); 23101.66Skamil} 23111.66Skamil 23121.66SkamilATF_TC(parent_attach_to_its_stopped_child); 23131.66SkamilATF_TC_HEAD(parent_attach_to_its_stopped_child, tc) 23141.66Skamil{ 23151.66Skamil atf_tc_set_md_var(tc, "descr", 23161.66Skamil "Assert that tracer parent can PT_ATTACH to its stopped child"); 23171.66Skamil} 23181.66Skamil 23191.66SkamilATF_TC_BODY(parent_attach_to_its_stopped_child, tc) 23201.66Skamil{ 23211.66Skamil 23221.66Skamil parent_attach_to_its_child(true); 23231.66Skamil} 23241.66Skamil 23251.51Skamil/// ---------------------------------------------------------------------------- 23261.51Skamil 23271.65Skamilstatic void 23281.65Skamilchild_attach_to_its_parent(bool stopped) 23291.1Skamil{ 23301.1Skamil struct msg_fds parent_tracee; 23311.1Skamil const int exitval_tracer = 5; 23321.1Skamil pid_t tracer, wpid; 23331.1Skamil uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */ 23341.1Skamil#if defined(TWAIT_HAVE_STATUS) 23351.1Skamil int status; 23361.1Skamil#endif 23371.1Skamil 23381.13Schristos DPRINTF("Spawn tracer\n"); 23391.13Schristos SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0); 23401.1Skamil tracer = atf_utils_fork(); 23411.1Skamil if (tracer == 0) { 23421.1Skamil /* Wait for message from the parent */ 23431.1Skamil CHILD_FROM_PARENT("Message 1", parent_tracee, msg); 23441.1Skamil 23451.65Skamil if (stopped) { 23461.65Skamil DPRINTF("Await for a stopped parent PID %d\n", 23471.65Skamil getppid()); 23481.65Skamil await_stopped(getppid()); 23491.65Skamil } 23501.65Skamil 23511.13Schristos DPRINTF("Attach to parent PID %d with PT_ATTACH from child\n", 23521.1Skamil getppid()); 23531.1Skamil FORKEE_ASSERT(ptrace(PT_ATTACH, getppid(), NULL, 0) != -1); 23541.1Skamil 23551.13Schristos DPRINTF("Wait for the stopped parent process with %s()\n", 23561.1Skamil TWAIT_FNAME); 23571.1Skamil FORKEE_REQUIRE_SUCCESS( 23581.1Skamil wpid = TWAIT_GENERIC(getppid(), &status, 0), getppid()); 23591.1Skamil 23601.1Skamil forkee_status_stopped(status, SIGSTOP); 23611.1Skamil 23621.13Schristos DPRINTF("Resume parent with PT_DETACH\n"); 23631.1Skamil FORKEE_ASSERT(ptrace(PT_DETACH, getppid(), (void *)1, 0) 23641.1Skamil != -1); 23651.1Skamil 23661.1Skamil /* Tell parent we are ready */ 23671.1Skamil CHILD_TO_PARENT("Message 1", parent_tracee, msg); 23681.1Skamil 23691.1Skamil _exit(exitval_tracer); 23701.1Skamil } 23711.1Skamil 23721.13Schristos DPRINTF("Wait for the tracer to become ready\n"); 23731.1Skamil PARENT_TO_CHILD("Message 1", parent_tracee, msg); 23741.65Skamil 23751.65Skamil if (stopped) { 23761.65Skamil DPRINTF("Stop self PID %d\n", getpid()); 23771.65Skamil SYSCALL_REQUIRE(raise(SIGSTOP) != -1); 23781.65Skamil } 23791.65Skamil 23801.13Schristos DPRINTF("Allow the tracer to exit now\n"); 23811.1Skamil PARENT_FROM_CHILD("Message 1", parent_tracee, msg); 23821.1Skamil 23831.13Schristos DPRINTF("Wait for tracer to exit with %s()\n", TWAIT_FNAME); 23841.1Skamil TWAIT_REQUIRE_SUCCESS( 23851.1Skamil wpid = TWAIT_GENERIC(tracer, &status, 0), tracer); 23861.1Skamil 23871.1Skamil validate_status_exited(status, exitval_tracer); 23881.1Skamil 23891.13Schristos DPRINTF("Before calling %s() for tracer\n", TWAIT_FNAME); 23901.1Skamil TWAIT_REQUIRE_FAILURE(ECHILD, 23911.1Skamil wpid = TWAIT_GENERIC(tracer, &status, 0)); 23921.1Skamil 23931.1Skamil msg_close(&parent_tracee); 23941.1Skamil} 23951.1Skamil 23961.65SkamilATF_TC(child_attach_to_its_parent); 23971.65SkamilATF_TC_HEAD(child_attach_to_its_parent, tc) 23981.65Skamil{ 23991.65Skamil atf_tc_set_md_var(tc, "descr", 24001.65Skamil "Assert that tracer child can PT_ATTACH to its parent"); 24011.65Skamil} 24021.65Skamil 24031.65SkamilATF_TC_BODY(child_attach_to_its_parent, tc) 24041.65Skamil{ 24051.65Skamil 24061.65Skamil child_attach_to_its_parent(false); 24071.65Skamil} 24081.65Skamil 24091.65SkamilATF_TC(child_attach_to_its_stopped_parent); 24101.65SkamilATF_TC_HEAD(child_attach_to_its_stopped_parent, tc) 24111.65Skamil{ 24121.65Skamil atf_tc_set_md_var(tc, "descr", 24131.65Skamil "Assert that tracer child can PT_ATTACH to its stopped parent"); 24141.65Skamil} 24151.65Skamil 24161.65SkamilATF_TC_BODY(child_attach_to_its_stopped_parent, tc) 24171.65Skamil{ 24181.65Skamil /* 24191.65Skamil * The ATF framework (atf-run) does not tolerate raise(SIGSTOP), as 24201.65Skamil * this causes a pipe (established from atf-run) to be broken. 24211.65Skamil * atf-run uses this mechanism to monitor whether a test is alive. 24221.65Skamil * 24231.65Skamil * As a workaround spawn this test as a subprocess. 24241.65Skamil */ 24251.65Skamil 24261.65Skamil const int exitval = 15; 24271.65Skamil pid_t child, wpid; 24281.65Skamil#if defined(TWAIT_HAVE_STATUS) 24291.65Skamil int status; 24301.65Skamil#endif 24311.65Skamil 24321.65Skamil SYSCALL_REQUIRE((child = fork()) != -1); 24331.65Skamil if (child == 0) { 24341.65Skamil child_attach_to_its_parent(true); 24351.65Skamil _exit(exitval); 24361.65Skamil } else { 24371.65Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 24381.65Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 24391.65Skamil 24401.65Skamil validate_status_exited(status, exitval); 24411.65Skamil 24421.65Skamil DPRINTF("Before calling %s() for the exited child\n", TWAIT_FNAME); 24431.65Skamil TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 24441.65Skamil } 24451.65Skamil} 24461.65Skamil 24471.51Skamil/// ---------------------------------------------------------------------------- 24481.51Skamil 24491.1Skamil#if defined(TWAIT_HAVE_PID) 24501.1Skamil 24511.51Skamilenum tracee_sees_its_original_parent_type { 24521.51Skamil TRACEE_SEES_ITS_ORIGINAL_PARENT_GETPPID, 24531.51Skamil TRACEE_SEES_ITS_ORIGINAL_PARENT_SYSCTL_KINFO_PROC2, 24541.51Skamil TRACEE_SEES_ITS_ORIGINAL_PARENT_PROCFS_STATUS 24551.51Skamil}; 24561.51Skamil 24571.51Skamilstatic void 24581.51Skamiltracee_sees_its_original_parent(enum tracee_sees_its_original_parent_type type) 24591.1Skamil{ 24601.1Skamil struct msg_fds parent_tracer, parent_tracee; 24611.1Skamil const int exitval_tracee = 5; 24621.1Skamil const int exitval_tracer = 10; 24631.1Skamil pid_t parent, tracee, tracer, wpid; 24641.1Skamil uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */ 24651.1Skamil#if defined(TWAIT_HAVE_STATUS) 24661.1Skamil int status; 24671.1Skamil#endif 24681.51Skamil /* sysctl(3) - kinfo_proc2 */ 24691.51Skamil int name[CTL_MAXNAME]; 24701.51Skamil struct kinfo_proc2 kp; 24711.51Skamil size_t len = sizeof(kp); 24721.51Skamil unsigned int namelen; 24731.51Skamil 24741.51Skamil /* procfs - status */ 24751.51Skamil FILE *fp; 24761.51Skamil struct stat st; 24771.51Skamil const char *fname = "/proc/curproc/status"; 24781.51Skamil char s_executable[MAXPATHLEN]; 24791.51Skamil int s_pid, s_ppid; 24801.51Skamil int rv; 24811.51Skamil 24821.51Skamil if (type == TRACEE_SEES_ITS_ORIGINAL_PARENT_PROCFS_STATUS) { 24831.61Skre SYSCALL_REQUIRE( 24841.61Skre (rv = stat(fname, &st)) == 0 || (errno == ENOENT)); 24851.61Skre if (rv != 0) 24861.51Skamil atf_tc_skip("/proc/curproc/status not found"); 24871.51Skamil } 24881.1Skamil 24891.13Schristos DPRINTF("Spawn tracee\n"); 24901.13Schristos SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0); 24911.13Schristos SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0); 24921.1Skamil tracee = atf_utils_fork(); 24931.1Skamil if (tracee == 0) { 24941.1Skamil parent = getppid(); 24951.1Skamil 24961.1Skamil /* Emit message to the parent */ 24971.1Skamil CHILD_TO_PARENT("tracee ready", parent_tracee, msg); 24981.1Skamil CHILD_FROM_PARENT("exit tracee", parent_tracee, msg); 24991.1Skamil 25001.51Skamil switch (type) { 25011.51Skamil case TRACEE_SEES_ITS_ORIGINAL_PARENT_GETPPID: 25021.51Skamil FORKEE_ASSERT_EQ(parent, getppid()); 25031.51Skamil break; 25041.51Skamil case TRACEE_SEES_ITS_ORIGINAL_PARENT_SYSCTL_KINFO_PROC2: 25051.51Skamil namelen = 0; 25061.51Skamil name[namelen++] = CTL_KERN; 25071.51Skamil name[namelen++] = KERN_PROC2; 25081.51Skamil name[namelen++] = KERN_PROC_PID; 25091.51Skamil name[namelen++] = getpid(); 25101.51Skamil name[namelen++] = len; 25111.51Skamil name[namelen++] = 1; 25121.51Skamil 25131.61Skre FORKEE_ASSERT_EQ( 25141.61Skre sysctl(name, namelen, &kp, &len, NULL, 0), 0); 25151.51Skamil FORKEE_ASSERT_EQ(parent, kp.p_ppid); 25161.51Skamil break; 25171.51Skamil case TRACEE_SEES_ITS_ORIGINAL_PARENT_PROCFS_STATUS: 25181.51Skamil /* 25191.51Skamil * Format: 25201.51Skamil * EXECUTABLE PID PPID ... 25211.51Skamil */ 25221.51Skamil FORKEE_ASSERT((fp = fopen(fname, "r")) != NULL); 25231.51Skamil fscanf(fp, "%s %d %d", s_executable, &s_pid, &s_ppid); 25241.51Skamil FORKEE_ASSERT_EQ(fclose(fp), 0); 25251.51Skamil FORKEE_ASSERT_EQ(parent, s_ppid); 25261.51Skamil break; 25271.51Skamil } 25281.1Skamil 25291.1Skamil _exit(exitval_tracee); 25301.1Skamil } 25311.13Schristos DPRINTF("Wait for child to record its parent identifier (pid)\n"); 25321.1Skamil PARENT_FROM_CHILD("tracee ready", parent_tracee, msg); 25331.1Skamil 25341.13Schristos DPRINTF("Spawn debugger\n"); 25351.1Skamil tracer = atf_utils_fork(); 25361.1Skamil if (tracer == 0) { 25371.1Skamil /* No IPC to communicate with the child */ 25381.13Schristos DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid()); 25391.1Skamil FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1); 25401.1Skamil 25411.1Skamil /* Wait for tracee and assert that it was stopped w/ SIGSTOP */ 25421.1Skamil FORKEE_REQUIRE_SUCCESS( 25431.1Skamil wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 25441.1Skamil 25451.1Skamil forkee_status_stopped(status, SIGSTOP); 25461.1Skamil 25471.1Skamil /* Resume tracee with PT_CONTINUE */ 25481.1Skamil FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1); 25491.1Skamil 25501.1Skamil /* Inform parent that tracer has attached to tracee */ 25511.1Skamil CHILD_TO_PARENT("tracer ready", parent_tracer, msg); 25521.1Skamil 25531.1Skamil /* Wait for parent to tell use that tracee should have exited */ 25541.1Skamil CHILD_FROM_PARENT("wait for tracee exit", parent_tracer, msg); 25551.1Skamil 25561.1Skamil /* Wait for tracee and assert that it exited */ 25571.1Skamil FORKEE_REQUIRE_SUCCESS( 25581.1Skamil wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 25591.1Skamil 25601.1Skamil forkee_status_exited(status, exitval_tracee); 25611.1Skamil 25621.13Schristos DPRINTF("Before exiting of the tracer process\n"); 25631.1Skamil _exit(exitval_tracer); 25641.1Skamil } 25651.1Skamil 25661.13Schristos DPRINTF("Wait for the tracer to attach to the tracee\n"); 25671.1Skamil PARENT_FROM_CHILD("tracer ready", parent_tracer, msg); 25681.1Skamil 25691.13Schristos DPRINTF("Resume the tracee and let it exit\n"); 25701.1Skamil PARENT_TO_CHILD("exit tracee", parent_tracee, msg); 25711.1Skamil 25721.13Schristos DPRINTF("Detect that tracee is zombie\n"); 25731.1Skamil await_zombie(tracee); 25741.1Skamil 25751.13Schristos DPRINTF("Assert that there is no status about tracee - " 25761.1Skamil "Tracer must detect zombie first - calling %s()\n", TWAIT_FNAME); 25771.1Skamil TWAIT_REQUIRE_SUCCESS( 25781.1Skamil wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0); 25791.1Skamil 25801.13Schristos DPRINTF("Tell the tracer child should have exited\n"); 25811.1Skamil PARENT_TO_CHILD("wait for tracee exit", parent_tracer, msg); 25821.1Skamil 25831.13Schristos DPRINTF("Wait from tracer child to complete waiting for tracee\n"); 25841.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0), 25851.1Skamil tracer); 25861.1Skamil 25871.1Skamil validate_status_exited(status, exitval_tracer); 25881.1Skamil 25891.13Schristos DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n", 25901.1Skamil TWAIT_FNAME); 25911.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 25921.1Skamil tracee); 25931.1Skamil 25941.1Skamil validate_status_exited(status, exitval_tracee); 25951.1Skamil 25961.1Skamil msg_close(&parent_tracer); 25971.1Skamil msg_close(&parent_tracee); 25981.1Skamil} 25991.1Skamil 26001.61Skre#define TRACEE_SEES_ITS_ORIGINAL_PARENT(test, type, descr) \ 26011.61SkreATF_TC(test); \ 26021.61SkreATF_TC_HEAD(test, tc) \ 26031.61Skre{ \ 26041.61Skre atf_tc_set_md_var(tc, "descr", \ 26051.61Skre "Assert that tracee sees its original parent when being traced " \ 26061.61Skre "(check " descr ")"); \ 26071.61Skre} \ 26081.61Skre \ 26091.61SkreATF_TC_BODY(test, tc) \ 26101.61Skre{ \ 26111.61Skre \ 26121.61Skre tracee_sees_its_original_parent(type); \ 26131.1Skamil} 26141.1Skamil 26151.51SkamilTRACEE_SEES_ITS_ORIGINAL_PARENT( 26161.51Skamil tracee_sees_its_original_parent_getppid, 26171.51Skamil TRACEE_SEES_ITS_ORIGINAL_PARENT_GETPPID, 26181.51Skamil "getppid(2)"); 26191.51SkamilTRACEE_SEES_ITS_ORIGINAL_PARENT( 26201.51Skamil tracee_sees_its_original_parent_sysctl_kinfo_proc2, 26211.51Skamil TRACEE_SEES_ITS_ORIGINAL_PARENT_SYSCTL_KINFO_PROC2, 26221.51Skamil "sysctl(3) and kinfo_proc2"); 26231.51SkamilTRACEE_SEES_ITS_ORIGINAL_PARENT( 26241.51Skamil tracee_sees_its_original_parent_procfs_status, 26251.51Skamil TRACEE_SEES_ITS_ORIGINAL_PARENT_PROCFS_STATUS, 26261.51Skamil "the status file in procfs"); 26271.1Skamil#endif 26281.1Skamil 26291.51Skamil/// ---------------------------------------------------------------------------- 26301.1Skamil 26311.53Skamilstatic void 26321.53Skamileventmask_preserved(int event) 26331.1Skamil{ 26341.1Skamil const int exitval = 5; 26351.1Skamil const int sigval = SIGSTOP; 26361.1Skamil pid_t child, wpid; 26371.1Skamil#if defined(TWAIT_HAVE_STATUS) 26381.1Skamil int status; 26391.1Skamil#endif 26401.1Skamil ptrace_event_t set_event, get_event; 26411.1Skamil const int len = sizeof(ptrace_event_t); 26421.1Skamil 26431.13Schristos DPRINTF("Before forking process PID=%d\n", getpid()); 26441.13Schristos SYSCALL_REQUIRE((child = fork()) != -1); 26451.1Skamil if (child == 0) { 26461.13Schristos DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 26471.1Skamil FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 26481.1Skamil 26491.13Schristos DPRINTF("Before raising %s from child\n", strsignal(sigval)); 26501.1Skamil FORKEE_ASSERT(raise(sigval) == 0); 26511.1Skamil 26521.13Schristos DPRINTF("Before exiting of the child process\n"); 26531.1Skamil _exit(exitval); 26541.1Skamil } 26551.13Schristos DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 26561.1Skamil 26571.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 26581.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 26591.1Skamil 26601.1Skamil validate_status_stopped(status, sigval); 26611.1Skamil 26621.53Skamil set_event.pe_set_event = event; 26631.61Skre SYSCALL_REQUIRE( 26641.61Skre ptrace(PT_SET_EVENT_MASK, child, &set_event, len) != -1); 26651.61Skre SYSCALL_REQUIRE( 26661.61Skre ptrace(PT_GET_EVENT_MASK, child, &get_event, len) != -1); 26671.1Skamil ATF_REQUIRE(memcmp(&set_event, &get_event, len) == 0); 26681.1Skamil 26691.13Schristos DPRINTF("Before resuming the child process where it left off and " 26701.1Skamil "without signal to be sent\n"); 26711.13Schristos SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 26721.1Skamil 26731.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 26741.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 26751.1Skamil 26761.1Skamil validate_status_exited(status, exitval); 26771.1Skamil 26781.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 26791.1Skamil TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 26801.1Skamil} 26811.1Skamil 26821.61Skre#define EVENTMASK_PRESERVED(test, event) \ 26831.61SkreATF_TC(test); \ 26841.61SkreATF_TC_HEAD(test, tc) \ 26851.61Skre{ \ 26861.61Skre atf_tc_set_md_var(tc, "descr", \ 26871.61Skre "Verify that eventmask " #event " is preserved"); \ 26881.61Skre} \ 26891.61Skre \ 26901.61SkreATF_TC_BODY(test, tc) \ 26911.61Skre{ \ 26921.61Skre \ 26931.61Skre eventmask_preserved(event); \ 26941.1Skamil} 26951.1Skamil 26961.53SkamilEVENTMASK_PRESERVED(eventmask_preserved_empty, 0) 26971.53SkamilEVENTMASK_PRESERVED(eventmask_preserved_fork, PTRACE_FORK) 26981.53SkamilEVENTMASK_PRESERVED(eventmask_preserved_vfork, PTRACE_VFORK) 26991.53SkamilEVENTMASK_PRESERVED(eventmask_preserved_vfork_done, PTRACE_VFORK_DONE) 27001.53SkamilEVENTMASK_PRESERVED(eventmask_preserved_lwp_create, PTRACE_LWP_CREATE) 27011.53SkamilEVENTMASK_PRESERVED(eventmask_preserved_lwp_exit, PTRACE_LWP_EXIT) 27021.1Skamil 27031.53Skamil/// ---------------------------------------------------------------------------- 27041.1Skamil 27051.28Skamilstatic void 27061.32Skamilfork_body(pid_t (*fn)(void), bool trackfork, bool trackvfork, 27071.61Skre bool trackvforkdone, bool detachchild, bool detachparent) 27081.1Skamil{ 27091.1Skamil const int exitval = 5; 27101.1Skamil const int exitval2 = 15; 27111.1Skamil const int sigval = SIGSTOP; 27121.31Skamil pid_t child, child2 = 0, wpid; 27131.1Skamil#if defined(TWAIT_HAVE_STATUS) 27141.1Skamil int status; 27151.1Skamil#endif 27161.1Skamil ptrace_state_t state; 27171.1Skamil const int slen = sizeof(state); 27181.1Skamil ptrace_event_t event; 27191.1Skamil const int elen = sizeof(event); 27201.1Skamil 27211.13Schristos DPRINTF("Before forking process PID=%d\n", getpid()); 27221.13Schristos SYSCALL_REQUIRE((child = fork()) != -1); 27231.1Skamil if (child == 0) { 27241.13Schristos DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 27251.1Skamil FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 27261.1Skamil 27271.13Schristos DPRINTF("Before raising %s from child\n", strsignal(sigval)); 27281.1Skamil FORKEE_ASSERT(raise(sigval) == 0); 27291.1Skamil 27301.30Skamil FORKEE_ASSERT((child2 = (fn)()) != -1); 27311.1Skamil 27321.1Skamil if (child2 == 0) 27331.1Skamil _exit(exitval2); 27341.1Skamil 27351.1Skamil FORKEE_REQUIRE_SUCCESS 27361.1Skamil (wpid = TWAIT_GENERIC(child2, &status, 0), child2); 27371.1Skamil 27381.1Skamil forkee_status_exited(status, exitval2); 27391.1Skamil 27401.13Schristos DPRINTF("Before exiting of the child process\n"); 27411.1Skamil _exit(exitval); 27421.1Skamil } 27431.13Schristos DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 27441.1Skamil 27451.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 27461.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 27471.1Skamil 27481.1Skamil validate_status_stopped(status, sigval); 27491.1Skamil 27501.30Skamil DPRINTF("Set 0%s%s%s in EVENT_MASK for the child %d\n", 27511.61Skre trackfork ? "|PTRACE_FORK" : "", 27521.61Skre trackvfork ? "|PTRACE_VFORK" : "", 27531.61Skre trackvforkdone ? "|PTRACE_VFORK_DONE" : "", child); 27541.30Skamil event.pe_set_event = 0; 27551.30Skamil if (trackfork) 27561.30Skamil event.pe_set_event |= PTRACE_FORK; 27571.30Skamil if (trackvfork) 27581.30Skamil event.pe_set_event |= PTRACE_VFORK; 27591.30Skamil if (trackvforkdone) 27601.30Skamil event.pe_set_event |= PTRACE_VFORK_DONE; 27611.13Schristos SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); 27621.1Skamil 27631.13Schristos DPRINTF("Before resuming the child process where it left off and " 27641.1Skamil "without signal to be sent\n"); 27651.13Schristos SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 27661.1Skamil 27671.29Skamil#if defined(TWAIT_HAVE_PID) 27681.31Skamil if ((trackfork && fn == fork) || (trackvfork && fn == vfork)) { 27691.29Skamil DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME, 27701.61Skre child); 27711.29Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), 27721.61Skre child); 27731.1Skamil 27741.29Skamil validate_status_stopped(status, SIGTRAP); 27751.1Skamil 27761.61Skre SYSCALL_REQUIRE( 27771.61Skre ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 27781.31Skamil if (trackfork && fn == fork) { 27791.30Skamil ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK, 27801.30Skamil PTRACE_FORK); 27811.30Skamil } 27821.31Skamil if (trackvfork && fn == vfork) { 27831.30Skamil ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK, 27841.30Skamil PTRACE_VFORK); 27851.30Skamil } 27861.29Skamil 27871.29Skamil child2 = state.pe_other_pid; 27881.30Skamil DPRINTF("Reported ptrace event with forkee %d\n", child2); 27891.29Skamil 27901.29Skamil DPRINTF("Before calling %s() for the forkee %d of the child " 27911.61Skre "%d\n", TWAIT_FNAME, child2, child); 27921.29Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0), 27931.29Skamil child2); 27941.1Skamil 27951.29Skamil validate_status_stopped(status, SIGTRAP); 27961.1Skamil 27971.61Skre SYSCALL_REQUIRE( 27981.61Skre ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1); 27991.31Skamil if (trackfork && fn == fork) { 28001.30Skamil ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK, 28011.30Skamil PTRACE_FORK); 28021.30Skamil } 28031.31Skamil if (trackvfork && fn == vfork) { 28041.30Skamil ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK, 28051.30Skamil PTRACE_VFORK); 28061.30Skamil } 28071.30Skamil 28081.29Skamil ATF_REQUIRE_EQ(state.pe_other_pid, child); 28091.29Skamil 28101.29Skamil DPRINTF("Before resuming the forkee process where it left off " 28111.29Skamil "and without signal to be sent\n"); 28121.61Skre SYSCALL_REQUIRE( 28131.61Skre ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1); 28141.29Skamil 28151.29Skamil DPRINTF("Before resuming the child process where it left off " 28161.61Skre "and without signal to be sent\n"); 28171.29Skamil SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 28181.30Skamil } 28191.30Skamil#endif 28201.30Skamil 28211.31Skamil if (trackvforkdone && fn == vfork) { 28221.30Skamil DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME, 28231.61Skre child); 28241.61Skre TWAIT_REQUIRE_SUCCESS( 28251.61Skre wpid = TWAIT_GENERIC(child, &status, 0), child); 28261.30Skamil 28271.30Skamil validate_status_stopped(status, SIGTRAP); 28281.30Skamil 28291.61Skre SYSCALL_REQUIRE( 28301.61Skre ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 28311.30Skamil ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK_DONE); 28321.30Skamil 28331.30Skamil child2 = state.pe_other_pid; 28341.30Skamil DPRINTF("Reported PTRACE_VFORK_DONE event with forkee %d\n", 28351.61Skre child2); 28361.30Skamil 28371.30Skamil DPRINTF("Before resuming the child process where it left off " 28381.61Skre "and without signal to be sent\n"); 28391.30Skamil SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 28401.30Skamil } 28411.29Skamil 28421.30Skamil#if defined(TWAIT_HAVE_PID) 28431.31Skamil if ((trackfork && fn == fork) || (trackvfork && fn == vfork)) { 28441.29Skamil DPRINTF("Before calling %s() for the forkee - expected exited" 28451.61Skre "\n", TWAIT_FNAME); 28461.61Skre TWAIT_REQUIRE_SUCCESS( 28471.61Skre wpid = TWAIT_GENERIC(child2, &status, 0), child2); 28481.29Skamil 28491.29Skamil validate_status_exited(status, exitval2); 28501.29Skamil 28511.29Skamil DPRINTF("Before calling %s() for the forkee - expected no " 28521.61Skre "process\n", TWAIT_FNAME); 28531.29Skamil TWAIT_REQUIRE_FAILURE(ECHILD, 28541.29Skamil wpid = TWAIT_GENERIC(child2, &status, 0)); 28551.29Skamil } 28561.29Skamil#endif 28571.1Skamil 28581.13Schristos DPRINTF("Before calling %s() for the child - expected stopped " 28591.1Skamil "SIGCHLD\n", TWAIT_FNAME); 28601.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 28611.1Skamil 28621.1Skamil validate_status_stopped(status, SIGCHLD); 28631.1Skamil 28641.13Schristos DPRINTF("Before resuming the child process where it left off and " 28651.1Skamil "without signal to be sent\n"); 28661.13Schristos SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 28671.1Skamil 28681.13Schristos DPRINTF("Before calling %s() for the child - expected exited\n", 28691.1Skamil TWAIT_FNAME); 28701.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 28711.1Skamil 28721.1Skamil validate_status_exited(status, exitval); 28731.1Skamil 28741.13Schristos DPRINTF("Before calling %s() for the child - expected no process\n", 28751.1Skamil TWAIT_FNAME); 28761.1Skamil TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 28771.1Skamil} 28781.28Skamil 28791.61Skre#define FORK_TEST(name,descr,fun,tfork,tvfork,tvforkdone,detchild,detparent) \ 28801.61SkreATF_TC(name); \ 28811.61SkreATF_TC_HEAD(name, tc) \ 28821.61Skre{ \ 28831.61Skre atf_tc_set_md_var(tc, "descr", descr); \ 28841.61Skre} \ 28851.61Skre \ 28861.61SkreATF_TC_BODY(name, tc) \ 28871.61Skre{ \ 28881.61Skre \ 28891.61Skre fork_body(fun, tfork, tvfork, tvforkdone, detchild, detparent); \ 28901.32Skamil} 28911.32Skamil 28921.32Skamil#define F false 28931.32Skamil#define T true 28941.32Skamil 28951.32Skamil#define F_IF__0(x) 28961.32Skamil#define F_IF__1(x) x 28971.32Skamil#define F_IF__(x,y) F_IF__ ## x (y) 28981.32Skamil#define F_IF_(x,y) F_IF__(x,y) 28991.32Skamil#define F_IF(x,y) F_IF_(x,y) 29001.32Skamil 29011.61Skre#define DSCR(function,forkbit,vforkbit,vforkdonebit,dchildbit,dparentbit) \ 29021.61Skre "Verify " #function "(2) called with 0" \ 29031.61Skre F_IF(forkbit,"|PTRACE_FORK") \ 29041.61Skre F_IF(vforkbit,"|PTRACE_VFORK") \ 29051.61Skre F_IF(vforkdonebit,"|PTRACE_VFORK_DONE") \ 29061.61Skre " in EVENT_MASK." \ 29071.61Skre F_IF(dchildbit," Detach child in this test.") \ 29081.61Skre F_IF(dparentbit," Detach parent in this test.") 29091.1Skamil 29101.32SkamilFORK_TEST(fork1, DSCR(fork,0,0,0,0,0), fork, F, F, F, F, F) 29111.31Skamil#if defined(TWAIT_HAVE_PID) 29121.32SkamilFORK_TEST(fork2, DSCR(fork,1,0,0,0,0), fork, T, F, F, F, F) 29131.32SkamilFORK_TEST(fork3, DSCR(fork,0,1,0,0,0), fork, F, T, F, F, F) 29141.32SkamilFORK_TEST(fork4, DSCR(fork,1,1,0,0,0), fork, T, T, F, F, F) 29151.31Skamil#endif 29161.32SkamilFORK_TEST(fork5, DSCR(fork,0,0,1,0,0), fork, F, F, T, F, F) 29171.31Skamil#if defined(TWAIT_HAVE_PID) 29181.32SkamilFORK_TEST(fork6, DSCR(fork,1,0,1,0,0), fork, T, F, T, F, F) 29191.32SkamilFORK_TEST(fork7, DSCR(fork,0,1,1,0,0), fork, F, T, T, F, F) 29201.32SkamilFORK_TEST(fork8, DSCR(fork,1,1,1,0,0), fork, T, T, T, F, F) 29211.31Skamil#endif 29221.1Skamil 29231.32SkamilFORK_TEST(vfork1, DSCR(vfork,0,0,0,0,0), vfork, F, F, F, F, F) 29241.31Skamil#if defined(TWAIT_HAVE_PID) 29251.32SkamilFORK_TEST(vfork2, DSCR(vfork,1,0,0,0,0), vfork, T, F, F, F, F) 29261.32SkamilFORK_TEST(vfork3, DSCR(vfork,0,1,0,0,0), vfork, F, T, F, F, F) 29271.32SkamilFORK_TEST(vfork4, DSCR(vfork,1,1,0,0,0), vfork, T, T, F, F, F) 29281.31Skamil#endif 29291.32SkamilFORK_TEST(vfork5, DSCR(vfork,0,0,1,0,0), vfork, F, F, T, F, F) 29301.31Skamil#if defined(TWAIT_HAVE_PID) 29311.32SkamilFORK_TEST(vfork6, DSCR(vfork,1,0,1,0,0), vfork, T, F, T, F, F) 29321.32SkamilFORK_TEST(vfork7, DSCR(vfork,0,1,1,0,0), vfork, F, T, T, F, F) 29331.32SkamilFORK_TEST(vfork8, DSCR(vfork,1,1,1,0,0), vfork, T, T, T, F, F) 29341.31Skamil#endif 29351.31Skamil 29361.54Skamil/// ---------------------------------------------------------------------------- 29371.31Skamil 29381.54Skamilenum bytes_transfer_type { 29391.54Skamil BYTES_TRANSFER_DATA, 29401.54Skamil BYTES_TRANSFER_DATAIO, 29411.54Skamil BYTES_TRANSFER_TEXT, 29421.54Skamil BYTES_TRANSFER_TEXTIO, 29431.54Skamil BYTES_TRANSFER_AUXV 29441.54Skamil}; 29451.31Skamil 29461.54Skamilstatic int __used 29471.54Skamilbytes_transfer_dummy(int a, int b, int c, int d) 29481.54Skamil{ 29491.54Skamil int e, f, g, h; 29501.1Skamil 29511.54Skamil a *= 4; 29521.54Skamil b += 3; 29531.54Skamil c -= 2; 29541.54Skamil d /= 1; 29551.1Skamil 29561.54Skamil e = strtol("10", NULL, 10); 29571.54Skamil f = strtol("20", NULL, 10); 29581.54Skamil g = strtol("30", NULL, 10); 29591.54Skamil h = strtol("40", NULL, 10); 29601.1Skamil 29611.54Skamil return (a + b * c - d) + (e * f - g / h); 29621.1Skamil} 29631.1Skamil 29641.54Skamilstatic void 29651.55Schristosbytes_transfer(int operation, size_t size, enum bytes_transfer_type type) 29661.1Skamil{ 29671.1Skamil const int exitval = 5; 29681.1Skamil const int sigval = SIGSTOP; 29691.1Skamil pid_t child, wpid; 29701.54Skamil bool skip = false; 29711.1Skamil 29721.54Skamil int lookup_me = 0; 29731.54Skamil uint8_t lookup_me8 = 0; 29741.54Skamil uint16_t lookup_me16 = 0; 29751.54Skamil uint32_t lookup_me32 = 0; 29761.54Skamil uint64_t lookup_me64 = 0; 29771.1Skamil 29781.54Skamil int magic = 0x13579246; 29791.54Skamil uint8_t magic8 = 0xab; 29801.54Skamil uint16_t magic16 = 0x1234; 29811.54Skamil uint32_t magic32 = 0x98765432; 29821.54Skamil uint64_t magic64 = 0xabcdef0123456789; 29831.1Skamil 29841.54Skamil struct ptrace_io_desc io; 29851.1Skamil#if defined(TWAIT_HAVE_STATUS) 29861.1Skamil int status; 29871.1Skamil#endif 29881.60Skre /* 513 is just enough, for the purposes of ATF it's good enough */ 29891.60Skre AuxInfo ai[513], *aip; 29901.55Schristos 29911.55Schristos ATF_REQUIRE(size < sizeof(ai)); 29921.1Skamil 29931.54Skamil /* Prepare variables for .TEXT transfers */ 29941.54Skamil switch (type) { 29951.54Skamil case BYTES_TRANSFER_TEXT: 29961.54Skamil memcpy(&magic, bytes_transfer_dummy, sizeof(magic)); 29971.54Skamil break; 29981.54Skamil case BYTES_TRANSFER_TEXTIO: 29991.54Skamil switch (size) { 30001.54Skamil case 8: 30011.54Skamil memcpy(&magic8, bytes_transfer_dummy, sizeof(magic8)); 30021.54Skamil break; 30031.54Skamil case 16: 30041.54Skamil memcpy(&magic16, bytes_transfer_dummy, sizeof(magic16)); 30051.54Skamil break; 30061.54Skamil case 32: 30071.54Skamil memcpy(&magic32, bytes_transfer_dummy, sizeof(magic32)); 30081.54Skamil break; 30091.54Skamil case 64: 30101.54Skamil memcpy(&magic64, bytes_transfer_dummy, sizeof(magic64)); 30111.54Skamil break; 30121.54Skamil } 30131.54Skamil break; 30141.54Skamil default: 30151.54Skamil break; 30161.54Skamil } 30171.1Skamil 30181.54Skamil /* Prepare variables for PIOD and AUXV transfers */ 30191.54Skamil switch (type) { 30201.54Skamil case BYTES_TRANSFER_TEXTIO: 30211.54Skamil case BYTES_TRANSFER_DATAIO: 30221.54Skamil io.piod_op = operation; 30231.54Skamil switch (size) { 30241.54Skamil case 8: 30251.54Skamil io.piod_offs = (type == BYTES_TRANSFER_TEXTIO) ? 30261.54Skamil (void *)bytes_transfer_dummy : 30271.54Skamil &lookup_me8; 30281.54Skamil io.piod_addr = &lookup_me8; 30291.54Skamil io.piod_len = sizeof(lookup_me8); 30301.54Skamil break; 30311.54Skamil case 16: 30321.54Skamil io.piod_offs = (type == BYTES_TRANSFER_TEXTIO) ? 30331.54Skamil (void *)bytes_transfer_dummy : 30341.54Skamil &lookup_me16; 30351.54Skamil io.piod_addr = &lookup_me16; 30361.54Skamil io.piod_len = sizeof(lookup_me16); 30371.54Skamil break; 30381.54Skamil case 32: 30391.54Skamil io.piod_offs = (type == BYTES_TRANSFER_TEXTIO) ? 30401.54Skamil (void *)bytes_transfer_dummy : 30411.54Skamil &lookup_me32; 30421.54Skamil io.piod_addr = &lookup_me32; 30431.54Skamil io.piod_len = sizeof(lookup_me32); 30441.54Skamil break; 30451.54Skamil case 64: 30461.54Skamil io.piod_offs = (type == BYTES_TRANSFER_TEXTIO) ? 30471.54Skamil (void *)bytes_transfer_dummy : 30481.54Skamil &lookup_me64; 30491.54Skamil io.piod_addr = &lookup_me64; 30501.54Skamil io.piod_len = sizeof(lookup_me64); 30511.54Skamil break; 30521.54Skamil default: 30531.54Skamil break; 30541.54Skamil } 30551.54Skamil break; 30561.54Skamil case BYTES_TRANSFER_AUXV: 30571.54Skamil io.piod_op = operation; 30581.54Skamil io.piod_offs = 0; 30591.54Skamil io.piod_addr = ai; 30601.54Skamil io.piod_len = size; 30611.54Skamil break; 30621.54Skamil default: 30631.54Skamil break; 30641.1Skamil } 30651.1Skamil 30661.13Schristos DPRINTF("Before forking process PID=%d\n", getpid()); 30671.13Schristos SYSCALL_REQUIRE((child = fork()) != -1); 30681.1Skamil if (child == 0) { 30691.13Schristos DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 30701.1Skamil FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 30711.1Skamil 30721.54Skamil switch (type) { 30731.54Skamil case BYTES_TRANSFER_DATA: 30741.54Skamil switch (operation) { 30751.54Skamil case PT_READ_D: 30761.54Skamil case PT_READ_I: 30771.54Skamil lookup_me = magic; 30781.54Skamil break; 30791.54Skamil default: 30801.54Skamil break; 30811.54Skamil } 30821.54Skamil break; 30831.54Skamil case BYTES_TRANSFER_DATAIO: 30841.54Skamil switch (operation) { 30851.54Skamil case PIOD_READ_D: 30861.54Skamil case PIOD_READ_I: 30871.54Skamil switch (size) { 30881.54Skamil case 8: 30891.54Skamil lookup_me8 = magic8; 30901.54Skamil break; 30911.54Skamil case 16: 30921.54Skamil lookup_me16 = magic16; 30931.54Skamil break; 30941.54Skamil case 32: 30951.54Skamil lookup_me32 = magic32; 30961.54Skamil break; 30971.54Skamil case 64: 30981.54Skamil lookup_me64 = magic64; 30991.54Skamil break; 31001.54Skamil default: 31011.54Skamil break; 31021.54Skamil } 31031.54Skamil break; 31041.54Skamil default: 31051.54Skamil break; 31061.54Skamil } 31071.54Skamil default: 31081.54Skamil break; 31091.54Skamil } 31101.54Skamil 31111.13Schristos DPRINTF("Before raising %s from child\n", strsignal(sigval)); 31121.1Skamil FORKEE_ASSERT(raise(sigval) == 0); 31131.1Skamil 31141.54Skamil /* Handle PIOD and PT separately as operation values overlap */ 31151.54Skamil switch (type) { 31161.54Skamil case BYTES_TRANSFER_DATA: 31171.54Skamil switch (operation) { 31181.54Skamil case PT_WRITE_D: 31191.54Skamil case PT_WRITE_I: 31201.54Skamil FORKEE_ASSERT_EQ(lookup_me, magic); 31211.54Skamil break; 31221.54Skamil default: 31231.54Skamil break; 31241.54Skamil } 31251.54Skamil break; 31261.54Skamil case BYTES_TRANSFER_DATAIO: 31271.54Skamil switch (operation) { 31281.54Skamil case PIOD_WRITE_D: 31291.54Skamil case PIOD_WRITE_I: 31301.54Skamil switch (size) { 31311.54Skamil case 8: 31321.54Skamil FORKEE_ASSERT_EQ(lookup_me8, magic8); 31331.54Skamil break; 31341.54Skamil case 16: 31351.54Skamil FORKEE_ASSERT_EQ(lookup_me16, magic16); 31361.54Skamil break; 31371.54Skamil case 32: 31381.54Skamil FORKEE_ASSERT_EQ(lookup_me32, magic32); 31391.54Skamil break; 31401.54Skamil case 64: 31411.54Skamil FORKEE_ASSERT_EQ(lookup_me64, magic64); 31421.54Skamil break; 31431.54Skamil default: 31441.54Skamil break; 31451.54Skamil } 31461.54Skamil break; 31471.54Skamil default: 31481.54Skamil break; 31491.54Skamil } 31501.54Skamil break; 31511.54Skamil case BYTES_TRANSFER_TEXT: 31521.54Skamil FORKEE_ASSERT(memcmp(&magic, bytes_transfer_dummy, 31531.54Skamil sizeof(magic)) == 0); 31541.54Skamil break; 31551.54Skamil case BYTES_TRANSFER_TEXTIO: 31561.54Skamil switch (size) { 31571.54Skamil case 8: 31581.54Skamil FORKEE_ASSERT(memcmp(&magic8, 31591.54Skamil bytes_transfer_dummy, 31601.54Skamil sizeof(magic8)) == 0); 31611.54Skamil break; 31621.54Skamil case 16: 31631.54Skamil FORKEE_ASSERT(memcmp(&magic16, 31641.54Skamil bytes_transfer_dummy, 31651.54Skamil sizeof(magic16)) == 0); 31661.54Skamil break; 31671.54Skamil case 32: 31681.54Skamil FORKEE_ASSERT(memcmp(&magic32, 31691.54Skamil bytes_transfer_dummy, 31701.54Skamil sizeof(magic32)) == 0); 31711.54Skamil break; 31721.54Skamil case 64: 31731.54Skamil FORKEE_ASSERT(memcmp(&magic64, 31741.54Skamil bytes_transfer_dummy, 31751.54Skamil sizeof(magic64)) == 0); 31761.54Skamil break; 31771.54Skamil } 31781.54Skamil break; 31791.54Skamil default: 31801.54Skamil break; 31811.54Skamil } 31821.54Skamil 31831.13Schristos DPRINTF("Before exiting of the child process\n"); 31841.1Skamil _exit(exitval); 31851.1Skamil } 31861.13Schristos DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 31871.1Skamil 31881.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 31891.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 31901.1Skamil 31911.1Skamil validate_status_stopped(status, sigval); 31921.1Skamil 31931.54Skamil /* Check PaX MPROTECT */ 31941.54Skamil if (!can_we_write_to_text(child)) { 31951.54Skamil switch (type) { 31961.54Skamil case BYTES_TRANSFER_TEXTIO: 31971.54Skamil switch (operation) { 31981.54Skamil case PIOD_WRITE_D: 31991.54Skamil case PIOD_WRITE_I: 32001.54Skamil skip = true; 32011.54Skamil break; 32021.54Skamil default: 32031.54Skamil break; 32041.54Skamil } 32051.54Skamil break; 32061.54Skamil case BYTES_TRANSFER_TEXT: 32071.54Skamil switch (operation) { 32081.54Skamil case PT_WRITE_D: 32091.54Skamil case PT_WRITE_I: 32101.54Skamil skip = true; 32111.54Skamil break; 32121.54Skamil default: 32131.54Skamil break; 32141.54Skamil } 32151.54Skamil break; 32161.54Skamil default: 32171.54Skamil break; 32181.54Skamil } 32191.54Skamil } 32201.1Skamil 32211.54Skamil /* Bailout cleanly killing the child process */ 32221.54Skamil if (skip) { 32231.54Skamil SYSCALL_REQUIRE(ptrace(PT_KILL, child, (void *)1, 0) != -1); 32241.54Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 32251.54Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), 32261.54Skamil child); 32271.1Skamil 32281.54Skamil validate_status_signaled(status, SIGKILL, 0); 32291.1Skamil 32301.54Skamil atf_tc_skip("PaX MPROTECT setup prevents writes to .text"); 32311.54Skamil } 32321.1Skamil 32331.54Skamil DPRINTF("Calling operation to transfer bytes between child=%d and " 32341.54Skamil "parent=%d\n", child, getpid()); 32351.1Skamil 32361.54Skamil switch (type) { 32371.54Skamil case BYTES_TRANSFER_TEXTIO: 32381.54Skamil case BYTES_TRANSFER_DATAIO: 32391.54Skamil case BYTES_TRANSFER_AUXV: 32401.54Skamil switch (operation) { 32411.54Skamil case PIOD_WRITE_D: 32421.54Skamil case PIOD_WRITE_I: 32431.54Skamil switch (size) { 32441.54Skamil case 8: 32451.54Skamil lookup_me8 = magic8; 32461.54Skamil break; 32471.54Skamil case 16: 32481.54Skamil lookup_me16 = magic16; 32491.54Skamil break; 32501.54Skamil case 32: 32511.54Skamil lookup_me32 = magic32; 32521.54Skamil break; 32531.54Skamil case 64: 32541.54Skamil lookup_me64 = magic64; 32551.54Skamil break; 32561.54Skamil default: 32571.54Skamil break; 32581.54Skamil } 32591.54Skamil break; 32601.54Skamil default: 32611.54Skamil break; 32621.54Skamil } 32631.54Skamil SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1); 32641.54Skamil switch (operation) { 32651.54Skamil case PIOD_READ_D: 32661.54Skamil case PIOD_READ_I: 32671.54Skamil switch (size) { 32681.54Skamil case 8: 32691.54Skamil ATF_REQUIRE_EQ(lookup_me8, magic8); 32701.54Skamil break; 32711.54Skamil case 16: 32721.54Skamil ATF_REQUIRE_EQ(lookup_me16, magic16); 32731.54Skamil break; 32741.54Skamil case 32: 32751.54Skamil ATF_REQUIRE_EQ(lookup_me32, magic32); 32761.54Skamil break; 32771.54Skamil case 64: 32781.54Skamil ATF_REQUIRE_EQ(lookup_me64, magic64); 32791.54Skamil break; 32801.54Skamil default: 32811.54Skamil break; 32821.54Skamil } 32831.54Skamil break; 32841.54Skamil case PIOD_READ_AUXV: 32851.54Skamil DPRINTF("Asserting that AUXV length (%zu) is > 0\n", 32861.54Skamil io.piod_len); 32871.54Skamil ATF_REQUIRE(io.piod_len > 0); 32881.54Skamil for (aip = ai; aip->a_type != AT_NULL; aip++) 32891.54Skamil DPRINTF("a_type=%#llx a_v=%#llx\n", 32901.54Skamil (long long int)aip->a_type, 32911.54Skamil (long long int)aip->a_v); 32921.54Skamil break; 32931.54Skamil default: 32941.54Skamil break; 32951.54Skamil } 32961.54Skamil break; 32971.54Skamil case BYTES_TRANSFER_TEXT: 32981.54Skamil switch (operation) { 32991.54Skamil case PT_READ_D: 33001.54Skamil case PT_READ_I: 33011.54Skamil errno = 0; 33021.54Skamil lookup_me = ptrace(operation, child, 33031.54Skamil bytes_transfer_dummy, 0); 33041.54Skamil ATF_REQUIRE_EQ(lookup_me, magic); 33051.54Skamil SYSCALL_REQUIRE_ERRNO(errno, 0); 33061.54Skamil break; 33071.54Skamil case PT_WRITE_D: 33081.54Skamil case PT_WRITE_I: 33091.54Skamil SYSCALL_REQUIRE(ptrace(operation, child, 33101.54Skamil bytes_transfer_dummy, magic) 33111.54Skamil != -1); 33121.54Skamil break; 33131.54Skamil default: 33141.54Skamil break; 33151.54Skamil } 33161.54Skamil break; 33171.54Skamil case BYTES_TRANSFER_DATA: 33181.54Skamil switch (operation) { 33191.54Skamil case PT_READ_D: 33201.54Skamil case PT_READ_I: 33211.54Skamil errno = 0; 33221.54Skamil lookup_me = ptrace(operation, child, &lookup_me, 0); 33231.54Skamil ATF_REQUIRE_EQ(lookup_me, magic); 33241.54Skamil SYSCALL_REQUIRE_ERRNO(errno, 0); 33251.54Skamil break; 33261.54Skamil case PT_WRITE_D: 33271.54Skamil case PT_WRITE_I: 33281.54Skamil lookup_me = magic; 33291.54Skamil SYSCALL_REQUIRE(ptrace(operation, child, &lookup_me, 33301.54Skamil magic) != -1); 33311.54Skamil break; 33321.54Skamil default: 33331.54Skamil break; 33341.54Skamil } 33351.54Skamil break; 33361.54Skamil default: 33371.54Skamil break; 33381.54Skamil } 33391.1Skamil 33401.13Schristos DPRINTF("Before resuming the child process where it left off and " 33411.1Skamil "without signal to be sent\n"); 33421.13Schristos SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 33431.1Skamil 33441.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 33451.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 33461.1Skamil 33471.1Skamil validate_status_exited(status, exitval); 33481.1Skamil 33491.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 33501.1Skamil TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 33511.1Skamil} 33521.1Skamil 33531.61Skre#define BYTES_TRANSFER(test, operation, size, type) \ 33541.61SkreATF_TC(test); \ 33551.61SkreATF_TC_HEAD(test, tc) \ 33561.61Skre{ \ 33571.61Skre atf_tc_set_md_var(tc, "descr", \ 33581.61Skre "Verify bytes transfer operation" #operation " and size " #size \ 33591.61Skre " of type " #type); \ 33601.61Skre} \ 33611.61Skre \ 33621.61SkreATF_TC_BODY(test, tc) \ 33631.61Skre{ \ 33641.61Skre \ 33651.61Skre bytes_transfer(operation, size, BYTES_TRANSFER_##type); \ 33661.1Skamil} 33671.1Skamil 33681.54Skamil// DATA 33691.1Skamil 33701.54SkamilBYTES_TRANSFER(bytes_transfer_piod_read_d_8, PIOD_READ_D, 8, DATAIO) 33711.54SkamilBYTES_TRANSFER(bytes_transfer_piod_read_d_16, PIOD_READ_D, 16, DATAIO) 33721.54SkamilBYTES_TRANSFER(bytes_transfer_piod_read_d_32, PIOD_READ_D, 32, DATAIO) 33731.54SkamilBYTES_TRANSFER(bytes_transfer_piod_read_d_64, PIOD_READ_D, 64, DATAIO) 33741.54Skamil 33751.54SkamilBYTES_TRANSFER(bytes_transfer_piod_read_i_8, PIOD_READ_I, 8, DATAIO) 33761.54SkamilBYTES_TRANSFER(bytes_transfer_piod_read_i_16, PIOD_READ_I, 16, DATAIO) 33771.54SkamilBYTES_TRANSFER(bytes_transfer_piod_read_i_32, PIOD_READ_I, 32, DATAIO) 33781.54SkamilBYTES_TRANSFER(bytes_transfer_piod_read_i_64, PIOD_READ_I, 64, DATAIO) 33791.54Skamil 33801.54SkamilBYTES_TRANSFER(bytes_transfer_piod_write_d_8, PIOD_WRITE_D, 8, DATAIO) 33811.54SkamilBYTES_TRANSFER(bytes_transfer_piod_write_d_16, PIOD_WRITE_D, 16, DATAIO) 33821.54SkamilBYTES_TRANSFER(bytes_transfer_piod_write_d_32, PIOD_WRITE_D, 32, DATAIO) 33831.54SkamilBYTES_TRANSFER(bytes_transfer_piod_write_d_64, PIOD_WRITE_D, 64, DATAIO) 33841.54Skamil 33851.54SkamilBYTES_TRANSFER(bytes_transfer_piod_write_i_8, PIOD_WRITE_I, 8, DATAIO) 33861.54SkamilBYTES_TRANSFER(bytes_transfer_piod_write_i_16, PIOD_WRITE_I, 16, DATAIO) 33871.54SkamilBYTES_TRANSFER(bytes_transfer_piod_write_i_32, PIOD_WRITE_I, 32, DATAIO) 33881.54SkamilBYTES_TRANSFER(bytes_transfer_piod_write_i_64, PIOD_WRITE_I, 64, DATAIO) 33891.54Skamil 33901.54SkamilBYTES_TRANSFER(bytes_transfer_read_d, PT_READ_D, 32, DATA) 33911.54SkamilBYTES_TRANSFER(bytes_transfer_read_i, PT_READ_I, 32, DATA) 33921.54SkamilBYTES_TRANSFER(bytes_transfer_write_d, PT_WRITE_D, 32, DATA) 33931.54SkamilBYTES_TRANSFER(bytes_transfer_write_i, PT_WRITE_I, 32, DATA) 33941.54Skamil 33951.54Skamil// TEXT 33961.54Skamil 33971.54SkamilBYTES_TRANSFER(bytes_transfer_piod_read_d_8_text, PIOD_READ_D, 8, TEXTIO) 33981.54SkamilBYTES_TRANSFER(bytes_transfer_piod_read_d_16_text, PIOD_READ_D, 16, TEXTIO) 33991.54SkamilBYTES_TRANSFER(bytes_transfer_piod_read_d_32_text, PIOD_READ_D, 32, TEXTIO) 34001.54SkamilBYTES_TRANSFER(bytes_transfer_piod_read_d_64_text, PIOD_READ_D, 64, TEXTIO) 34011.54Skamil 34021.54SkamilBYTES_TRANSFER(bytes_transfer_piod_read_i_8_text, PIOD_READ_I, 8, TEXTIO) 34031.54SkamilBYTES_TRANSFER(bytes_transfer_piod_read_i_16_text, PIOD_READ_I, 16, TEXTIO) 34041.54SkamilBYTES_TRANSFER(bytes_transfer_piod_read_i_32_text, PIOD_READ_I, 32, TEXTIO) 34051.54SkamilBYTES_TRANSFER(bytes_transfer_piod_read_i_64_text, PIOD_READ_I, 64, TEXTIO) 34061.54Skamil 34071.54SkamilBYTES_TRANSFER(bytes_transfer_piod_write_d_8_text, PIOD_WRITE_D, 8, TEXTIO) 34081.54SkamilBYTES_TRANSFER(bytes_transfer_piod_write_d_16_text, PIOD_WRITE_D, 16, TEXTIO) 34091.54SkamilBYTES_TRANSFER(bytes_transfer_piod_write_d_32_text, PIOD_WRITE_D, 32, TEXTIO) 34101.54SkamilBYTES_TRANSFER(bytes_transfer_piod_write_d_64_text, PIOD_WRITE_D, 64, TEXTIO) 34111.54Skamil 34121.54SkamilBYTES_TRANSFER(bytes_transfer_piod_write_i_8_text, PIOD_WRITE_I, 8, TEXTIO) 34131.54SkamilBYTES_TRANSFER(bytes_transfer_piod_write_i_16_text, PIOD_WRITE_I, 16, TEXTIO) 34141.54SkamilBYTES_TRANSFER(bytes_transfer_piod_write_i_32_text, PIOD_WRITE_I, 32, TEXTIO) 34151.54SkamilBYTES_TRANSFER(bytes_transfer_piod_write_i_64_text, PIOD_WRITE_I, 64, TEXTIO) 34161.54Skamil 34171.54SkamilBYTES_TRANSFER(bytes_transfer_read_d_text, PT_READ_D, 32, TEXT) 34181.54SkamilBYTES_TRANSFER(bytes_transfer_read_i_text, PT_READ_I, 32, TEXT) 34191.54SkamilBYTES_TRANSFER(bytes_transfer_write_d_text, PT_WRITE_D, 32, TEXT) 34201.54SkamilBYTES_TRANSFER(bytes_transfer_write_i_text, PT_WRITE_I, 32, TEXT) 34211.1Skamil 34221.54Skamil// AUXV 34231.1Skamil 34241.54SkamilBYTES_TRANSFER(bytes_transfer_piod_read_auxv, PIOD_READ_AUXV, 4096, AUXV) 34251.1Skamil 34261.54Skamil/// ---------------------------------------------------------------------------- 34271.1Skamil 34281.76Sscole#if defined(HAVE_GPREGS) || defined(HAVE_FPREGS) 34291.72Skamilstatic void 34301.72Skamilaccess_regs(const char *regset, const char *aux) 34311.1Skamil{ 34321.1Skamil const int exitval = 5; 34331.1Skamil const int sigval = SIGSTOP; 34341.1Skamil pid_t child, wpid; 34351.1Skamil#if defined(TWAIT_HAVE_STATUS) 34361.1Skamil int status; 34371.1Skamil#endif 34381.72Skamil#if defined(HAVE_GPREGS) 34391.72Skamil struct reg gpr; 34401.76Sscole register_t rgstr; 34411.1Skamil#endif 34421.72Skamil#if defined(HAVE_FPREGS) 34431.72Skamil struct fpreg fpr; 34441.1Skamil#endif 34451.76Sscole 34461.72Skamil#if !defined(HAVE_GPREGS) 34471.72Skamil if (strcmp(regset, "regs") == 0) 34481.72Skamil atf_tc_fail("Impossible test scenario!"); 34491.1Skamil#endif 34501.1Skamil 34511.72Skamil#if !defined(HAVE_FPREGS) 34521.72Skamil if (strcmp(regset, "fpregs") == 0) 34531.72Skamil atf_tc_fail("Impossible test scenario!"); 34541.1Skamil#endif 34551.1Skamil 34561.13Schristos DPRINTF("Before forking process PID=%d\n", getpid()); 34571.13Schristos SYSCALL_REQUIRE((child = fork()) != -1); 34581.1Skamil if (child == 0) { 34591.13Schristos DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 34601.1Skamil FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 34611.1Skamil 34621.13Schristos DPRINTF("Before raising %s from child\n", strsignal(sigval)); 34631.1Skamil FORKEE_ASSERT(raise(sigval) == 0); 34641.1Skamil 34651.13Schristos DPRINTF("Before exiting of the child process\n"); 34661.1Skamil _exit(exitval); 34671.1Skamil } 34681.13Schristos DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 34691.1Skamil 34701.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 34711.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 34721.1Skamil 34731.1Skamil validate_status_stopped(status, sigval); 34741.1Skamil 34751.1Skamil#if defined(HAVE_GPREGS) 34761.72Skamil if (strcmp(regset, "regs") == 0) { 34771.72Skamil DPRINTF("Call GETREGS for the child process\n"); 34781.72Skamil SYSCALL_REQUIRE(ptrace(PT_GETREGS, child, &gpr, 0) != -1); 34791.72Skamil 34801.72Skamil if (strcmp(aux, "none") == 0) { 34811.72Skamil DPRINTF("Retrieved registers\n"); 34821.72Skamil } else if (strcmp(aux, "pc") == 0) { 34831.72Skamil rgstr = PTRACE_REG_PC(&gpr); 34841.72Skamil DPRINTF("Retrieved %" PRIxREGISTER "\n", rgstr); 34851.72Skamil } else if (strcmp(aux, "set_pc") == 0) { 34861.72Skamil rgstr = PTRACE_REG_PC(&gpr); 34871.72Skamil PTRACE_REG_SET_PC(&gpr, rgstr); 34881.72Skamil } else if (strcmp(aux, "sp") == 0) { 34891.72Skamil rgstr = PTRACE_REG_SP(&gpr); 34901.72Skamil DPRINTF("Retrieved %" PRIxREGISTER "\n", rgstr); 34911.72Skamil } else if (strcmp(aux, "intrv") == 0) { 34921.72Skamil rgstr = PTRACE_REG_INTRV(&gpr); 34931.72Skamil DPRINTF("Retrieved %" PRIxREGISTER "\n", rgstr); 34941.72Skamil } else if (strcmp(aux, "setregs") == 0) { 34951.72Skamil DPRINTF("Call SETREGS for the child process\n"); 34961.72Skamil SYSCALL_REQUIRE( 34971.72Skamil ptrace(PT_GETREGS, child, &gpr, 0) != -1); 34981.72Skamil } 34991.72Skamil } 35001.1Skamil#endif 35011.1Skamil 35021.72Skamil#if defined(HAVE_FPREGS) 35031.72Skamil if (strcmp(regset, "fpregs") == 0) { 35041.72Skamil DPRINTF("Call GETFPREGS for the child process\n"); 35051.72Skamil SYSCALL_REQUIRE(ptrace(PT_GETFPREGS, child, &fpr, 0) != -1); 35061.72Skamil 35071.72Skamil if (strcmp(aux, "getfpregs") == 0) { 35081.72Skamil DPRINTF("Retrieved FP registers\n"); 35091.72Skamil } else if (strcmp(aux, "setfpregs") == 0) { 35101.72Skamil DPRINTF("Call SETFPREGS for the child\n"); 35111.72Skamil SYSCALL_REQUIRE( 35121.72Skamil ptrace(PT_SETFPREGS, child, &fpr, 0) != -1); 35131.72Skamil } 35141.1Skamil } 35151.1Skamil#endif 35161.1Skamil 35171.13Schristos DPRINTF("Before resuming the child process where it left off and " 35181.1Skamil "without signal to be sent\n"); 35191.13Schristos SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 35201.1Skamil 35211.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 35221.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 35231.1Skamil 35241.1Skamil validate_status_exited(status, exitval); 35251.1Skamil 35261.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 35271.1Skamil TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 35281.1Skamil} 35291.1Skamil 35301.72Skamil#define ACCESS_REGS(test, regset, aux) \ 35311.72SkamilATF_TC(test); \ 35321.72SkamilATF_TC_HEAD(test, tc) \ 35331.72Skamil{ \ 35341.72Skamil atf_tc_set_md_var(tc, "descr", \ 35351.72Skamil "Verify " regset " with auxiliary operation: " aux); \ 35361.72Skamil} \ 35371.72Skamil \ 35381.72SkamilATF_TC_BODY(test, tc) \ 35391.72Skamil{ \ 35401.72Skamil \ 35411.72Skamil access_regs(regset, aux); \ 35421.1Skamil} 35431.1Skamil#endif 35441.1Skamil 35451.72Skamil#if defined(HAVE_GPREGS) 35461.72SkamilACCESS_REGS(access_regs1, "regs", "none") 35471.72SkamilACCESS_REGS(access_regs2, "regs", "pc") 35481.72SkamilACCESS_REGS(access_regs3, "regs", "set_pc") 35491.72SkamilACCESS_REGS(access_regs4, "regs", "sp") 35501.72SkamilACCESS_REGS(access_regs5, "regs", "intrv") 35511.72SkamilACCESS_REGS(access_regs6, "regs", "setregs") 35521.1Skamil#endif 35531.1Skamil#if defined(HAVE_FPREGS) 35541.72SkamilACCESS_REGS(access_fpregs1, "fpregs", "getfpregs") 35551.72SkamilACCESS_REGS(access_fpregs2, "fpregs", "setfpregs") 35561.1Skamil#endif 35571.1Skamil 35581.72Skamil/// ---------------------------------------------------------------------------- 35591.1Skamil 35601.1Skamil#if defined(PT_STEP) 35611.1Skamilstatic void 35621.2Skamilptrace_step(int N, int setstep) 35631.1Skamil{ 35641.1Skamil const int exitval = 5; 35651.1Skamil const int sigval = SIGSTOP; 35661.1Skamil pid_t child, wpid; 35671.1Skamil#if defined(TWAIT_HAVE_STATUS) 35681.1Skamil int status; 35691.1Skamil#endif 35701.1Skamil int happy; 35711.81Skamil struct ptrace_siginfo info; 35721.1Skamil 35731.1Skamil#if defined(__arm__) 35741.1Skamil /* PT_STEP not supported on arm 32-bit */ 35751.1Skamil atf_tc_expect_fail("PR kern/52119"); 35761.1Skamil#endif 35771.1Skamil 35781.13Schristos DPRINTF("Before forking process PID=%d\n", getpid()); 35791.13Schristos SYSCALL_REQUIRE((child = fork()) != -1); 35801.1Skamil if (child == 0) { 35811.13Schristos DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 35821.1Skamil FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 35831.1Skamil 35841.1Skamil happy = check_happy(999); 35851.1Skamil 35861.13Schristos DPRINTF("Before raising %s from child\n", strsignal(sigval)); 35871.1Skamil FORKEE_ASSERT(raise(sigval) == 0); 35881.1Skamil 35891.1Skamil FORKEE_ASSERT_EQ(happy, check_happy(999)); 35901.1Skamil 35911.13Schristos DPRINTF("Before exiting of the child process\n"); 35921.1Skamil _exit(exitval); 35931.1Skamil } 35941.13Schristos DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 35951.1Skamil 35961.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 35971.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 35981.1Skamil 35991.1Skamil validate_status_stopped(status, sigval); 36001.1Skamil 36011.81Skamil DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 36021.81Skamil SYSCALL_REQUIRE( 36031.81Skamil ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 36041.81Skamil 36051.81Skamil DPRINTF("Before checking siginfo_t\n"); 36061.81Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 36071.81Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 36081.81Skamil 36091.1Skamil while (N --> 0) { 36101.2Skamil if (setstep) { 36111.13Schristos DPRINTF("Before resuming the child process where it " 36121.2Skamil "left off and without signal to be sent (use " 36131.9Skamil "PT_SETSTEP and PT_CONTINUE)\n"); 36141.13Schristos SYSCALL_REQUIRE(ptrace(PT_SETSTEP, child, 0, 0) != -1); 36151.13Schristos SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) 36161.2Skamil != -1); 36171.2Skamil } else { 36181.13Schristos DPRINTF("Before resuming the child process where it " 36191.2Skamil "left off and without signal to be sent (use " 36201.2Skamil "PT_STEP)\n"); 36211.13Schristos SYSCALL_REQUIRE(ptrace(PT_STEP, child, (void *)1, 0) 36221.2Skamil != -1); 36231.2Skamil } 36241.1Skamil 36251.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 36261.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), 36271.1Skamil child); 36281.1Skamil 36291.1Skamil validate_status_stopped(status, SIGTRAP); 36301.2Skamil 36311.81Skamil DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 36321.81Skamil SYSCALL_REQUIRE( 36331.81Skamil ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 36341.81Skamil 36351.81Skamil DPRINTF("Before checking siginfo_t\n"); 36361.81Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); 36371.81Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_TRACE); 36381.81Skamil 36391.2Skamil if (setstep) { 36401.13Schristos SYSCALL_REQUIRE(ptrace(PT_CLEARSTEP, child, 0, 0) != -1); 36411.2Skamil } 36421.1Skamil } 36431.1Skamil 36441.13Schristos DPRINTF("Before resuming the child process where it left off and " 36451.1Skamil "without signal to be sent\n"); 36461.13Schristos SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 36471.1Skamil 36481.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 36491.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 36501.1Skamil 36511.1Skamil validate_status_exited(status, exitval); 36521.1Skamil 36531.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 36541.1Skamil TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 36551.1Skamil} 36561.1Skamil 36571.73Skamil#define PTRACE_STEP(test, N, setstep) \ 36581.73SkamilATF_TC(test); \ 36591.73SkamilATF_TC_HEAD(test, tc) \ 36601.73Skamil{ \ 36611.73Skamil atf_tc_set_md_var(tc, "descr", \ 36621.74Skamil "Verify " #N " (PT_SETSTEP set to: " #setstep ")"); \ 36631.73Skamil} \ 36641.73Skamil \ 36651.73SkamilATF_TC_BODY(test, tc) \ 36661.73Skamil{ \ 36671.73Skamil \ 36681.73Skamil ptrace_step(N, setstep); \ 36691.1Skamil} 36701.1Skamil 36711.73SkamilPTRACE_STEP(step1, 1, 0) 36721.73SkamilPTRACE_STEP(step2, 2, 0) 36731.73SkamilPTRACE_STEP(step3, 3, 0) 36741.73SkamilPTRACE_STEP(step4, 4, 0) 36751.73SkamilPTRACE_STEP(setstep1, 1, 1) 36761.73SkamilPTRACE_STEP(setstep2, 2, 1) 36771.73SkamilPTRACE_STEP(setstep3, 3, 1) 36781.73SkamilPTRACE_STEP(setstep4, 4, 1) 36791.1Skamil#endif 36801.1Skamil 36811.73Skamil/// ---------------------------------------------------------------------------- 36821.1Skamil 36831.75Skamilstatic void 36841.75Skamilptrace_kill(const char *type) 36851.1Skamil{ 36861.75Skamil const int sigval = SIGSTOP; 36871.1Skamil pid_t child, wpid; 36881.1Skamil#if defined(TWAIT_HAVE_STATUS) 36891.1Skamil int status; 36901.1Skamil#endif 36911.1Skamil 36921.13Schristos DPRINTF("Before forking process PID=%d\n", getpid()); 36931.13Schristos SYSCALL_REQUIRE((child = fork()) != -1); 36941.1Skamil if (child == 0) { 36951.13Schristos DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 36961.1Skamil FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 36971.1Skamil 36981.13Schristos DPRINTF("Before raising %s from child\n", strsignal(sigval)); 36991.1Skamil FORKEE_ASSERT(raise(sigval) == 0); 37001.1Skamil 37011.1Skamil /* NOTREACHED */ 37021.1Skamil FORKEE_ASSERTX(0 && 37031.1Skamil "Child should be terminated by a signal from its parent"); 37041.1Skamil } 37051.13Schristos DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 37061.1Skamil 37071.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 37081.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 37091.1Skamil 37101.1Skamil validate_status_stopped(status, sigval); 37111.1Skamil 37121.75Skamil DPRINTF("Before killing the child process with %s\n", type); 37131.75Skamil if (strcmp(type, "ptrace(PT_KILL)") == 0) { 37141.75Skamil SYSCALL_REQUIRE(ptrace(PT_KILL, child, (void*)1, 0) != -1); 37151.75Skamil } else if (strcmp(type, "kill(SIGKILL)") == 0) { 37161.75Skamil kill(child, SIGKILL); 37171.75Skamil } else if (strcmp(type, "killpg(SIGKILL)") == 0) { 37181.75Skamil setpgid(child, 0); 37191.75Skamil killpg(getpgid(child), SIGKILL); 37201.75Skamil } 37211.1Skamil 37221.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 37231.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 37241.1Skamil 37251.75Skamil validate_status_signaled(status, SIGKILL, 0); 37261.1Skamil 37271.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 37281.1Skamil TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 37291.1Skamil} 37301.1Skamil 37311.75Skamil#define PTRACE_KILL(test, type) \ 37321.75SkamilATF_TC(test); \ 37331.75SkamilATF_TC_HEAD(test, tc) \ 37341.75Skamil{ \ 37351.75Skamil atf_tc_set_md_var(tc, "descr", \ 37361.75Skamil "Verify killing the child with " type); \ 37371.75Skamil} \ 37381.75Skamil \ 37391.75SkamilATF_TC_BODY(test, tc) \ 37401.75Skamil{ \ 37411.75Skamil \ 37421.75Skamil ptrace_kill(type); \ 37431.1Skamil} 37441.1Skamil 37451.75Skamil// PT_CONTINUE with SIGKILL is covered by traceme_sendsignal_simple1 37461.75SkamilPTRACE_KILL(kill1, "ptrace(PT_KILL)") 37471.75SkamilPTRACE_KILL(kill2, "kill(SIGKILL)") 37481.75SkamilPTRACE_KILL(kill3, "killpg(SIGKILL)") 37491.1Skamil 37501.75Skamil/// ---------------------------------------------------------------------------- 37511.1Skamil 37521.77Skamilstatic void 37531.77Skamiltraceme_lwpinfo(const int threads) 37541.1Skamil{ 37551.1Skamil const int sigval = SIGSTOP; 37561.77Skamil const int sigval2 = SIGINT; 37571.1Skamil pid_t child, wpid; 37581.1Skamil#if defined(TWAIT_HAVE_STATUS) 37591.1Skamil int status; 37601.1Skamil#endif 37611.77Skamil struct ptrace_lwpinfo lwp = {0, 0}; 37621.77Skamil struct ptrace_siginfo info; 37631.77Skamil 37641.77Skamil /* Maximum number of supported threads in this test */ 37651.77Skamil pthread_t t[3]; 37661.77Skamil int n, rv; 37671.77Skamil 37681.77Skamil ATF_REQUIRE((int)__arraycount(t) >= threads); 37691.1Skamil 37701.13Schristos DPRINTF("Before forking process PID=%d\n", getpid()); 37711.13Schristos SYSCALL_REQUIRE((child = fork()) != -1); 37721.1Skamil if (child == 0) { 37731.13Schristos DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 37741.1Skamil FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 37751.1Skamil 37761.13Schristos DPRINTF("Before raising %s from child\n", strsignal(sigval)); 37771.1Skamil FORKEE_ASSERT(raise(sigval) == 0); 37781.1Skamil 37791.77Skamil for (n = 0; n < threads; n++) { 37801.77Skamil rv = pthread_create(&t[n], NULL, infinite_thread, NULL); 37811.77Skamil FORKEE_ASSERT(rv == 0); 37821.77Skamil } 37831.77Skamil 37841.77Skamil DPRINTF("Before raising %s from child\n", strsignal(sigval2)); 37851.77Skamil FORKEE_ASSERT(raise(sigval2) == 0); 37861.77Skamil 37871.77Skamil /* NOTREACHED */ 37881.77Skamil FORKEE_ASSERTX(0 && "Not reached"); 37891.1Skamil } 37901.13Schristos DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 37911.1Skamil 37921.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 37931.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 37941.1Skamil 37951.1Skamil validate_status_stopped(status, sigval); 37961.1Skamil 37971.77Skamil DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child"); 37981.77Skamil SYSCALL_REQUIRE( 37991.77Skamil ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 38001.77Skamil 38011.77Skamil DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 38021.77Skamil DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 38031.77Skamil info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 38041.77Skamil info.psi_siginfo.si_errno); 38051.77Skamil 38061.77Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 38071.77Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 38081.77Skamil 38091.13Schristos DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n"); 38101.77Skamil SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &lwp, sizeof(lwp)) != -1); 38111.1Skamil 38121.77Skamil DPRINTF("Assert that there exists a single thread only\n"); 38131.77Skamil ATF_REQUIRE(lwp.pl_lwpid > 0); 38141.1Skamil 38151.13Schristos DPRINTF("Assert that lwp thread %d received event PL_EVENT_SIGNAL\n", 38161.77Skamil lwp.pl_lwpid); 38171.77Skamil FORKEE_ASSERT_EQ(lwp.pl_event, PL_EVENT_SIGNAL); 38181.1Skamil 38191.13Schristos DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n"); 38201.77Skamil SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &lwp, sizeof(lwp)) != -1); 38211.1Skamil 38221.77Skamil DPRINTF("Assert that there exists a single thread only\n"); 38231.77Skamil ATF_REQUIRE_EQ(lwp.pl_lwpid, 0); 38241.1Skamil 38251.13Schristos DPRINTF("Before resuming the child process where it left off and " 38261.1Skamil "without signal to be sent\n"); 38271.13Schristos SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 38281.1Skamil 38291.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 38301.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 38311.1Skamil 38321.77Skamil validate_status_stopped(status, sigval2); 38331.77Skamil 38341.77Skamil DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child"); 38351.77Skamil SYSCALL_REQUIRE( 38361.77Skamil ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 38371.77Skamil 38381.77Skamil DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 38391.77Skamil DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 38401.77Skamil info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 38411.77Skamil info.psi_siginfo.si_errno); 38421.77Skamil 38431.77Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval2); 38441.77Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 38451.77Skamil 38461.77Skamil memset(&lwp, 0, sizeof(lwp)); 38471.77Skamil 38481.77Skamil for (n = 0; n <= threads; n++) { 38491.77Skamil DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n"); 38501.77Skamil SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &lwp, sizeof(lwp)) != -1); 38511.77Skamil DPRINTF("LWP=%d\n", lwp.pl_lwpid); 38521.77Skamil 38531.77Skamil DPRINTF("Assert that the thread exists\n"); 38541.77Skamil ATF_REQUIRE(lwp.pl_lwpid > 0); 38551.77Skamil 38561.77Skamil DPRINTF("Assert that lwp thread %d received expected event\n", 38571.77Skamil lwp.pl_lwpid); 38581.77Skamil FORKEE_ASSERT_EQ(lwp.pl_event, info.psi_lwpid == lwp.pl_lwpid ? 38591.77Skamil PL_EVENT_SIGNAL : PL_EVENT_NONE); 38601.77Skamil } 38611.77Skamil DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n"); 38621.77Skamil SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &lwp, sizeof(lwp)) != -1); 38631.77Skamil DPRINTF("LWP=%d\n", lwp.pl_lwpid); 38641.77Skamil 38651.77Skamil DPRINTF("Assert that there are no more threads\n"); 38661.77Skamil ATF_REQUIRE_EQ(lwp.pl_lwpid, 0); 38671.77Skamil 38681.77Skamil DPRINTF("Before resuming the child process where it left off and " 38691.77Skamil "without signal to be sent\n"); 38701.77Skamil SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, SIGKILL) != -1); 38711.77Skamil 38721.77Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 38731.77Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 38741.77Skamil 38751.77Skamil validate_status_signaled(status, SIGKILL, 0); 38761.1Skamil 38771.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 38781.1Skamil TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 38791.1Skamil} 38801.1Skamil 38811.77Skamil#define TRACEME_LWPINFO(test, threads) \ 38821.77SkamilATF_TC(test); \ 38831.77SkamilATF_TC_HEAD(test, tc) \ 38841.77Skamil{ \ 38851.77Skamil atf_tc_set_md_var(tc, "descr", \ 38861.77Skamil "Verify LWPINFO with the child with " #threads \ 38871.77Skamil " spawned extra threads"); \ 38881.77Skamil} \ 38891.77Skamil \ 38901.77SkamilATF_TC_BODY(test, tc) \ 38911.77Skamil{ \ 38921.77Skamil \ 38931.77Skamil traceme_lwpinfo(threads); \ 38941.1Skamil} 38951.1Skamil 38961.77SkamilTRACEME_LWPINFO(traceme_lwpinfo0, 0) 38971.77SkamilTRACEME_LWPINFO(traceme_lwpinfo1, 1) 38981.77SkamilTRACEME_LWPINFO(traceme_lwpinfo2, 2) 38991.77SkamilTRACEME_LWPINFO(traceme_lwpinfo3, 3) 39001.77Skamil 39011.77Skamil/// ---------------------------------------------------------------------------- 39021.77Skamil 39031.77Skamil#if defined(TWAIT_HAVE_PID) 39041.77Skamilstatic void 39051.77Skamilattach_lwpinfo(const int threads) 39061.1Skamil{ 39071.77Skamil const int sigval = SIGINT; 39081.1Skamil struct msg_fds parent_tracee, parent_tracer; 39091.1Skamil const int exitval_tracer = 10; 39101.1Skamil pid_t tracee, tracer, wpid; 39111.1Skamil uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */ 39121.1Skamil#if defined(TWAIT_HAVE_STATUS) 39131.1Skamil int status; 39141.1Skamil#endif 39151.77Skamil struct ptrace_lwpinfo lwp = {0, 0}; 39161.77Skamil struct ptrace_siginfo info; 39171.77Skamil 39181.77Skamil /* Maximum number of supported threads in this test */ 39191.77Skamil pthread_t t[3]; 39201.77Skamil int n, rv; 39211.1Skamil 39221.13Schristos DPRINTF("Spawn tracee\n"); 39231.13Schristos SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0); 39241.13Schristos SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0); 39251.1Skamil tracee = atf_utils_fork(); 39261.1Skamil if (tracee == 0) { 39271.1Skamil /* Wait for message from the parent */ 39281.1Skamil CHILD_TO_PARENT("tracee ready", parent_tracee, msg); 39291.1Skamil 39301.77Skamil CHILD_FROM_PARENT("spawn threads", parent_tracee, msg); 39311.77Skamil 39321.77Skamil for (n = 0; n < threads; n++) { 39331.77Skamil rv = pthread_create(&t[n], NULL, infinite_thread, NULL); 39341.77Skamil FORKEE_ASSERT(rv == 0); 39351.77Skamil } 39361.77Skamil 39371.77Skamil CHILD_TO_PARENT("tracee exit", parent_tracee, msg); 39381.77Skamil 39391.77Skamil DPRINTF("Before raising %s from child\n", strsignal(sigval)); 39401.77Skamil FORKEE_ASSERT(raise(sigval) == 0); 39411.77Skamil 39421.77Skamil /* NOTREACHED */ 39431.77Skamil FORKEE_ASSERTX(0 && "Not reached"); 39441.1Skamil } 39451.1Skamil PARENT_FROM_CHILD("tracee ready", parent_tracee, msg); 39461.1Skamil 39471.13Schristos DPRINTF("Spawn debugger\n"); 39481.1Skamil tracer = atf_utils_fork(); 39491.1Skamil if (tracer == 0) { 39501.1Skamil /* No IPC to communicate with the child */ 39511.13Schristos DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid()); 39521.1Skamil FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1); 39531.1Skamil 39541.1Skamil /* Wait for tracee and assert that it was stopped w/ SIGSTOP */ 39551.1Skamil FORKEE_REQUIRE_SUCCESS( 39561.1Skamil wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 39571.1Skamil 39581.1Skamil forkee_status_stopped(status, SIGSTOP); 39591.1Skamil 39601.77Skamil DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for " 39611.77Skamil "tracee"); 39621.77Skamil FORKEE_ASSERT( 39631.77Skamil ptrace(PT_GET_SIGINFO, tracee, &info, sizeof(info)) != -1); 39641.77Skamil 39651.77Skamil DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 39661.77Skamil DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 39671.77Skamil "si_errno=%#x\n", 39681.77Skamil info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 39691.77Skamil info.psi_siginfo.si_errno); 39701.77Skamil 39711.77Skamil FORKEE_ASSERT_EQ(info.psi_siginfo.si_signo, SIGSTOP); 39721.77Skamil FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, SI_USER); 39731.77Skamil 39741.13Schristos DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n"); 39751.77Skamil FORKEE_ASSERT(ptrace(PT_LWPINFO, tracee, &lwp, sizeof(lwp)) 39761.1Skamil != -1); 39771.1Skamil 39781.13Schristos DPRINTF("Assert that there exists a thread\n"); 39791.77Skamil FORKEE_ASSERTX(lwp.pl_lwpid > 0); 39801.1Skamil 39811.13Schristos DPRINTF("Assert that lwp thread %d received event " 39821.77Skamil "PL_EVENT_SIGNAL\n", lwp.pl_lwpid); 39831.77Skamil FORKEE_ASSERT_EQ(lwp.pl_event, PL_EVENT_SIGNAL); 39841.1Skamil 39851.77Skamil DPRINTF("Before calling ptrace(2) with PT_LWPINFO for " 39861.77Skamil "tracee\n"); 39871.77Skamil FORKEE_ASSERT(ptrace(PT_LWPINFO, tracee, &lwp, sizeof(lwp)) 39881.1Skamil != -1); 39891.1Skamil 39901.77Skamil DPRINTF("Assert that there are no more lwp threads in " 39911.77Skamil "tracee\n"); 39921.77Skamil FORKEE_ASSERT_EQ(lwp.pl_lwpid, 0); 39931.1Skamil 39941.1Skamil /* Resume tracee with PT_CONTINUE */ 39951.1Skamil FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1); 39961.1Skamil 39971.1Skamil /* Inform parent that tracer has attached to tracee */ 39981.1Skamil CHILD_TO_PARENT("tracer ready", parent_tracer, msg); 39991.77Skamil 40001.1Skamil /* Wait for parent */ 40011.1Skamil CHILD_FROM_PARENT("tracer wait", parent_tracer, msg); 40021.1Skamil 40031.77Skamil /* Wait for tracee and assert that it raised a signal */ 40041.77Skamil FORKEE_REQUIRE_SUCCESS( 40051.77Skamil wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 40061.77Skamil 40071.77Skamil forkee_status_stopped(status, SIGINT); 40081.77Skamil 40091.77Skamil DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for " 40101.77Skamil "child"); 40111.77Skamil FORKEE_ASSERT( 40121.77Skamil ptrace(PT_GET_SIGINFO, tracee, &info, sizeof(info)) != -1); 40131.77Skamil 40141.77Skamil DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 40151.77Skamil DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 40161.77Skamil "si_errno=%#x\n", 40171.77Skamil info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 40181.77Skamil info.psi_siginfo.si_errno); 40191.77Skamil 40201.77Skamil FORKEE_ASSERT_EQ(info.psi_siginfo.si_signo, sigval); 40211.77Skamil FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, SI_LWP); 40221.77Skamil 40231.77Skamil memset(&lwp, 0, sizeof(lwp)); 40241.77Skamil 40251.77Skamil for (n = 0; n <= threads; n++) { 40261.77Skamil DPRINTF("Before calling ptrace(2) with PT_LWPINFO for " 40271.77Skamil "child\n"); 40281.77Skamil FORKEE_ASSERT(ptrace(PT_LWPINFO, tracee, &lwp, 40291.77Skamil sizeof(lwp)) != -1); 40301.77Skamil DPRINTF("LWP=%d\n", lwp.pl_lwpid); 40311.77Skamil 40321.77Skamil DPRINTF("Assert that the thread exists\n"); 40331.77Skamil FORKEE_ASSERT(lwp.pl_lwpid > 0); 40341.77Skamil 40351.77Skamil DPRINTF("Assert that lwp thread %d received expected " 40361.77Skamil "event\n", lwp.pl_lwpid); 40371.77Skamil FORKEE_ASSERT_EQ(lwp.pl_event, 40381.77Skamil info.psi_lwpid == lwp.pl_lwpid ? 40391.77Skamil PL_EVENT_SIGNAL : PL_EVENT_NONE); 40401.77Skamil } 40411.77Skamil DPRINTF("Before calling ptrace(2) with PT_LWPINFO for " 40421.77Skamil "tracee\n"); 40431.77Skamil FORKEE_ASSERT(ptrace(PT_LWPINFO, tracee, &lwp, sizeof(lwp)) 40441.77Skamil != -1); 40451.77Skamil DPRINTF("LWP=%d\n", lwp.pl_lwpid); 40461.77Skamil 40471.77Skamil DPRINTF("Assert that there are no more threads\n"); 40481.77Skamil FORKEE_ASSERT_EQ(lwp.pl_lwpid, 0); 40491.77Skamil 40501.77Skamil DPRINTF("Before resuming the child process where it left off " 40511.77Skamil "and without signal to be sent\n"); 40521.77Skamil FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, SIGKILL) 40531.77Skamil != -1); 40541.77Skamil 40551.1Skamil /* Wait for tracee and assert that it exited */ 40561.1Skamil FORKEE_REQUIRE_SUCCESS( 40571.1Skamil wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 40581.1Skamil 40591.77Skamil forkee_status_signaled(status, SIGKILL, 0); 40601.1Skamil 40611.13Schristos DPRINTF("Before exiting of the tracer process\n"); 40621.1Skamil _exit(exitval_tracer); 40631.1Skamil } 40641.1Skamil 40651.13Schristos DPRINTF("Wait for the tracer to attach to the tracee\n"); 40661.1Skamil PARENT_FROM_CHILD("tracer ready", parent_tracer, msg); 40671.1Skamil 40681.77Skamil DPRINTF("Resume the tracee and spawn threads\n"); 40691.77Skamil PARENT_TO_CHILD("spawn threads", parent_tracee, msg); 40701.77Skamil 40711.13Schristos DPRINTF("Resume the tracee and let it exit\n"); 40721.77Skamil PARENT_FROM_CHILD("tracee exit", parent_tracee, msg); 40731.1Skamil 40741.77Skamil DPRINTF("Resume the tracer and let it detect multiple threads\n"); 40751.1Skamil PARENT_TO_CHILD("tracer wait", parent_tracer, msg); 40761.1Skamil 40771.13Schristos DPRINTF("Wait for tracer to finish its job and exit - calling %s()\n", 40781.1Skamil TWAIT_FNAME); 40791.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0), 40801.1Skamil tracer); 40811.1Skamil 40821.1Skamil validate_status_exited(status, exitval_tracer); 40831.1Skamil 40841.13Schristos DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n", 40851.1Skamil TWAIT_FNAME); 40861.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 40871.1Skamil tracee); 40881.1Skamil 40891.77Skamil validate_status_signaled(status, SIGKILL, 0); 40901.1Skamil 40911.1Skamil msg_close(&parent_tracer); 40921.1Skamil msg_close(&parent_tracee); 40931.1Skamil} 40941.77Skamil 40951.77Skamil#define ATTACH_LWPINFO(test, threads) \ 40961.77SkamilATF_TC(test); \ 40971.77SkamilATF_TC_HEAD(test, tc) \ 40981.77Skamil{ \ 40991.77Skamil atf_tc_set_md_var(tc, "descr", \ 41001.77Skamil "Verify LWPINFO with the child with " #threads \ 41011.77Skamil " spawned extra threads (tracer is not the original " \ 41021.77Skamil "parent)"); \ 41031.77Skamil} \ 41041.77Skamil \ 41051.77SkamilATF_TC_BODY(test, tc) \ 41061.77Skamil{ \ 41071.77Skamil \ 41081.77Skamil attach_lwpinfo(threads); \ 41091.77Skamil} 41101.77Skamil 41111.77SkamilATTACH_LWPINFO(attach_lwpinfo0, 0) 41121.77SkamilATTACH_LWPINFO(attach_lwpinfo1, 1) 41131.77SkamilATTACH_LWPINFO(attach_lwpinfo2, 2) 41141.77SkamilATTACH_LWPINFO(attach_lwpinfo3, 3) 41151.1Skamil#endif 41161.1Skamil 41171.77Skamil/// ---------------------------------------------------------------------------- 41181.77Skamil 41191.1Skamilstatic void 41201.79Skamilptrace_siginfo(bool faked, void (*sah)(int a, siginfo_t *b, void *c), int *signal_caught) 41211.1Skamil{ 41221.1Skamil const int exitval = 5; 41231.1Skamil const int sigval = SIGINT; 41241.1Skamil const int sigfaked = SIGTRAP; 41251.1Skamil const int sicodefaked = TRAP_BRKPT; 41261.1Skamil pid_t child, wpid; 41271.1Skamil struct sigaction sa; 41281.1Skamil#if defined(TWAIT_HAVE_STATUS) 41291.1Skamil int status; 41301.1Skamil#endif 41311.1Skamil struct ptrace_siginfo info; 41321.1Skamil memset(&info, 0, sizeof(info)); 41331.1Skamil 41341.13Schristos DPRINTF("Before forking process PID=%d\n", getpid()); 41351.13Schristos SYSCALL_REQUIRE((child = fork()) != -1); 41361.1Skamil if (child == 0) { 41371.13Schristos DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 41381.1Skamil FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 41391.1Skamil 41401.79Skamil sa.sa_sigaction = sah; 41411.1Skamil sa.sa_flags = SA_SIGINFO; 41421.1Skamil sigemptyset(&sa.sa_mask); 41431.1Skamil 41441.79Skamil FORKEE_ASSERT(sigaction(faked ? sigfaked : sigval, &sa, NULL) 41451.79Skamil != -1); 41461.1Skamil 41471.13Schristos DPRINTF("Before raising %s from child\n", strsignal(sigval)); 41481.1Skamil FORKEE_ASSERT(raise(sigval) == 0); 41491.1Skamil 41501.79Skamil FORKEE_ASSERT_EQ(*signal_caught, 1); 41511.1Skamil 41521.13Schristos DPRINTF("Before exiting of the child process\n"); 41531.1Skamil _exit(exitval); 41541.1Skamil } 41551.13Schristos DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 41561.1Skamil 41571.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 41581.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 41591.1Skamil 41601.1Skamil validate_status_stopped(status, sigval); 41611.1Skamil 41621.13Schristos DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 41631.61Skre SYSCALL_REQUIRE( 41641.61Skre ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 41651.1Skamil 41661.13Schristos DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 41671.13Schristos DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 41681.1Skamil info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 41691.1Skamil info.psi_siginfo.si_errno); 41701.1Skamil 41711.79Skamil if (faked) { 41721.79Skamil DPRINTF("Before setting new faked signal to signo=%d " 41731.79Skamil "si_code=%d\n", sigfaked, sicodefaked); 41741.79Skamil info.psi_siginfo.si_signo = sigfaked; 41751.79Skamil info.psi_siginfo.si_code = sicodefaked; 41761.79Skamil } 41771.1Skamil 41781.13Schristos DPRINTF("Before calling ptrace(2) with PT_SET_SIGINFO for child\n"); 41791.61Skre SYSCALL_REQUIRE( 41801.61Skre ptrace(PT_SET_SIGINFO, child, &info, sizeof(info)) != -1); 41811.1Skamil 41821.79Skamil if (faked) { 41831.79Skamil DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for " 41841.79Skamil "child\n"); 41851.79Skamil SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, 41861.79Skamil sizeof(info)) != -1); 41871.1Skamil 41881.79Skamil DPRINTF("Before checking siginfo_t\n"); 41891.79Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigfaked); 41901.79Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_code, sicodefaked); 41911.79Skamil } 41921.1Skamil 41931.13Schristos DPRINTF("Before resuming the child process where it left off and " 41941.1Skamil "without signal to be sent\n"); 41951.79Skamil SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 41961.79Skamil faked ? sigfaked : sigval) != -1); 41971.1Skamil 41981.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 41991.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 42001.1Skamil 42011.1Skamil validate_status_exited(status, exitval); 42021.1Skamil 42031.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 42041.1Skamil TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 42051.1Skamil} 42061.1Skamil 42071.79Skamil#define PTRACE_SIGINFO(test, faked) \ 42081.79SkamilATF_TC(test); \ 42091.79SkamilATF_TC_HEAD(test, tc) \ 42101.79Skamil{ \ 42111.79Skamil atf_tc_set_md_var(tc, "descr", \ 42121.79Skamil "Verify basic PT_GET_SIGINFO and PT_SET_SIGINFO calls" \ 42131.79Skamil "with%s setting signal to new value", faked ? "" : "out"); \ 42141.79Skamil} \ 42151.79Skamil \ 42161.79Skamilstatic int test##_caught = 0; \ 42171.79Skamil \ 42181.79Skamilstatic void \ 42191.79Skamiltest##_sighandler(int sig, siginfo_t *info, void *ctx) \ 42201.79Skamil{ \ 42211.79Skamil if (faked) { \ 42221.79Skamil FORKEE_ASSERT_EQ(sig, SIGTRAP); \ 42231.79Skamil FORKEE_ASSERT_EQ(info->si_signo, SIGTRAP); \ 42241.79Skamil FORKEE_ASSERT_EQ(info->si_code, TRAP_BRKPT); \ 42251.79Skamil } else { \ 42261.79Skamil FORKEE_ASSERT_EQ(sig, SIGINT); \ 42271.79Skamil FORKEE_ASSERT_EQ(info->si_signo, SIGINT); \ 42281.79Skamil FORKEE_ASSERT_EQ(info->si_code, SI_LWP); \ 42291.79Skamil } \ 42301.79Skamil \ 42311.79Skamil ++ test##_caught; \ 42321.79Skamil} \ 42331.79Skamil \ 42341.79SkamilATF_TC_BODY(test, tc) \ 42351.79Skamil{ \ 42361.79Skamil \ 42371.79Skamil ptrace_siginfo(faked, test##_sighandler, & test##_caught); \ 42381.79Skamil} 42391.79Skamil 42401.79SkamilPTRACE_SIGINFO(siginfo_set_unmodified, false) 42411.79SkamilPTRACE_SIGINFO(siginfo_set_faked, true) 42421.79Skamil 42431.79Skamil/// ---------------------------------------------------------------------------- 42441.79Skamil 42451.82SkamilATF_TC(traceme_exec); 42461.82SkamilATF_TC_HEAD(traceme_exec, tc) 42471.1Skamil{ 42481.1Skamil atf_tc_set_md_var(tc, "descr", 42491.1Skamil "Detect SIGTRAP TRAP_EXEC from tracee"); 42501.1Skamil} 42511.1Skamil 42521.82SkamilATF_TC_BODY(traceme_exec, tc) 42531.1Skamil{ 42541.1Skamil const int sigval = SIGTRAP; 42551.1Skamil pid_t child, wpid; 42561.1Skamil#if defined(TWAIT_HAVE_STATUS) 42571.1Skamil int status; 42581.1Skamil#endif 42591.1Skamil 42601.1Skamil struct ptrace_siginfo info; 42611.1Skamil memset(&info, 0, sizeof(info)); 42621.1Skamil 42631.13Schristos DPRINTF("Before forking process PID=%d\n", getpid()); 42641.13Schristos SYSCALL_REQUIRE((child = fork()) != -1); 42651.1Skamil if (child == 0) { 42661.13Schristos DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 42671.1Skamil FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 42681.1Skamil 42691.13Schristos DPRINTF("Before calling execve(2) from child\n"); 42701.1Skamil execlp("/bin/echo", "/bin/echo", NULL); 42711.1Skamil 42721.1Skamil FORKEE_ASSERT(0 && "Not reached"); 42731.1Skamil } 42741.13Schristos DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 42751.1Skamil 42761.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 42771.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 42781.1Skamil 42791.1Skamil validate_status_stopped(status, sigval); 42801.1Skamil 42811.13Schristos DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 42821.61Skre SYSCALL_REQUIRE( 42831.61Skre ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 42841.1Skamil 42851.13Schristos DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 42861.13Schristos DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 42871.1Skamil info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 42881.1Skamil info.psi_siginfo.si_errno); 42891.1Skamil 42901.1Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 42911.1Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_EXEC); 42921.1Skamil 42931.13Schristos DPRINTF("Before resuming the child process where it left off and " 42941.1Skamil "without signal to be sent\n"); 42951.13Schristos SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 42961.1Skamil 42971.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 42981.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 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.82Skamil/// ---------------------------------------------------------------------------- 43051.82Skamil 43061.83Skamilstatic volatile int done; 43071.1Skamil 43081.83Skamilstatic void * 43091.83Skamiltrace_threads_cb(void *arg __unused) 43101.1Skamil{ 43111.1Skamil 43121.83Skamil done++; 43131.83Skamil 43141.83Skamil while (done < 3) 43151.83Skamil continue; 43161.83Skamil 43171.83Skamil return NULL; 43181.1Skamil} 43191.1Skamil 43201.83Skamilstatic void 43211.83Skamiltrace_threads(bool trace_create, bool trace_exit) 43221.1Skamil{ 43231.1Skamil const int sigval = SIGSTOP; 43241.1Skamil pid_t child, wpid; 43251.1Skamil#if defined(TWAIT_HAVE_STATUS) 43261.1Skamil int status; 43271.1Skamil#endif 43281.1Skamil ptrace_state_t state; 43291.1Skamil const int slen = sizeof(state); 43301.1Skamil ptrace_event_t event; 43311.1Skamil const int elen = sizeof(event); 43321.83Skamil struct ptrace_siginfo info; 43331.83Skamil 43341.83Skamil pthread_t t[3]; 43351.83Skamil int rv; 43361.83Skamil size_t n; 43371.1Skamil lwpid_t lid; 43381.83Skamil 43391.83Skamil /* Track created and exited threads */ 43401.83Skamil bool traced_lwps[__arraycount(t)]; 43411.83Skamil 43421.83Skamil atf_tc_skip("PR kern/51995"); 43431.1Skamil 43441.13Schristos DPRINTF("Before forking process PID=%d\n", getpid()); 43451.13Schristos SYSCALL_REQUIRE((child = fork()) != -1); 43461.1Skamil if (child == 0) { 43471.13Schristos DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 43481.1Skamil FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 43491.1Skamil 43501.13Schristos DPRINTF("Before raising %s from child\n", strsignal(sigval)); 43511.1Skamil FORKEE_ASSERT(raise(sigval) == 0); 43521.1Skamil 43531.83Skamil for (n = 0; n < __arraycount(t); n++) { 43541.83Skamil rv = pthread_create(&t[n], NULL, trace_threads_cb, 43551.83Skamil NULL); 43561.83Skamil FORKEE_ASSERT(rv == 0); 43571.83Skamil } 43581.1Skamil 43591.83Skamil for (n = 0; n < __arraycount(t); n++) { 43601.83Skamil rv = pthread_join(t[n], NULL); 43611.83Skamil FORKEE_ASSERT(rv == 0); 43621.83Skamil } 43631.1Skamil 43641.83Skamil /* 43651.83Skamil * There is race between _exit() and pthread_join() detaching 43661.83Skamil * a thread. For simplicity kill the process after detecting 43671.83Skamil * LWP events. 43681.83Skamil */ 43691.83Skamil while (true) 43701.83Skamil continue; 43711.1Skamil 43721.83Skamil FORKEE_ASSERT(0 && "Not reached"); 43731.1Skamil } 43741.13Schristos DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 43751.1Skamil 43761.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 43771.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 43781.1Skamil 43791.1Skamil validate_status_stopped(status, sigval); 43801.1Skamil 43811.83Skamil DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 43821.83Skamil SYSCALL_REQUIRE( 43831.83Skamil ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 43841.1Skamil 43851.83Skamil DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 43861.83Skamil DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 43871.83Skamil info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 43881.83Skamil info.psi_siginfo.si_errno); 43891.1Skamil 43901.83Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 43911.83Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 43921.1Skamil 43931.83Skamil DPRINTF("Set LWP event mask for the child %d\n", child); 43941.83Skamil memset(&event, 0, sizeof(event)); 43951.83Skamil if (trace_create) 43961.83Skamil event.pe_set_event |= PTRACE_LWP_CREATE; 43971.83Skamil if (trace_exit) 43981.83Skamil event.pe_set_event |= PTRACE_LWP_EXIT; 43991.83Skamil SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); 44001.1Skamil 44011.13Schristos DPRINTF("Before resuming the child process where it left off and " 44021.1Skamil "without signal to be sent\n"); 44031.13Schristos SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 44041.1Skamil 44051.83Skamil memset(traced_lwps, 0, sizeof(traced_lwps)); 44061.1Skamil 44071.83Skamil for (n = 0; n < (trace_create ? __arraycount(t) : 0); n++) { 44081.83Skamil DPRINTF("Before calling %s() for the child - expected stopped " 44091.83Skamil "SIGTRAP\n", TWAIT_FNAME); 44101.83Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), 44111.83Skamil child); 44121.1Skamil 44131.83Skamil validate_status_stopped(status, SIGTRAP); 44141.1Skamil 44151.83Skamil DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for " 44161.83Skamil "child\n"); 44171.83Skamil SYSCALL_REQUIRE( 44181.83Skamil ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 44191.1Skamil 44201.83Skamil DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 44211.83Skamil DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 44221.83Skamil "si_errno=%#x\n", 44231.83Skamil info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 44241.83Skamil info.psi_siginfo.si_errno); 44251.1Skamil 44261.83Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); 44271.83Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_LWP); 44281.1Skamil 44291.83Skamil SYSCALL_REQUIRE( 44301.83Skamil ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 44311.1Skamil 44321.83Skamil ATF_REQUIRE_EQ_MSG(state.pe_report_event, PTRACE_LWP_CREATE, 44331.83Skamil "%d != %d", state.pe_report_event, PTRACE_LWP_CREATE); 44341.1Skamil 44351.83Skamil lid = state.pe_lwp; 44361.83Skamil DPRINTF("Reported PTRACE_LWP_CREATE event with lid %d\n", lid); 44371.1Skamil 44381.83Skamil traced_lwps[lid - 1] = true; 44391.1Skamil 44401.83Skamil DPRINTF("Before resuming the child process where it left off " 44411.83Skamil "and without signal to be sent\n"); 44421.83Skamil SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 44431.83Skamil } 44441.1Skamil 44451.83Skamil for (n = 0; n < (trace_exit ? __arraycount(t) : 0); n++) { 44461.83Skamil DPRINTF("Before calling %s() for the child - expected stopped " 44471.83Skamil "SIGTRAP\n", TWAIT_FNAME); 44481.83Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), 44491.83Skamil child); 44501.1Skamil 44511.83Skamil validate_status_stopped(status, SIGTRAP); 44521.1Skamil 44531.83Skamil DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for " 44541.83Skamil "child\n"); 44551.83Skamil SYSCALL_REQUIRE( 44561.83Skamil ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 44571.1Skamil 44581.83Skamil DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 44591.83Skamil DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 44601.83Skamil "si_errno=%#x\n", 44611.83Skamil info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 44621.83Skamil info.psi_siginfo.si_errno); 44631.1Skamil 44641.83Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); 44651.83Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_LWP); 44661.1Skamil 44671.83Skamil SYSCALL_REQUIRE( 44681.83Skamil ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 44691.1Skamil 44701.83Skamil ATF_REQUIRE_EQ_MSG(state.pe_report_event, PTRACE_LWP_EXIT, 44711.83Skamil "%d != %d", state.pe_report_event, PTRACE_LWP_EXIT); 44721.1Skamil 44731.83Skamil lid = state.pe_lwp; 44741.83Skamil DPRINTF("Reported PTRACE_LWP_EXIT event with lid %d\n", lid); 44751.1Skamil 44761.83Skamil if (trace_create) { 44771.83Skamil ATF_REQUIRE(traced_lwps[lid - 1] == true); 44781.83Skamil traced_lwps[lid - 1] = false; 44791.83Skamil } 44801.1Skamil 44811.83Skamil DPRINTF("Before resuming the child process where it left off " 44821.83Skamil "and without signal to be sent\n"); 44831.83Skamil SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 44841.83Skamil } 44851.1Skamil 44861.83Skamil kill(child, SIGKILL); 44871.1Skamil 44881.13Schristos DPRINTF("Before calling %s() for the child - expected exited\n", 44891.1Skamil TWAIT_FNAME); 44901.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 44911.1Skamil 44921.83Skamil validate_status_signaled(status, SIGKILL, 0); 44931.1Skamil 44941.13Schristos DPRINTF("Before calling %s() for the child - expected no process\n", 44951.1Skamil TWAIT_FNAME); 44961.1Skamil TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 44971.1Skamil} 44981.1Skamil 44991.83Skamil#define TRACE_THREADS(test, trace_create, trace_exit) \ 45001.83SkamilATF_TC(test); \ 45011.83SkamilATF_TC_HEAD(test, tc) \ 45021.83Skamil{ \ 45031.83Skamil atf_tc_set_md_var(tc, "descr", \ 45041.83Skamil "Verify spawning threads with%s tracing LWP create and" \ 45051.83Skamil "with%s tracing LWP exit", trace_create ? "" : "out", \ 45061.83Skamil trace_exit ? "" : "out"); \ 45071.83Skamil} \ 45081.83Skamil \ 45091.83SkamilATF_TC_BODY(test, tc) \ 45101.83Skamil{ \ 45111.83Skamil \ 45121.83Skamil trace_threads(trace_create, trace_exit); \ 45131.83Skamil} 45141.83Skamil 45151.83SkamilTRACE_THREADS(trace_thread1, false, false) 45161.83SkamilTRACE_THREADS(trace_thread2, false, true) 45171.83SkamilTRACE_THREADS(trace_thread3, true, false) 45181.83SkamilTRACE_THREADS(trace_thread4, true, true) 45191.83Skamil 45201.83Skamil/// ---------------------------------------------------------------------------- 45211.83Skamil 45221.84SkamilATF_TC(signal_mask_unrelated); 45231.84SkamilATF_TC_HEAD(signal_mask_unrelated, tc) 45241.1Skamil{ 45251.1Skamil atf_tc_set_md_var(tc, "descr", 45261.1Skamil "Verify that masking single unrelated signal does not stop tracer " 45271.1Skamil "from catching other signals"); 45281.1Skamil} 45291.1Skamil 45301.84SkamilATF_TC_BODY(signal_mask_unrelated, tc) 45311.1Skamil{ 45321.1Skamil const int exitval = 5; 45331.1Skamil const int sigval = SIGSTOP; 45341.1Skamil const int sigmasked = SIGTRAP; 45351.1Skamil const int signotmasked = SIGINT; 45361.1Skamil pid_t child, wpid; 45371.1Skamil#if defined(TWAIT_HAVE_STATUS) 45381.1Skamil int status; 45391.1Skamil#endif 45401.1Skamil sigset_t intmask; 45411.1Skamil 45421.13Schristos DPRINTF("Before forking process PID=%d\n", getpid()); 45431.13Schristos SYSCALL_REQUIRE((child = fork()) != -1); 45441.1Skamil if (child == 0) { 45451.13Schristos DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 45461.1Skamil FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 45471.1Skamil 45481.1Skamil sigemptyset(&intmask); 45491.1Skamil sigaddset(&intmask, sigmasked); 45501.1Skamil sigprocmask(SIG_BLOCK, &intmask, NULL); 45511.1Skamil 45521.13Schristos DPRINTF("Before raising %s from child\n", strsignal(sigval)); 45531.1Skamil FORKEE_ASSERT(raise(sigval) == 0); 45541.1Skamil 45551.13Schristos DPRINTF("Before raising %s from child\n", 45561.1Skamil strsignal(signotmasked)); 45571.1Skamil FORKEE_ASSERT(raise(signotmasked) == 0); 45581.1Skamil 45591.13Schristos DPRINTF("Before exiting of the child process\n"); 45601.1Skamil _exit(exitval); 45611.1Skamil } 45621.13Schristos DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 45631.1Skamil 45641.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 45651.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 45661.1Skamil 45671.1Skamil validate_status_stopped(status, sigval); 45681.1Skamil 45691.13Schristos DPRINTF("Before resuming the child process where it left off and " 45701.1Skamil "without signal to be sent\n"); 45711.13Schristos SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 45721.1Skamil 45731.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 45741.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 45751.1Skamil 45761.1Skamil validate_status_stopped(status, signotmasked); 45771.1Skamil 45781.13Schristos DPRINTF("Before resuming the child process where it left off and " 45791.1Skamil "without signal to be sent\n"); 45801.13Schristos SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 45811.1Skamil 45821.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 45831.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 45841.1Skamil 45851.1Skamil validate_status_exited(status, exitval); 45861.1Skamil 45871.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 45881.1Skamil TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 45891.1Skamil} 45901.1Skamil 45911.84Skamil/// ---------------------------------------------------------------------------- 45921.84Skamil 45931.1Skamil#if defined(PT_STEP) 45941.1SkamilATF_TC(signal4); 45951.1SkamilATF_TC_HEAD(signal4, tc) 45961.1Skamil{ 45971.1Skamil atf_tc_set_md_var(tc, "descr", 45981.1Skamil "Verify that masking SIGTRAP in tracee does not stop tracer from " 45991.1Skamil "catching single step trap"); 46001.1Skamil} 46011.1Skamil 46021.1SkamilATF_TC_BODY(signal4, tc) 46031.1Skamil{ 46041.1Skamil const int exitval = 5; 46051.1Skamil const int sigval = SIGSTOP; 46061.1Skamil const int sigmasked = SIGTRAP; 46071.1Skamil pid_t child, wpid; 46081.1Skamil#if defined(TWAIT_HAVE_STATUS) 46091.1Skamil int status; 46101.1Skamil#endif 46111.1Skamil sigset_t intmask; 46121.1Skamil int happy; 46131.1Skamil 46141.1Skamil#if defined(__arm__) 46151.5Skamil /* PT_STEP not supported on arm 32-bit */ 46161.5Skamil atf_tc_expect_fail("PR kern/51918 PR kern/52119"); 46171.1Skamil#endif 46181.1Skamil 46191.13Schristos DPRINTF("Before forking process PID=%d\n", getpid()); 46201.13Schristos SYSCALL_REQUIRE((child = fork()) != -1); 46211.1Skamil if (child == 0) { 46221.13Schristos DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 46231.1Skamil FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 46241.1Skamil 46251.1Skamil happy = check_happy(100); 46261.1Skamil 46271.1Skamil sigemptyset(&intmask); 46281.1Skamil sigaddset(&intmask, sigmasked); 46291.1Skamil sigprocmask(SIG_BLOCK, &intmask, NULL); 46301.1Skamil 46311.13Schristos DPRINTF("Before raising %s from child\n", strsignal(sigval)); 46321.1Skamil FORKEE_ASSERT(raise(sigval) == 0); 46331.1Skamil 46341.1Skamil FORKEE_ASSERT_EQ(happy, check_happy(100)); 46351.1Skamil 46361.13Schristos DPRINTF("Before exiting of the child process\n"); 46371.1Skamil _exit(exitval); 46381.1Skamil } 46391.13Schristos DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 46401.1Skamil 46411.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 46421.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 46431.1Skamil 46441.1Skamil validate_status_stopped(status, sigval); 46451.1Skamil 46461.13Schristos DPRINTF("Before resuming the child process where it left off and " 46471.1Skamil "without signal to be sent\n"); 46481.13Schristos SYSCALL_REQUIRE(ptrace(PT_STEP, child, (void *)1, 0) != -1); 46491.1Skamil 46501.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 46511.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 46521.1Skamil 46531.1Skamil validate_status_stopped(status, sigmasked); 46541.1Skamil 46551.13Schristos DPRINTF("Before resuming the child process where it left off and " 46561.1Skamil "without signal to be sent\n"); 46571.13Schristos SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 46581.1Skamil 46591.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 46601.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 46611.1Skamil 46621.1Skamil validate_status_exited(status, exitval); 46631.1Skamil 46641.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 46651.1Skamil TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 46661.1Skamil} 46671.1Skamil#endif 46681.1Skamil 46691.1SkamilATF_TC(signal5); 46701.1SkamilATF_TC_HEAD(signal5, tc) 46711.1Skamil{ 46721.1Skamil atf_tc_set_md_var(tc, "descr", 46731.1Skamil "Verify that masking SIGTRAP in tracee does not stop tracer from " 46741.1Skamil "catching exec() breakpoint"); 46751.1Skamil} 46761.1Skamil 46771.1SkamilATF_TC_BODY(signal5, tc) 46781.1Skamil{ 46791.1Skamil const int sigval = SIGSTOP; 46801.1Skamil const int sigmasked = SIGTRAP; 46811.1Skamil pid_t child, wpid; 46821.1Skamil#if defined(TWAIT_HAVE_STATUS) 46831.1Skamil int status; 46841.1Skamil#endif 46851.58Skamil struct ptrace_siginfo info; 46861.1Skamil sigset_t intmask; 46871.1Skamil 46881.58Skamil memset(&info, 0, sizeof(info)); 46891.14Schristos 46901.13Schristos DPRINTF("Before forking process PID=%d\n", getpid()); 46911.13Schristos SYSCALL_REQUIRE((child = fork()) != -1); 46921.1Skamil if (child == 0) { 46931.13Schristos DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 46941.1Skamil FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 46951.1Skamil 46961.1Skamil sigemptyset(&intmask); 46971.1Skamil sigaddset(&intmask, sigmasked); 46981.1Skamil sigprocmask(SIG_BLOCK, &intmask, NULL); 46991.1Skamil 47001.13Schristos DPRINTF("Before raising %s from child\n", strsignal(sigval)); 47011.1Skamil FORKEE_ASSERT(raise(sigval) == 0); 47021.1Skamil 47031.13Schristos DPRINTF("Before calling execve(2) from child\n"); 47041.1Skamil execlp("/bin/echo", "/bin/echo", NULL); 47051.1Skamil 47061.58Skamil /* NOTREACHED */ 47071.58Skamil FORKEE_ASSERTX(0 && "Not reached"); 47081.1Skamil } 47091.13Schristos DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 47101.1Skamil 47111.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 47121.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 47131.1Skamil 47141.1Skamil validate_status_stopped(status, sigval); 47151.1Skamil 47161.13Schristos DPRINTF("Before resuming the child process where it left off and " 47171.1Skamil "without signal to be sent\n"); 47181.13Schristos SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 47191.1Skamil 47201.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 47211.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 47221.1Skamil 47231.1Skamil validate_status_stopped(status, sigmasked); 47241.1Skamil 47251.58Skamil DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 47261.61Skre SYSCALL_REQUIRE( 47271.61Skre ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 47281.58Skamil 47291.58Skamil DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 47301.58Skamil DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 47311.58Skamil info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 47321.58Skamil info.psi_siginfo.si_errno); 47331.58Skamil 47341.58Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigmasked); 47351.58Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_EXEC); 47361.58Skamil 47371.13Schristos DPRINTF("Before resuming the child process where it left off and " 47381.1Skamil "without signal to be sent\n"); 47391.13Schristos SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 47401.1Skamil 47411.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 47421.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 47431.1Skamil 47441.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 47451.1Skamil TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 47461.1Skamil} 47471.1Skamil 47481.1Skamil#if defined(TWAIT_HAVE_PID) 47491.1SkamilATF_TC(signal6); 47501.1SkamilATF_TC_HEAD(signal6, tc) 47511.1Skamil{ 47521.1Skamil atf_tc_set_md_var(tc, "timeout", "5"); 47531.1Skamil atf_tc_set_md_var(tc, "descr", 47541.1Skamil "Verify that masking SIGTRAP in tracee does not stop tracer from " 47551.1Skamil "catching PTRACE_FORK breakpoint"); 47561.1Skamil} 47571.1Skamil 47581.1SkamilATF_TC_BODY(signal6, tc) 47591.1Skamil{ 47601.1Skamil const int exitval = 5; 47611.1Skamil const int exitval2 = 15; 47621.1Skamil const int sigval = SIGSTOP; 47631.1Skamil const int sigmasked = SIGTRAP; 47641.1Skamil pid_t child, child2, wpid; 47651.1Skamil#if defined(TWAIT_HAVE_STATUS) 47661.1Skamil int status; 47671.1Skamil#endif 47681.1Skamil sigset_t intmask; 47691.1Skamil ptrace_state_t state; 47701.1Skamil const int slen = sizeof(state); 47711.1Skamil ptrace_event_t event; 47721.1Skamil const int elen = sizeof(event); 47731.1Skamil 47741.38Skamil atf_tc_expect_fail("PR kern/51918"); 47751.14Schristos 47761.13Schristos DPRINTF("Before forking process PID=%d\n", getpid()); 47771.13Schristos SYSCALL_REQUIRE((child = fork()) != -1); 47781.1Skamil if (child == 0) { 47791.13Schristos DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 47801.1Skamil FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 47811.1Skamil 47821.1Skamil sigemptyset(&intmask); 47831.1Skamil sigaddset(&intmask, sigmasked); 47841.1Skamil sigprocmask(SIG_BLOCK, &intmask, NULL); 47851.1Skamil 47861.13Schristos DPRINTF("Before raising %s from child\n", strsignal(sigval)); 47871.1Skamil FORKEE_ASSERT(raise(sigval) == 0); 47881.1Skamil 47891.1Skamil FORKEE_ASSERT((child2 = fork()) != -1); 47901.1Skamil 47911.1Skamil if (child2 == 0) 47921.1Skamil _exit(exitval2); 47931.1Skamil 47941.1Skamil FORKEE_REQUIRE_SUCCESS 47951.1Skamil (wpid = TWAIT_GENERIC(child2, &status, 0), child2); 47961.1Skamil 47971.1Skamil forkee_status_exited(status, exitval2); 47981.1Skamil 47991.13Schristos DPRINTF("Before exiting of the child process\n"); 48001.1Skamil _exit(exitval); 48011.1Skamil } 48021.13Schristos DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 48031.1Skamil 48041.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 48051.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 48061.1Skamil 48071.1Skamil validate_status_stopped(status, sigval); 48081.1Skamil 48091.13Schristos DPRINTF("Enable PTRACE_FORK in EVENT_MASK for the child %d\n", child); 48101.1Skamil event.pe_set_event = PTRACE_FORK; 48111.13Schristos SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); 48121.1Skamil 48131.13Schristos DPRINTF("Before resuming the child process where it left off and " 48141.1Skamil "without signal to be sent\n"); 48151.13Schristos SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 48161.1Skamil 48171.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 48181.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 48191.1Skamil 48201.1Skamil validate_status_stopped(status, sigmasked); 48211.1Skamil 48221.13Schristos SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 48231.1Skamil ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_FORK); 48241.1Skamil 48251.1Skamil child2 = state.pe_other_pid; 48261.13Schristos DPRINTF("Reported PTRACE_FORK event with forkee %d\n", child2); 48271.1Skamil 48281.13Schristos DPRINTF("Before calling %s() for the child2\n", TWAIT_FNAME); 48291.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0), 48301.1Skamil child2); 48311.1Skamil 48321.1Skamil validate_status_stopped(status, SIGTRAP); 48331.1Skamil 48341.13Schristos SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1); 48351.1Skamil ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_FORK); 48361.1Skamil ATF_REQUIRE_EQ(state.pe_other_pid, child); 48371.1Skamil 48381.13Schristos DPRINTF("Before resuming the forkee process where it left off and " 48391.1Skamil "without signal to be sent\n"); 48401.13Schristos SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1); 48411.1Skamil 48421.13Schristos DPRINTF("Before resuming the child process where it left off and " 48431.1Skamil "without signal to be sent\n"); 48441.13Schristos SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 48451.1Skamil 48461.13Schristos DPRINTF("Before calling %s() for the forkee - expected exited\n", 48471.1Skamil TWAIT_FNAME); 48481.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0), 48491.57Skamil child2); 48501.1Skamil 48511.1Skamil validate_status_exited(status, exitval2); 48521.1Skamil 48531.13Schristos DPRINTF("Before calling %s() for the forkee - expected no process\n", 48541.1Skamil TWAIT_FNAME); 48551.1Skamil TWAIT_REQUIRE_FAILURE(ECHILD, 48561.1Skamil wpid = TWAIT_GENERIC(child2, &status, 0)); 48571.1Skamil 48581.13Schristos DPRINTF("Before calling %s() for the child - expected stopped " 48591.1Skamil "SIGCHLD\n", TWAIT_FNAME); 48601.57Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 48611.1Skamil 48621.1Skamil validate_status_stopped(status, SIGCHLD); 48631.1Skamil 48641.57Skamil DPRINTF("Before resuming the child process where it left off and " 48651.1Skamil "without signal to be sent\n"); 48661.13Schristos SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 48671.1Skamil 48681.13Schristos DPRINTF("Before calling %s() for the child - expected exited\n", 48691.1Skamil TWAIT_FNAME); 48701.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 48711.1Skamil 48721.1Skamil validate_status_exited(status, exitval); 48731.1Skamil 48741.13Schristos DPRINTF("Before calling %s() for the child - expected no process\n", 48751.57Skamil TWAIT_FNAME); 48761.1Skamil TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 48771.1Skamil} 48781.1Skamil#endif 48791.1Skamil 48801.1Skamil#if defined(TWAIT_HAVE_PID) 48811.1SkamilATF_TC(signal7); 48821.1SkamilATF_TC_HEAD(signal7, tc) 48831.1Skamil{ 48841.1Skamil atf_tc_set_md_var(tc, "descr", 48851.1Skamil "Verify that masking SIGTRAP in tracee does not stop tracer from " 48861.1Skamil "catching PTRACE_VFORK breakpoint"); 48871.1Skamil} 48881.1Skamil 48891.1SkamilATF_TC_BODY(signal7, tc) 48901.1Skamil{ 48911.1Skamil const int exitval = 5; 48921.1Skamil const int exitval2 = 15; 48931.1Skamil const int sigval = SIGSTOP; 48941.1Skamil const int sigmasked = SIGTRAP; 48951.1Skamil pid_t child, child2, wpid; 48961.1Skamil#if defined(TWAIT_HAVE_STATUS) 48971.1Skamil int status; 48981.1Skamil#endif 48991.1Skamil sigset_t intmask; 49001.1Skamil ptrace_state_t state; 49011.1Skamil const int slen = sizeof(state); 49021.1Skamil ptrace_event_t event; 49031.1Skamil const int elen = sizeof(event); 49041.1Skamil 49051.38Skamil atf_tc_expect_fail("PR kern/51918"); 49061.14Schristos 49071.13Schristos DPRINTF("Before forking process PID=%d\n", getpid()); 49081.13Schristos SYSCALL_REQUIRE((child = fork()) != -1); 49091.1Skamil if (child == 0) { 49101.13Schristos DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 49111.1Skamil FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 49121.1Skamil 49131.1Skamil sigemptyset(&intmask); 49141.1Skamil sigaddset(&intmask, sigmasked); 49151.1Skamil sigprocmask(SIG_BLOCK, &intmask, NULL); 49161.1Skamil 49171.13Schristos DPRINTF("Before raising %s from child\n", strsignal(sigval)); 49181.1Skamil FORKEE_ASSERT(raise(sigval) == 0); 49191.1Skamil 49201.1Skamil FORKEE_ASSERT((child2 = fork()) != -1); 49211.1Skamil 49221.1Skamil if (child2 == 0) 49231.1Skamil _exit(exitval2); 49241.1Skamil 49251.1Skamil FORKEE_REQUIRE_SUCCESS 49261.1Skamil (wpid = TWAIT_GENERIC(child2, &status, 0), child2); 49271.1Skamil 49281.1Skamil forkee_status_exited(status, exitval2); 49291.1Skamil 49301.13Schristos DPRINTF("Before exiting of the child process\n"); 49311.1Skamil _exit(exitval); 49321.1Skamil } 49331.13Schristos DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 49341.1Skamil 49351.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 49361.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 49371.1Skamil 49381.1Skamil validate_status_stopped(status, sigval); 49391.1Skamil 49401.13Schristos DPRINTF("Enable PTRACE_VFORK in EVENT_MASK for the child %d\n", child); 49411.1Skamil event.pe_set_event = PTRACE_VFORK; 49421.61Skre SYSCALL_REQUIRE( 49431.61Skre ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1 || 49441.61Skre errno == ENOTSUP); 49451.1Skamil 49461.13Schristos DPRINTF("Before resuming the child process where it left off and " 49471.1Skamil "without signal to be sent\n"); 49481.13Schristos SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 49491.1Skamil 49501.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 49511.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 49521.1Skamil 49531.1Skamil validate_status_stopped(status, sigmasked); 49541.1Skamil 49551.61Skre SYSCALL_REQUIRE( 49561.61Skre ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 49571.1Skamil ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK); 49581.1Skamil 49591.1Skamil child2 = state.pe_other_pid; 49601.13Schristos DPRINTF("Reported PTRACE_VFORK event with forkee %d\n", child2); 49611.1Skamil 49621.13Schristos DPRINTF("Before calling %s() for the child2\n", TWAIT_FNAME); 49631.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0), 49641.1Skamil child2); 49651.1Skamil 49661.1Skamil validate_status_stopped(status, SIGTRAP); 49671.1Skamil 49681.61Skre SYSCALL_REQUIRE( 49691.61Skre ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1); 49701.1Skamil ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK); 49711.1Skamil ATF_REQUIRE_EQ(state.pe_other_pid, child); 49721.1Skamil 49731.13Schristos DPRINTF("Before resuming the forkee process where it left off and " 49741.1Skamil "without signal to be sent\n"); 49751.13Schristos SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1); 49761.1Skamil 49771.13Schristos DPRINTF("Before resuming the child process where it left off and " 49781.1Skamil "without signal to be sent\n"); 49791.13Schristos SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 49801.1Skamil 49811.13Schristos DPRINTF("Before calling %s() for the forkee - expected exited\n", 49821.1Skamil TWAIT_FNAME); 49831.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0), 49841.57Skamil child2); 49851.1Skamil 49861.1Skamil validate_status_exited(status, exitval2); 49871.1Skamil 49881.13Schristos DPRINTF("Before calling %s() for the forkee - expected no process\n", 49891.1Skamil TWAIT_FNAME); 49901.1Skamil TWAIT_REQUIRE_FAILURE(ECHILD, 49911.1Skamil wpid = TWAIT_GENERIC(child2, &status, 0)); 49921.1Skamil 49931.13Schristos DPRINTF("Before calling %s() for the child - expected stopped " 49941.1Skamil "SIGCHLD\n", TWAIT_FNAME); 49951.57Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 49961.1Skamil 49971.1Skamil validate_status_stopped(status, SIGCHLD); 49981.1Skamil 49991.57Skamil 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.57Skamil TWAIT_FNAME); 50111.1Skamil TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 50121.1Skamil} 50131.1Skamil#endif 50141.1Skamil 50151.1SkamilATF_TC(signal8); 50161.1SkamilATF_TC_HEAD(signal8, tc) 50171.1Skamil{ 50181.1Skamil atf_tc_set_md_var(tc, "descr", 50191.1Skamil "Verify that masking SIGTRAP in tracee does not stop tracer from " 50201.1Skamil "catching PTRACE_VFORK_DONE breakpoint"); 50211.1Skamil} 50221.1Skamil 50231.1SkamilATF_TC_BODY(signal8, tc) 50241.1Skamil{ 50251.1Skamil const int exitval = 5; 50261.1Skamil const int exitval2 = 15; 50271.1Skamil const int sigval = SIGSTOP; 50281.1Skamil const int sigmasked = SIGTRAP; 50291.1Skamil pid_t child, child2, wpid; 50301.1Skamil#if defined(TWAIT_HAVE_STATUS) 50311.1Skamil int status; 50321.1Skamil#endif 50331.1Skamil sigset_t intmask; 50341.1Skamil ptrace_state_t state; 50351.1Skamil const int slen = sizeof(state); 50361.1Skamil ptrace_event_t event; 50371.1Skamil const int elen = sizeof(event); 50381.1Skamil 50391.14Schristos atf_tc_expect_fail("PR kern/51918"); 50401.14Schristos 50411.13Schristos DPRINTF("Before forking process PID=%d\n", getpid()); 50421.13Schristos SYSCALL_REQUIRE((child = fork()) != -1); 50431.1Skamil if (child == 0) { 50441.13Schristos DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 50451.1Skamil FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 50461.1Skamil 50471.1Skamil sigemptyset(&intmask); 50481.1Skamil sigaddset(&intmask, sigmasked); 50491.1Skamil sigprocmask(SIG_BLOCK, &intmask, NULL); 50501.1Skamil 50511.13Schristos DPRINTF("Before raising %s from child\n", strsignal(sigval)); 50521.1Skamil FORKEE_ASSERT(raise(sigval) == 0); 50531.1Skamil 50541.1Skamil FORKEE_ASSERT((child2 = vfork()) != -1); 50551.1Skamil 50561.1Skamil if (child2 == 0) 50571.1Skamil _exit(exitval2); 50581.1Skamil 50591.1Skamil FORKEE_REQUIRE_SUCCESS 50601.1Skamil (wpid = TWAIT_GENERIC(child2, &status, 0), child2); 50611.1Skamil 50621.1Skamil forkee_status_exited(status, exitval2); 50631.1Skamil 50641.13Schristos DPRINTF("Before exiting of the child process\n"); 50651.1Skamil _exit(exitval); 50661.1Skamil } 50671.13Schristos DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 50681.1Skamil 50691.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 50701.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 50711.1Skamil 50721.1Skamil validate_status_stopped(status, sigval); 50731.1Skamil 50741.13Schristos DPRINTF("Enable PTRACE_VFORK_DONE in EVENT_MASK for the child %d\n", 50751.1Skamil child); 50761.1Skamil event.pe_set_event = PTRACE_VFORK_DONE; 50771.13Schristos SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); 50781.1Skamil 50791.13Schristos DPRINTF("Before resuming the child process where it left off and " 50801.1Skamil "without signal to be sent\n"); 50811.13Schristos SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 50821.1Skamil 50831.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 50841.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 50851.1Skamil 50861.1Skamil validate_status_stopped(status, sigmasked); 50871.1Skamil 50881.61Skre SYSCALL_REQUIRE( 50891.61Skre ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 50901.1Skamil ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK_DONE); 50911.1Skamil 50921.1Skamil child2 = state.pe_other_pid; 50931.13Schristos DPRINTF("Reported PTRACE_VFORK_DONE event with forkee %d\n", child2); 50941.1Skamil 50951.13Schristos DPRINTF("Before resuming the child process where it left off and " 50961.1Skamil "without signal to be sent\n"); 50971.13Schristos SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 50981.1Skamil 50991.13Schristos DPRINTF("Before calling %s() for the child - expected stopped " 51001.1Skamil "SIGCHLD\n", TWAIT_FNAME); 51011.57Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 51021.1Skamil 51031.1Skamil validate_status_stopped(status, SIGCHLD); 51041.1Skamil 51051.57Skamil DPRINTF("Before resuming the child process where it left off and " 51061.1Skamil "without signal to be sent\n"); 51071.13Schristos SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 51081.1Skamil 51091.13Schristos DPRINTF("Before calling %s() for the child - expected exited\n", 51101.1Skamil TWAIT_FNAME); 51111.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 51121.1Skamil 51131.1Skamil validate_status_exited(status, exitval); 51141.1Skamil 51151.13Schristos DPRINTF("Before calling %s() for the child - expected no process\n", 51161.57Skamil TWAIT_FNAME); 51171.1Skamil TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 51181.1Skamil} 51191.1Skamil 51201.83Skamilvolatile lwpid_t the_lwp_id = 0; 51211.83Skamil 51221.83Skamilstatic void 51231.83Skamillwp_main_func(void *arg) 51241.83Skamil{ 51251.83Skamil the_lwp_id = _lwp_self(); 51261.83Skamil _lwp_exit(); 51271.83Skamil} 51281.83Skamil 51291.1SkamilATF_TC(signal9); 51301.1SkamilATF_TC_HEAD(signal9, tc) 51311.1Skamil{ 51321.1Skamil atf_tc_set_md_var(tc, "descr", 51331.1Skamil "Verify that masking SIGTRAP in tracee does not stop tracer from " 51341.1Skamil "catching PTRACE_LWP_CREATE breakpoint"); 51351.1Skamil} 51361.1Skamil 51371.1SkamilATF_TC_BODY(signal9, tc) 51381.1Skamil{ 51391.1Skamil const int exitval = 5; 51401.1Skamil const int sigval = SIGSTOP; 51411.1Skamil const int sigmasked = SIGTRAP; 51421.1Skamil pid_t child, wpid; 51431.1Skamil#if defined(TWAIT_HAVE_STATUS) 51441.1Skamil int status; 51451.1Skamil#endif 51461.1Skamil sigset_t intmask; 51471.1Skamil ptrace_state_t state; 51481.1Skamil const int slen = sizeof(state); 51491.1Skamil ptrace_event_t event; 51501.1Skamil const int elen = sizeof(event); 51511.1Skamil ucontext_t uc; 51521.1Skamil lwpid_t lid; 51531.1Skamil static const size_t ssize = 16*1024; 51541.1Skamil void *stack; 51551.1Skamil 51561.14Schristos atf_tc_expect_fail("PR kern/51918"); 51571.14Schristos 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.1Skamil sigemptyset(&intmask); 51651.1Skamil sigaddset(&intmask, sigmasked); 51661.1Skamil sigprocmask(SIG_BLOCK, &intmask, NULL); 51671.1Skamil 51681.13Schristos DPRINTF("Before raising %s from child\n", strsignal(sigval)); 51691.1Skamil FORKEE_ASSERT(raise(sigval) == 0); 51701.1Skamil 51711.13Schristos DPRINTF("Before allocating memory for stack in child\n"); 51721.1Skamil FORKEE_ASSERT((stack = malloc(ssize)) != NULL); 51731.1Skamil 51741.13Schristos DPRINTF("Before making context for new lwp in child\n"); 51751.1Skamil _lwp_makecontext(&uc, lwp_main_func, NULL, NULL, stack, ssize); 51761.1Skamil 51771.13Schristos DPRINTF("Before creating new in child\n"); 51781.1Skamil FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0); 51791.1Skamil 51801.13Schristos DPRINTF("Before waiting for lwp %d to exit\n", lid); 51811.1Skamil FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0); 51821.1Skamil 51831.13Schristos DPRINTF("Before verifying that reported %d and running lid %d " 51841.1Skamil "are the same\n", lid, the_lwp_id); 51851.1Skamil FORKEE_ASSERT_EQ(lid, the_lwp_id); 51861.1Skamil 51871.13Schristos DPRINTF("Before exiting of the child process\n"); 51881.1Skamil _exit(exitval); 51891.1Skamil } 51901.13Schristos DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 51911.1Skamil 51921.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 51931.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 51941.1Skamil 51951.1Skamil validate_status_stopped(status, sigval); 51961.1Skamil 51971.13Schristos DPRINTF("Set empty EVENT_MASK for the child %d\n", child); 51981.1Skamil event.pe_set_event = PTRACE_LWP_CREATE; 51991.13Schristos SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); 52001.1Skamil 52011.13Schristos DPRINTF("Before resuming the child process where it left off and " 52021.1Skamil "without signal to be sent\n"); 52031.13Schristos SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 52041.1Skamil 52051.13Schristos DPRINTF("Before calling %s() for the child - expected stopped " 52061.1Skamil "SIGTRAP\n", TWAIT_FNAME); 52071.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 52081.1Skamil 52091.1Skamil validate_status_stopped(status, sigmasked); 52101.1Skamil 52111.13Schristos SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 52121.1Skamil 52131.1Skamil ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_LWP_CREATE); 52141.1Skamil 52151.1Skamil lid = state.pe_lwp; 52161.13Schristos DPRINTF("Reported PTRACE_LWP_CREATE event with lid %d\n", lid); 52171.1Skamil 52181.13Schristos DPRINTF("Before resuming the child process where it left off and " 52191.1Skamil "without signal to be sent\n"); 52201.13Schristos SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 52211.1Skamil 52221.13Schristos DPRINTF("Before calling %s() for the child - expected exited\n", 52231.1Skamil TWAIT_FNAME); 52241.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 52251.1Skamil 52261.1Skamil validate_status_exited(status, exitval); 52271.1Skamil 52281.13Schristos DPRINTF("Before calling %s() for the child - expected no process\n", 52291.1Skamil TWAIT_FNAME); 52301.1Skamil TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 52311.1Skamil} 52321.1Skamil 52331.1SkamilATF_TC(signal10); 52341.1SkamilATF_TC_HEAD(signal10, tc) 52351.1Skamil{ 52361.1Skamil atf_tc_set_md_var(tc, "descr", 52371.1Skamil "Verify that masking SIGTRAP in tracee does not stop tracer from " 52381.1Skamil "catching PTRACE_LWP_EXIT breakpoint"); 52391.1Skamil} 52401.1Skamil 52411.1SkamilATF_TC_BODY(signal10, tc) 52421.1Skamil{ 52431.1Skamil const int exitval = 5; 52441.1Skamil const int sigval = SIGSTOP; 52451.1Skamil const int sigmasked = SIGTRAP; 52461.1Skamil pid_t child, wpid; 52471.1Skamil#if defined(TWAIT_HAVE_STATUS) 52481.1Skamil int status; 52491.1Skamil#endif 52501.1Skamil sigset_t intmask; 52511.1Skamil ptrace_state_t state; 52521.1Skamil const int slen = sizeof(state); 52531.1Skamil ptrace_event_t event; 52541.1Skamil const int elen = sizeof(event); 52551.1Skamil ucontext_t uc; 52561.1Skamil lwpid_t lid; 52571.1Skamil static const size_t ssize = 16*1024; 52581.1Skamil void *stack; 52591.1Skamil 52601.14Schristos atf_tc_expect_fail("PR kern/51918"); 52611.14Schristos 52621.13Schristos DPRINTF("Before forking process PID=%d\n", getpid()); 52631.13Schristos SYSCALL_REQUIRE((child = fork()) != -1); 52641.1Skamil if (child == 0) { 52651.13Schristos DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 52661.1Skamil FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 52671.1Skamil 52681.1Skamil sigemptyset(&intmask); 52691.1Skamil sigaddset(&intmask, sigmasked); 52701.1Skamil sigprocmask(SIG_BLOCK, &intmask, NULL); 52711.1Skamil 52721.13Schristos DPRINTF("Before raising %s from child\n", strsignal(sigval)); 52731.1Skamil FORKEE_ASSERT(raise(sigval) == 0); 52741.1Skamil 52751.13Schristos DPRINTF("Before allocating memory for stack in child\n"); 52761.1Skamil FORKEE_ASSERT((stack = malloc(ssize)) != NULL); 52771.1Skamil 52781.13Schristos DPRINTF("Before making context for new lwp in child\n"); 52791.1Skamil _lwp_makecontext(&uc, lwp_main_func, NULL, NULL, stack, ssize); 52801.1Skamil 52811.13Schristos DPRINTF("Before creating new in child\n"); 52821.1Skamil FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0); 52831.1Skamil 52841.13Schristos DPRINTF("Before waiting for lwp %d to exit\n", lid); 52851.1Skamil FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0); 52861.1Skamil 52871.13Schristos DPRINTF("Before verifying that reported %d and running lid %d " 52881.1Skamil "are the same\n", lid, the_lwp_id); 52891.1Skamil FORKEE_ASSERT_EQ(lid, the_lwp_id); 52901.1Skamil 52911.13Schristos DPRINTF("Before exiting of the child process\n"); 52921.1Skamil _exit(exitval); 52931.1Skamil } 52941.13Schristos DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 52951.1Skamil 52961.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 52971.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 52981.1Skamil 52991.1Skamil validate_status_stopped(status, sigval); 53001.1Skamil 53011.13Schristos DPRINTF("Set empty EVENT_MASK for the child %d\n", child); 53021.1Skamil event.pe_set_event = PTRACE_LWP_EXIT; 53031.13Schristos SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); 53041.1Skamil 53051.13Schristos DPRINTF("Before resuming the child process where it left off and " 53061.1Skamil "without signal to be sent\n"); 53071.13Schristos SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 53081.1Skamil 53091.13Schristos DPRINTF("Before calling %s() for the child - expected stopped " 53101.1Skamil "SIGTRAP\n", TWAIT_FNAME); 53111.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 53121.1Skamil 53131.1Skamil validate_status_stopped(status, sigmasked); 53141.1Skamil 53151.13Schristos SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 53161.1Skamil 53171.1Skamil ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_LWP_EXIT); 53181.1Skamil 53191.1Skamil lid = state.pe_lwp; 53201.13Schristos DPRINTF("Reported PTRACE_LWP_EXIT event with lid %d\n", lid); 53211.1Skamil 53221.13Schristos DPRINTF("Before resuming the child process where it left off and " 53231.1Skamil "without signal to be sent\n"); 53241.13Schristos SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 53251.1Skamil 53261.13Schristos DPRINTF("Before calling %s() for the child - expected exited\n", 53271.1Skamil TWAIT_FNAME); 53281.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 53291.1Skamil 53301.1Skamil validate_status_exited(status, exitval); 53311.1Skamil 53321.13Schristos DPRINTF("Before calling %s() for the child - expected no process\n", 53331.1Skamil TWAIT_FNAME); 53341.1Skamil TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 53351.1Skamil} 53361.1Skamil 53371.1Skamilstatic void 53381.1Skamillwp_main_stop(void *arg) 53391.1Skamil{ 53401.1Skamil the_lwp_id = _lwp_self(); 53411.1Skamil 53421.1Skamil raise(SIGTRAP); 53431.1Skamil 53441.1Skamil _lwp_exit(); 53451.1Skamil} 53461.1Skamil 53471.1SkamilATF_TC(suspend1); 53481.1SkamilATF_TC_HEAD(suspend1, tc) 53491.1Skamil{ 53501.1Skamil atf_tc_set_md_var(tc, "descr", 53511.1Skamil "Verify that a thread can be suspended by a debugger and later " 53521.1Skamil "resumed by a tracee"); 53531.1Skamil} 53541.1Skamil 53551.1SkamilATF_TC_BODY(suspend1, tc) 53561.1Skamil{ 53571.1Skamil const int exitval = 5; 53581.1Skamil const int sigval = SIGSTOP; 53591.1Skamil pid_t child, wpid; 53601.1Skamil#if defined(TWAIT_HAVE_STATUS) 53611.1Skamil int status; 53621.1Skamil#endif 53631.1Skamil ucontext_t uc; 53641.1Skamil lwpid_t lid; 53651.1Skamil static const size_t ssize = 16*1024; 53661.1Skamil void *stack; 53671.1Skamil struct ptrace_lwpinfo pl; 53681.1Skamil struct ptrace_siginfo psi; 53691.1Skamil volatile int go = 0; 53701.1Skamil 53711.17Skamil // Feature pending for refactoring 53721.17Skamil atf_tc_expect_fail("PR kern/51995"); 53731.17Skamil 53741.16Skamil // Hangs with qemu 53751.16Skamil ATF_REQUIRE(0 && "In order to get reliable failure, abort"); 53761.16Skamil 53771.13Schristos DPRINTF("Before forking process PID=%d\n", getpid()); 53781.13Schristos SYSCALL_REQUIRE((child = fork()) != -1); 53791.1Skamil if (child == 0) { 53801.13Schristos DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 53811.1Skamil FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 53821.1Skamil 53831.13Schristos DPRINTF("Before raising %s from child\n", strsignal(sigval)); 53841.1Skamil FORKEE_ASSERT(raise(sigval) == 0); 53851.1Skamil 53861.13Schristos DPRINTF("Before allocating memory for stack in child\n"); 53871.1Skamil FORKEE_ASSERT((stack = malloc(ssize)) != NULL); 53881.1Skamil 53891.13Schristos DPRINTF("Before making context for new lwp in child\n"); 53901.1Skamil _lwp_makecontext(&uc, lwp_main_stop, NULL, NULL, stack, ssize); 53911.1Skamil 53921.13Schristos DPRINTF("Before creating new in child\n"); 53931.1Skamil FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0); 53941.1Skamil 53951.1Skamil while (go == 0) 53961.1Skamil continue; 53971.1Skamil 53981.1Skamil raise(SIGINT); 53991.1Skamil 54001.1Skamil FORKEE_ASSERT(_lwp_continue(lid) == 0); 54011.1Skamil 54021.13Schristos DPRINTF("Before waiting for lwp %d to exit\n", lid); 54031.1Skamil FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0); 54041.1Skamil 54051.13Schristos DPRINTF("Before verifying that reported %d and running lid %d " 54061.1Skamil "are the same\n", lid, the_lwp_id); 54071.1Skamil FORKEE_ASSERT_EQ(lid, the_lwp_id); 54081.1Skamil 54091.13Schristos DPRINTF("Before exiting of the child process\n"); 54101.1Skamil _exit(exitval); 54111.1Skamil } 54121.13Schristos DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 54131.1Skamil 54141.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 54151.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 54161.1Skamil 54171.1Skamil validate_status_stopped(status, sigval); 54181.1Skamil 54191.13Schristos DPRINTF("Before resuming the child process where it left off and " 54201.1Skamil "without signal to be sent\n"); 54211.13Schristos SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 54221.1Skamil 54231.13Schristos DPRINTF("Before calling %s() for the child - expected stopped " 54241.1Skamil "SIGTRAP\n", TWAIT_FNAME); 54251.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 54261.1Skamil 54271.1Skamil validate_status_stopped(status, SIGTRAP); 54281.1Skamil 54291.13Schristos DPRINTF("Before reading siginfo and lwpid_t\n"); 54301.13Schristos SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &psi, sizeof(psi)) != -1); 54311.1Skamil 54321.13Schristos DPRINTF("Before suspending LWP %d\n", psi.psi_lwpid); 54331.13Schristos SYSCALL_REQUIRE(ptrace(PT_SUSPEND, child, NULL, psi.psi_lwpid) != -1); 54341.1Skamil 54351.13Schristos DPRINTF("Write new go to tracee (PID=%d) from tracer (PID=%d)\n", 54361.1Skamil child, getpid()); 54371.13Schristos SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, __UNVOLATILE(&go), 1) != -1); 54381.1Skamil 54391.13Schristos DPRINTF("Before resuming the child process where it left off and " 54401.1Skamil "without signal to be sent\n"); 54411.13Schristos SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 54421.1Skamil 54431.13Schristos DPRINTF("Before calling %s() for the child - expected stopped " 54441.1Skamil "SIGINT\n", TWAIT_FNAME); 54451.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 54461.1Skamil 54471.1Skamil validate_status_stopped(status, SIGINT); 54481.1Skamil 54491.1Skamil pl.pl_lwpid = 0; 54501.1Skamil 54511.13Schristos SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &pl, sizeof(pl)) != -1); 54521.1Skamil while (pl.pl_lwpid != 0) { 54531.1Skamil 54541.13Schristos SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &pl, sizeof(pl)) != -1); 54551.1Skamil switch (pl.pl_lwpid) { 54561.1Skamil case 1: 54571.1Skamil ATF_REQUIRE_EQ(pl.pl_event, PL_EVENT_SIGNAL); 54581.1Skamil break; 54591.1Skamil case 2: 54601.1Skamil ATF_REQUIRE_EQ(pl.pl_event, PL_EVENT_SUSPENDED); 54611.1Skamil break; 54621.1Skamil } 54631.1Skamil } 54641.1Skamil 54651.13Schristos DPRINTF("Before resuming the child process where it left off and " 54661.1Skamil "without signal to be sent\n"); 54671.13Schristos SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 54681.1Skamil 54691.13Schristos DPRINTF("Before calling %s() for the child - expected exited\n", 54701.1Skamil TWAIT_FNAME); 54711.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 54721.1Skamil 54731.1Skamil validate_status_exited(status, exitval); 54741.1Skamil 54751.13Schristos DPRINTF("Before calling %s() for the child - expected no process\n", 54761.1Skamil TWAIT_FNAME); 54771.1Skamil TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 54781.1Skamil} 54791.1Skamil 54801.1SkamilATF_TC(suspend2); 54811.1SkamilATF_TC_HEAD(suspend2, tc) 54821.1Skamil{ 54831.1Skamil atf_tc_set_md_var(tc, "descr", 54841.1Skamil "Verify that the while the only thread within a process is " 54851.1Skamil "suspended, the whole process cannot be unstopped"); 54861.1Skamil} 54871.1Skamil 54881.1SkamilATF_TC_BODY(suspend2, tc) 54891.1Skamil{ 54901.1Skamil const int exitval = 5; 54911.1Skamil const int sigval = SIGSTOP; 54921.1Skamil pid_t child, wpid; 54931.1Skamil#if defined(TWAIT_HAVE_STATUS) 54941.1Skamil int status; 54951.1Skamil#endif 54961.1Skamil struct ptrace_siginfo psi; 54971.1Skamil 54981.17Skamil // Feature pending for refactoring 54991.17Skamil atf_tc_expect_fail("PR kern/51995"); 55001.17Skamil 55011.16Skamil // Hangs with qemu 55021.16Skamil ATF_REQUIRE(0 && "In order to get reliable failure, abort"); 55031.16Skamil 55041.13Schristos DPRINTF("Before forking process PID=%d\n", getpid()); 55051.13Schristos SYSCALL_REQUIRE((child = fork()) != -1); 55061.1Skamil if (child == 0) { 55071.13Schristos DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 55081.1Skamil FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 55091.1Skamil 55101.13Schristos DPRINTF("Before raising %s from child\n", strsignal(sigval)); 55111.1Skamil FORKEE_ASSERT(raise(sigval) == 0); 55121.1Skamil 55131.13Schristos DPRINTF("Before exiting of the child process\n"); 55141.1Skamil _exit(exitval); 55151.1Skamil } 55161.13Schristos DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 55171.1Skamil 55181.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 55191.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 55201.1Skamil 55211.1Skamil validate_status_stopped(status, sigval); 55221.1Skamil 55231.13Schristos DPRINTF("Before reading siginfo and lwpid_t\n"); 55241.13Schristos SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &psi, sizeof(psi)) != -1); 55251.1Skamil 55261.13Schristos DPRINTF("Before suspending LWP %d\n", psi.psi_lwpid); 55271.13Schristos SYSCALL_REQUIRE(ptrace(PT_SUSPEND, child, NULL, psi.psi_lwpid) != -1); 55281.1Skamil 55291.13Schristos DPRINTF("Before resuming the child process where it left off and " 55301.1Skamil "without signal to be sent\n"); 55311.1Skamil ATF_REQUIRE_ERRNO(EDEADLK, 55321.1Skamil ptrace(PT_CONTINUE, child, (void *)1, 0) == -1); 55331.1Skamil 55341.13Schristos DPRINTF("Before resuming LWP %d\n", psi.psi_lwpid); 55351.13Schristos SYSCALL_REQUIRE(ptrace(PT_RESUME, child, NULL, psi.psi_lwpid) != -1); 55361.1Skamil 55371.13Schristos DPRINTF("Before resuming the child process where it left off and " 55381.1Skamil "without signal to be sent\n"); 55391.13Schristos SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 55401.1Skamil 55411.13Schristos DPRINTF("Before calling %s() for the child - expected exited\n", 55421.1Skamil TWAIT_FNAME); 55431.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 55441.1Skamil 55451.1Skamil validate_status_exited(status, exitval); 55461.1Skamil 55471.13Schristos DPRINTF("Before calling %s() for the child - expected no process\n", 55481.1Skamil TWAIT_FNAME); 55491.1Skamil TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 55501.1Skamil} 55511.1Skamil 55521.1SkamilATF_TC(resume1); 55531.1SkamilATF_TC_HEAD(resume1, tc) 55541.1Skamil{ 55551.1Skamil atf_tc_set_md_var(tc, "timeout", "5"); 55561.1Skamil atf_tc_set_md_var(tc, "descr", 55571.1Skamil "Verify that a thread can be suspended by a debugger and later " 55581.1Skamil "resumed by the debugger"); 55591.1Skamil} 55601.1Skamil 55611.1SkamilATF_TC_BODY(resume1, tc) 55621.1Skamil{ 55631.1Skamil struct msg_fds fds; 55641.1Skamil const int exitval = 5; 55651.1Skamil const int sigval = SIGSTOP; 55661.1Skamil pid_t child, wpid; 55671.1Skamil uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */ 55681.1Skamil#if defined(TWAIT_HAVE_STATUS) 55691.1Skamil int status; 55701.1Skamil#endif 55711.1Skamil ucontext_t uc; 55721.1Skamil lwpid_t lid; 55731.1Skamil static const size_t ssize = 16*1024; 55741.1Skamil void *stack; 55751.1Skamil struct ptrace_lwpinfo pl; 55761.1Skamil struct ptrace_siginfo psi; 55771.1Skamil 55781.17Skamil // Feature pending for refactoring 55791.17Skamil atf_tc_expect_fail("PR kern/51995"); 55801.17Skamil 55811.15Schristos // Hangs with qemu 55821.15Schristos ATF_REQUIRE(0 && "In order to get reliable failure, abort"); 55831.1Skamil 55841.13Schristos SYSCALL_REQUIRE(msg_open(&fds) == 0); 55851.1Skamil 55861.13Schristos DPRINTF("Before forking process PID=%d\n", getpid()); 55871.13Schristos SYSCALL_REQUIRE((child = fork()) != -1); 55881.1Skamil if (child == 0) { 55891.13Schristos DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 55901.1Skamil FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 55911.1Skamil 55921.13Schristos DPRINTF("Before raising %s from child\n", strsignal(sigval)); 55931.1Skamil FORKEE_ASSERT(raise(sigval) == 0); 55941.1Skamil 55951.13Schristos DPRINTF("Before allocating memory for stack in child\n"); 55961.1Skamil FORKEE_ASSERT((stack = malloc(ssize)) != NULL); 55971.1Skamil 55981.13Schristos DPRINTF("Before making context for new lwp in child\n"); 55991.1Skamil _lwp_makecontext(&uc, lwp_main_stop, NULL, NULL, stack, ssize); 56001.1Skamil 56011.13Schristos DPRINTF("Before creating new in child\n"); 56021.1Skamil FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0); 56031.1Skamil 56041.1Skamil CHILD_TO_PARENT("Message", fds, msg); 56051.1Skamil 56061.1Skamil raise(SIGINT); 56071.1Skamil 56081.13Schristos DPRINTF("Before waiting for lwp %d to exit\n", lid); 56091.1Skamil FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0); 56101.1Skamil 56111.13Schristos DPRINTF("Before verifying that reported %d and running lid %d " 56121.1Skamil "are the same\n", lid, the_lwp_id); 56131.1Skamil FORKEE_ASSERT_EQ(lid, the_lwp_id); 56141.1Skamil 56151.13Schristos DPRINTF("Before exiting of the child process\n"); 56161.1Skamil _exit(exitval); 56171.1Skamil } 56181.13Schristos DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 56191.1Skamil 56201.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 56211.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 56221.1Skamil 56231.1Skamil validate_status_stopped(status, sigval); 56241.1Skamil 56251.13Schristos DPRINTF("Before resuming the child process where it left off and " 56261.1Skamil "without signal to be sent\n"); 56271.13Schristos SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 56281.1Skamil 56291.13Schristos DPRINTF("Before calling %s() for the child - expected stopped " 56301.1Skamil "SIGTRAP\n", TWAIT_FNAME); 56311.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 56321.1Skamil 56331.1Skamil validate_status_stopped(status, SIGTRAP); 56341.1Skamil 56351.13Schristos DPRINTF("Before reading siginfo and lwpid_t\n"); 56361.13Schristos SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &psi, sizeof(psi)) != -1); 56371.1Skamil 56381.13Schristos DPRINTF("Before suspending LWP %d\n", psi.psi_lwpid); 56391.13Schristos SYSCALL_REQUIRE(ptrace(PT_SUSPEND, child, NULL, psi.psi_lwpid) != -1); 56401.1Skamil 56411.1Skamil PARENT_FROM_CHILD("Message", fds, msg); 56421.1Skamil 56431.13Schristos DPRINTF("Before resuming the child process where it left off and " 56441.1Skamil "without signal to be sent\n"); 56451.13Schristos SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 56461.1Skamil 56471.13Schristos DPRINTF("Before calling %s() for the child - expected stopped " 56481.1Skamil "SIGINT\n", TWAIT_FNAME); 56491.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 56501.1Skamil 56511.1Skamil validate_status_stopped(status, SIGINT); 56521.1Skamil 56531.1Skamil pl.pl_lwpid = 0; 56541.1Skamil 56551.13Schristos SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &pl, sizeof(pl)) != -1); 56561.1Skamil while (pl.pl_lwpid != 0) { 56571.13Schristos SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &pl, sizeof(pl)) != -1); 56581.1Skamil switch (pl.pl_lwpid) { 56591.1Skamil case 1: 56601.1Skamil ATF_REQUIRE_EQ(pl.pl_event, PL_EVENT_SIGNAL); 56611.1Skamil break; 56621.1Skamil case 2: 56631.1Skamil ATF_REQUIRE_EQ(pl.pl_event, PL_EVENT_SUSPENDED); 56641.1Skamil break; 56651.1Skamil } 56661.1Skamil } 56671.1Skamil 56681.13Schristos DPRINTF("Before resuming LWP %d\n", psi.psi_lwpid); 56691.13Schristos SYSCALL_REQUIRE(ptrace(PT_RESUME, child, NULL, psi.psi_lwpid) != -1); 56701.1Skamil 56711.13Schristos DPRINTF("Before resuming the child process where it left off and " 56721.1Skamil "without signal to be sent\n"); 56731.13Schristos SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 56741.1Skamil 56751.13Schristos DPRINTF("Before calling %s() for the child - expected exited\n", 56761.1Skamil TWAIT_FNAME); 56771.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 56781.1Skamil 56791.1Skamil validate_status_exited(status, exitval); 56801.1Skamil 56811.13Schristos DPRINTF("Before calling %s() for the child - expected no process\n", 56821.1Skamil TWAIT_FNAME); 56831.1Skamil TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 56841.1Skamil 56851.1Skamil msg_close(&fds); 56861.1Skamil 56871.13Schristos DPRINTF("XXX: Test worked this time but for consistency timeout it\n"); 56881.1Skamil sleep(10); 56891.1Skamil} 56901.1Skamil 56911.1SkamilATF_TC(syscall1); 56921.1SkamilATF_TC_HEAD(syscall1, tc) 56931.1Skamil{ 56941.1Skamil atf_tc_set_md_var(tc, "descr", 56951.1Skamil "Verify that getpid(2) can be traced with PT_SYSCALL"); 56961.1Skamil} 56971.1Skamil 56981.1SkamilATF_TC_BODY(syscall1, tc) 56991.1Skamil{ 57001.1Skamil const int exitval = 5; 57011.1Skamil const int sigval = SIGSTOP; 57021.1Skamil pid_t child, wpid; 57031.1Skamil#if defined(TWAIT_HAVE_STATUS) 57041.1Skamil int status; 57051.1Skamil#endif 57061.1Skamil struct ptrace_siginfo info; 57071.1Skamil memset(&info, 0, sizeof(info)); 57081.1Skamil 57091.13Schristos DPRINTF("Before forking process PID=%d\n", getpid()); 57101.13Schristos SYSCALL_REQUIRE((child = fork()) != -1); 57111.1Skamil if (child == 0) { 57121.13Schristos DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 57131.1Skamil FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 57141.1Skamil 57151.13Schristos DPRINTF("Before raising %s from child\n", strsignal(sigval)); 57161.1Skamil FORKEE_ASSERT(raise(sigval) == 0); 57171.1Skamil 57181.1Skamil syscall(SYS_getpid); 57191.1Skamil 57201.13Schristos DPRINTF("Before exiting of the child process\n"); 57211.1Skamil _exit(exitval); 57221.1Skamil } 57231.13Schristos DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 57241.1Skamil 57251.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 57261.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 57271.1Skamil 57281.1Skamil validate_status_stopped(status, sigval); 57291.1Skamil 57301.13Schristos DPRINTF("Before resuming the child process where it left off and " 57311.1Skamil "without signal to be sent\n"); 57321.13Schristos SYSCALL_REQUIRE(ptrace(PT_SYSCALL, child, (void *)1, 0) != -1); 57331.1Skamil 57341.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 57351.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 57361.1Skamil 57371.1Skamil validate_status_stopped(status, SIGTRAP); 57381.1Skamil 57391.13Schristos DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 57401.13Schristos SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 57411.1Skamil 57421.38Skamil DPRINTF("Before checking siginfo_t and lwpid\n"); 57431.38Skamil ATF_REQUIRE_EQ(info.psi_lwpid, 1); 57441.1Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); 57451.1Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_SCE); 57461.1Skamil 57471.13Schristos DPRINTF("Before resuming the child process where it left off and " 57481.1Skamil "without signal to be sent\n"); 57491.13Schristos SYSCALL_REQUIRE(ptrace(PT_SYSCALL, child, (void *)1, 0) != -1); 57501.1Skamil 57511.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 57521.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 57531.1Skamil 57541.1Skamil validate_status_stopped(status, SIGTRAP); 57551.1Skamil 57561.13Schristos DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 57571.13Schristos SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 57581.1Skamil 57591.38Skamil DPRINTF("Before checking siginfo_t and lwpid\n"); 57601.38Skamil ATF_REQUIRE_EQ(info.psi_lwpid, 1); 57611.1Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); 57621.1Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_SCX); 57631.1Skamil 57641.13Schristos DPRINTF("Before resuming the child process where it left off and " 57651.1Skamil "without signal to be sent\n"); 57661.13Schristos SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 57671.1Skamil 57681.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 57691.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 57701.1Skamil 57711.1Skamil validate_status_exited(status, exitval); 57721.1Skamil 57731.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 57741.1Skamil TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 57751.1Skamil} 57761.1Skamil 57771.1SkamilATF_TC(syscallemu1); 57781.1SkamilATF_TC_HEAD(syscallemu1, tc) 57791.1Skamil{ 57801.1Skamil atf_tc_set_md_var(tc, "descr", 57811.1Skamil "Verify that exit(2) can be intercepted with PT_SYSCALLEMU"); 57821.1Skamil} 57831.1Skamil 57841.1SkamilATF_TC_BODY(syscallemu1, tc) 57851.1Skamil{ 57861.1Skamil const int exitval = 5; 57871.1Skamil const int sigval = SIGSTOP; 57881.1Skamil pid_t child, wpid; 57891.1Skamil#if defined(TWAIT_HAVE_STATUS) 57901.1Skamil int status; 57911.1Skamil#endif 57921.1Skamil 57931.6Skamil#if defined(__sparc__) && !defined(__sparc64__) 57941.6Skamil /* syscallemu does not work on sparc (32-bit) */ 57951.6Skamil atf_tc_expect_fail("PR kern/52166"); 57961.6Skamil#endif 57971.6Skamil 57981.13Schristos DPRINTF("Before forking process PID=%d\n", getpid()); 57991.13Schristos SYSCALL_REQUIRE((child = fork()) != -1); 58001.1Skamil if (child == 0) { 58011.13Schristos DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 58021.1Skamil FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 58031.1Skamil 58041.13Schristos DPRINTF("Before raising %s from child\n", strsignal(sigval)); 58051.1Skamil FORKEE_ASSERT(raise(sigval) == 0); 58061.1Skamil 58071.1Skamil syscall(SYS_exit, 100); 58081.1Skamil 58091.13Schristos DPRINTF("Before exiting of the child process\n"); 58101.1Skamil _exit(exitval); 58111.1Skamil } 58121.13Schristos DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 58131.1Skamil 58141.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 58151.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 58161.1Skamil 58171.1Skamil validate_status_stopped(status, sigval); 58181.1Skamil 58191.13Schristos DPRINTF("Before resuming the child process where it left off and " 58201.1Skamil "without signal to be sent\n"); 58211.13Schristos SYSCALL_REQUIRE(ptrace(PT_SYSCALL, child, (void *)1, 0) != -1); 58221.1Skamil 58231.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 58241.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 58251.1Skamil 58261.1Skamil validate_status_stopped(status, SIGTRAP); 58271.1Skamil 58281.13Schristos DPRINTF("Set SYSCALLEMU for intercepted syscall\n"); 58291.13Schristos SYSCALL_REQUIRE(ptrace(PT_SYSCALLEMU, child, (void *)1, 0) != -1); 58301.1Skamil 58311.13Schristos DPRINTF("Before resuming the child process where it left off and " 58321.1Skamil "without signal to be sent\n"); 58331.13Schristos SYSCALL_REQUIRE(ptrace(PT_SYSCALL, child, (void *)1, 0) != -1); 58341.1Skamil 58351.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 58361.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 58371.1Skamil 58381.1Skamil validate_status_stopped(status, SIGTRAP); 58391.1Skamil 58401.13Schristos DPRINTF("Before resuming the child process where it left off and " 58411.1Skamil "without signal to be sent\n"); 58421.13Schristos SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 58431.1Skamil 58441.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 58451.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 58461.1Skamil 58471.1Skamil validate_status_exited(status, exitval); 58481.1Skamil 58491.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 58501.1Skamil TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 58511.1Skamil} 58521.1Skamil 58531.1Skamil#include "t_ptrace_amd64_wait.h" 58541.1Skamil#include "t_ptrace_i386_wait.h" 58551.1Skamil#include "t_ptrace_x86_wait.h" 58561.1Skamil 58571.1SkamilATF_TP_ADD_TCS(tp) 58581.1Skamil{ 58591.1Skamil setvbuf(stdout, NULL, _IONBF, 0); 58601.1Skamil setvbuf(stderr, NULL, _IONBF, 0); 58611.33Skamil 58621.36Skamil ATF_TP_ADD_TC(tp, traceme_raise1); 58631.33Skamil ATF_TP_ADD_TC(tp, traceme_raise2); 58641.33Skamil ATF_TP_ADD_TC(tp, traceme_raise3); 58651.33Skamil ATF_TP_ADD_TC(tp, traceme_raise4); 58661.33Skamil ATF_TP_ADD_TC(tp, traceme_raise5); 58671.85Skamil ATF_TP_ADD_TC(tp, traceme_raise6); 58681.85Skamil ATF_TP_ADD_TC(tp, traceme_raise7); 58691.85Skamil ATF_TP_ADD_TC(tp, traceme_raise8); 58701.85Skamil ATF_TP_ADD_TC(tp, traceme_raise9); 58711.85Skamil ATF_TP_ADD_TC(tp, traceme_raise10); 58721.33Skamil 58731.87Skamil ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored1); 58741.87Skamil ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored2); 58751.87Skamil ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored3); 58761.87Skamil ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored4); 58771.87Skamil ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored5); 58781.87Skamil ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored6); 58791.87Skamil ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored7); 58801.87Skamil ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored8); 58811.87Skamil 58821.86Skamil ATF_TP_ADD_TC(tp, traceme_raisesignal_masked1); 58831.86Skamil ATF_TP_ADD_TC(tp, traceme_raisesignal_masked2); 58841.86Skamil ATF_TP_ADD_TC(tp, traceme_raisesignal_masked3); 58851.86Skamil ATF_TP_ADD_TC(tp, traceme_raisesignal_masked4); 58861.86Skamil ATF_TP_ADD_TC(tp, traceme_raisesignal_masked5); 58871.86Skamil ATF_TP_ADD_TC(tp, traceme_raisesignal_masked6); 58881.86Skamil ATF_TP_ADD_TC(tp, traceme_raisesignal_masked7); 58891.86Skamil ATF_TP_ADD_TC(tp, traceme_raisesignal_masked8); 58901.86Skamil 58911.59Skamil ATF_TP_ADD_TC(tp, traceme_crash_trap); 58921.59Skamil ATF_TP_ADD_TC(tp, traceme_crash_segv); 58931.71Skamil ATF_TP_ADD_TC(tp, traceme_crash_ill); 58941.59Skamil ATF_TP_ADD_TC(tp, traceme_crash_fpe); 58951.59Skamil ATF_TP_ADD_TC(tp, traceme_crash_bus); 58961.59Skamil 58971.88Skamil ATF_TP_ADD_TC(tp, traceme_signalmasked_crash_trap); 58981.88Skamil ATF_TP_ADD_TC(tp, traceme_signalmasked_crash_segv); 58991.88Skamil ATF_TP_ADD_TC(tp, traceme_signalmasked_crash_ill); 59001.88Skamil ATF_TP_ADD_TC(tp, traceme_signalmasked_crash_fpe); 59011.88Skamil ATF_TP_ADD_TC(tp, traceme_signalmasked_crash_bus); 59021.88Skamil 59031.88Skamil ATF_TP_ADD_TC(tp, traceme_signalignored_crash_trap); 59041.88Skamil ATF_TP_ADD_TC(tp, traceme_signalignored_crash_segv); 59051.88Skamil ATF_TP_ADD_TC(tp, traceme_signalignored_crash_ill); 59061.88Skamil ATF_TP_ADD_TC(tp, traceme_signalignored_crash_fpe); 59071.88Skamil ATF_TP_ADD_TC(tp, traceme_signalignored_crash_bus); 59081.88Skamil 59091.50Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_handle1); 59101.50Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_handle2); 59111.50Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_handle3); 59121.85Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_handle4); 59131.85Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_handle5); 59141.85Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_handle6); 59151.85Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_handle7); 59161.85Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_handle8); 59171.50Skamil 59181.50Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_masked1); 59191.50Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_masked2); 59201.50Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_masked3); 59211.85Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_masked4); 59221.85Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_masked5); 59231.85Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_masked6); 59241.85Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_masked7); 59251.85Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_masked8); 59261.50Skamil 59271.50Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored1); 59281.50Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored2); 59291.50Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored3); 59301.85Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored4); 59311.85Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored5); 59321.85Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored6); 59331.85Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored7); 59341.85Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored8); 59351.50Skamil 59361.50Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_simple1); 59371.50Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_simple2); 59381.50Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_simple3); 59391.50Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_simple4); 59401.50Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_simple5); 59411.85Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_simple6); 59421.85Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_simple7); 59431.85Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_simple8); 59441.85Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_simple9); 59451.85Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_simple10); 59461.1Skamil 59471.37Skamil ATF_TP_ADD_TC(tp, traceme_pid1_parent); 59481.37Skamil 59491.40Skamil ATF_TP_ADD_TC(tp, traceme_vfork_raise1); 59501.46Skamil ATF_TP_ADD_TC(tp, traceme_vfork_raise2); 59511.40Skamil ATF_TP_ADD_TC(tp, traceme_vfork_raise3); 59521.40Skamil ATF_TP_ADD_TC(tp, traceme_vfork_raise4); 59531.40Skamil ATF_TP_ADD_TC(tp, traceme_vfork_raise5); 59541.47Skamil ATF_TP_ADD_TC(tp, traceme_vfork_raise6); 59551.47Skamil ATF_TP_ADD_TC(tp, traceme_vfork_raise7); 59561.47Skamil ATF_TP_ADD_TC(tp, traceme_vfork_raise8); 59571.85Skamil ATF_TP_ADD_TC(tp, traceme_vfork_raise9); 59581.85Skamil ATF_TP_ADD_TC(tp, traceme_vfork_raise10); 59591.85Skamil ATF_TP_ADD_TC(tp, traceme_vfork_raise11); 59601.85Skamil ATF_TP_ADD_TC(tp, traceme_vfork_raise12); 59611.85Skamil ATF_TP_ADD_TC(tp, traceme_vfork_raise13); 59621.40Skamil 59631.52Skamil ATF_TP_ADD_TC(tp, traceme_vfork_crash_trap); 59641.52Skamil ATF_TP_ADD_TC(tp, traceme_vfork_crash_segv); 59651.71Skamil ATF_TP_ADD_TC(tp, traceme_vfork_crash_ill); 59661.52Skamil ATF_TP_ADD_TC(tp, traceme_vfork_crash_fpe); 59671.52Skamil ATF_TP_ADD_TC(tp, traceme_vfork_crash_bus); 59681.41Skamil 59691.92Skamil ATF_TP_ADD_TC(tp, traceme_vfork_signalmasked_crash_trap); 59701.92Skamil ATF_TP_ADD_TC(tp, traceme_vfork_signalmasked_crash_segv); 59711.92Skamil ATF_TP_ADD_TC(tp, traceme_vfork_signalmasked_crash_ill); 59721.92Skamil ATF_TP_ADD_TC(tp, traceme_vfork_signalmasked_crash_fpe); 59731.92Skamil ATF_TP_ADD_TC(tp, traceme_vfork_signalmasked_crash_bus); 59741.92Skamil 59751.92Skamil ATF_TP_ADD_TC(tp, traceme_vfork_signalignored_crash_trap); 59761.92Skamil ATF_TP_ADD_TC(tp, traceme_vfork_signalignored_crash_segv); 59771.92Skamil ATF_TP_ADD_TC(tp, traceme_vfork_signalignored_crash_ill); 59781.92Skamil ATF_TP_ADD_TC(tp, traceme_vfork_signalignored_crash_fpe); 59791.92Skamil ATF_TP_ADD_TC(tp, traceme_vfork_signalignored_crash_bus); 59801.92Skamil 59811.43Skamil ATF_TP_ADD_TC(tp, traceme_vfork_exec); 59821.43Skamil 59831.59Skamil ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_sees_crash_trap); 59841.59Skamil ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_sees_crash_segv); 59851.71Skamil ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_sees_crash_ill); 59861.59Skamil ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_sees_crash_fpe); 59871.59Skamil ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_sees_crash_bus); 59881.59Skamil 59891.51Skamil ATF_TP_ADD_TC_HAVE_PID(tp, tracer_sees_terminaton_before_the_parent); 59901.51Skamil ATF_TP_ADD_TC_HAVE_PID(tp, tracer_sysctl_lookup_without_duplicates); 59911.61Skre ATF_TP_ADD_TC_HAVE_PID(tp, 59921.61Skre unrelated_tracer_sees_terminaton_before_the_parent); 59931.67Skamil ATF_TP_ADD_TC_HAVE_PID(tp, tracer_attach_to_unrelated_stopped_process); 59941.51Skamil 59951.51Skamil ATF_TP_ADD_TC(tp, parent_attach_to_its_child); 59961.66Skamil ATF_TP_ADD_TC(tp, parent_attach_to_its_stopped_child); 59971.51Skamil 59981.51Skamil ATF_TP_ADD_TC(tp, child_attach_to_its_parent); 59991.65Skamil ATF_TP_ADD_TC(tp, child_attach_to_its_stopped_parent); 60001.51Skamil 60011.51Skamil ATF_TP_ADD_TC_HAVE_PID(tp, 60021.51Skamil tracee_sees_its_original_parent_getppid); 60031.51Skamil ATF_TP_ADD_TC_HAVE_PID(tp, 60041.51Skamil tracee_sees_its_original_parent_sysctl_kinfo_proc2); 60051.51Skamil ATF_TP_ADD_TC_HAVE_PID(tp, 60061.51Skamil tracee_sees_its_original_parent_procfs_status); 60071.1Skamil 60081.53Skamil ATF_TP_ADD_TC(tp, eventmask_preserved_empty); 60091.53Skamil ATF_TP_ADD_TC(tp, eventmask_preserved_fork); 60101.53Skamil ATF_TP_ADD_TC(tp, eventmask_preserved_vfork); 60111.53Skamil ATF_TP_ADD_TC(tp, eventmask_preserved_vfork_done); 60121.53Skamil ATF_TP_ADD_TC(tp, eventmask_preserved_lwp_create); 60131.53Skamil ATF_TP_ADD_TC(tp, eventmask_preserved_lwp_exit); 60141.1Skamil 60151.31Skamil ATF_TP_ADD_TC(tp, fork1); 60161.31Skamil ATF_TP_ADD_TC_HAVE_PID(tp, fork2); 60171.31Skamil ATF_TP_ADD_TC_HAVE_PID(tp, fork3); 60181.31Skamil ATF_TP_ADD_TC_HAVE_PID(tp, fork4); 60191.31Skamil ATF_TP_ADD_TC(tp, fork5); 60201.31Skamil ATF_TP_ADD_TC_HAVE_PID(tp, fork6); 60211.31Skamil ATF_TP_ADD_TC_HAVE_PID(tp, fork7); 60221.31Skamil ATF_TP_ADD_TC_HAVE_PID(tp, fork8); 60231.31Skamil 60241.31Skamil ATF_TP_ADD_TC(tp, vfork1); 60251.31Skamil ATF_TP_ADD_TC_HAVE_PID(tp, vfork2); 60261.31Skamil ATF_TP_ADD_TC_HAVE_PID(tp, vfork3); 60271.31Skamil ATF_TP_ADD_TC_HAVE_PID(tp, vfork4); 60281.31Skamil ATF_TP_ADD_TC(tp, vfork5); 60291.31Skamil ATF_TP_ADD_TC_HAVE_PID(tp, vfork6); 60301.64Smartin// thes tests hang on SMP machines, disable them for now 60311.64Smartin// ATF_TP_ADD_TC_HAVE_PID(tp, vfork7); 60321.64Smartin// ATF_TP_ADD_TC_HAVE_PID(tp, vfork8); 60331.1Skamil 60341.54Skamil ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_8); 60351.54Skamil ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_16); 60361.54Skamil ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_32); 60371.54Skamil ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_64); 60381.54Skamil 60391.54Skamil ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_8); 60401.54Skamil ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_16); 60411.54Skamil ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_32); 60421.54Skamil ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_64); 60431.54Skamil 60441.54Skamil ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_8); 60451.54Skamil ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_16); 60461.54Skamil ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_32); 60471.54Skamil ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_64); 60481.54Skamil 60491.54Skamil ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_8); 60501.54Skamil ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_16); 60511.54Skamil ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_32); 60521.54Skamil ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_64); 60531.54Skamil 60541.54Skamil ATF_TP_ADD_TC(tp, bytes_transfer_read_d); 60551.54Skamil ATF_TP_ADD_TC(tp, bytes_transfer_read_i); 60561.54Skamil ATF_TP_ADD_TC(tp, bytes_transfer_write_d); 60571.54Skamil ATF_TP_ADD_TC(tp, bytes_transfer_write_i); 60581.54Skamil 60591.54Skamil ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_8_text); 60601.54Skamil ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_16_text); 60611.54Skamil ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_32_text); 60621.54Skamil ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_64_text); 60631.54Skamil 60641.54Skamil ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_8_text); 60651.54Skamil ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_16_text); 60661.54Skamil ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_32_text); 60671.54Skamil ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_64_text); 60681.54Skamil 60691.54Skamil ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_8_text); 60701.54Skamil ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_16_text); 60711.54Skamil ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_32_text); 60721.54Skamil ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_64_text); 60731.54Skamil 60741.54Skamil ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_8_text); 60751.54Skamil ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_16_text); 60761.54Skamil ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_32_text); 60771.54Skamil ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_64_text); 60781.54Skamil 60791.54Skamil ATF_TP_ADD_TC(tp, bytes_transfer_read_d_text); 60801.54Skamil ATF_TP_ADD_TC(tp, bytes_transfer_read_i_text); 60811.54Skamil ATF_TP_ADD_TC(tp, bytes_transfer_write_d_text); 60821.54Skamil ATF_TP_ADD_TC(tp, bytes_transfer_write_i_text); 60831.1Skamil 60841.54Skamil ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_auxv); 60851.1Skamil 60861.72Skamil ATF_TP_ADD_TC_HAVE_GPREGS(tp, access_regs1); 60871.72Skamil ATF_TP_ADD_TC_HAVE_GPREGS(tp, access_regs2); 60881.72Skamil ATF_TP_ADD_TC_HAVE_GPREGS(tp, access_regs3); 60891.72Skamil ATF_TP_ADD_TC_HAVE_GPREGS(tp, access_regs4); 60901.72Skamil ATF_TP_ADD_TC_HAVE_GPREGS(tp, access_regs5); 60911.72Skamil ATF_TP_ADD_TC_HAVE_GPREGS(tp, access_regs6); 60921.1Skamil 60931.72Skamil ATF_TP_ADD_TC_HAVE_FPREGS(tp, access_fpregs1); 60941.72Skamil ATF_TP_ADD_TC_HAVE_FPREGS(tp, access_fpregs2); 60951.1Skamil 60961.1Skamil ATF_TP_ADD_TC_PT_STEP(tp, step1); 60971.1Skamil ATF_TP_ADD_TC_PT_STEP(tp, step2); 60981.1Skamil ATF_TP_ADD_TC_PT_STEP(tp, step3); 60991.1Skamil ATF_TP_ADD_TC_PT_STEP(tp, step4); 61001.1Skamil 61011.2Skamil ATF_TP_ADD_TC_PT_STEP(tp, setstep1); 61021.2Skamil ATF_TP_ADD_TC_PT_STEP(tp, setstep2); 61031.2Skamil ATF_TP_ADD_TC_PT_STEP(tp, setstep3); 61041.2Skamil ATF_TP_ADD_TC_PT_STEP(tp, setstep4); 61051.2Skamil 61061.1Skamil ATF_TP_ADD_TC(tp, kill1); 61071.1Skamil ATF_TP_ADD_TC(tp, kill2); 61081.75Skamil ATF_TP_ADD_TC(tp, kill3); 61091.1Skamil 61101.77Skamil ATF_TP_ADD_TC(tp, traceme_lwpinfo0); 61111.77Skamil ATF_TP_ADD_TC(tp, traceme_lwpinfo1); 61121.77Skamil ATF_TP_ADD_TC(tp, traceme_lwpinfo2); 61131.77Skamil ATF_TP_ADD_TC(tp, traceme_lwpinfo3); 61141.77Skamil 61151.77Skamil ATF_TP_ADD_TC_HAVE_PID(tp, attach_lwpinfo0); 61161.77Skamil ATF_TP_ADD_TC_HAVE_PID(tp, attach_lwpinfo1); 61171.77Skamil ATF_TP_ADD_TC_HAVE_PID(tp, attach_lwpinfo2); 61181.77Skamil ATF_TP_ADD_TC_HAVE_PID(tp, attach_lwpinfo3); 61191.1Skamil 61201.79Skamil ATF_TP_ADD_TC(tp, siginfo_set_unmodified); 61211.79Skamil ATF_TP_ADD_TC(tp, siginfo_set_faked); 61221.79Skamil 61231.82Skamil ATF_TP_ADD_TC(tp, traceme_exec); 61241.1Skamil 61251.83Skamil ATF_TP_ADD_TC(tp, trace_thread1); 61261.83Skamil ATF_TP_ADD_TC(tp, trace_thread2); 61271.83Skamil ATF_TP_ADD_TC(tp, trace_thread3); 61281.83Skamil ATF_TP_ADD_TC(tp, trace_thread4); 61291.1Skamil 61301.84Skamil ATF_TP_ADD_TC(tp, signal_mask_unrelated); 61311.84Skamil 61321.1Skamil ATF_TP_ADD_TC_PT_STEP(tp, signal4); 61331.1Skamil ATF_TP_ADD_TC(tp, signal5); 61341.1Skamil ATF_TP_ADD_TC_HAVE_PID(tp, signal6); 61351.1Skamil ATF_TP_ADD_TC_HAVE_PID(tp, signal7); 61361.1Skamil ATF_TP_ADD_TC(tp, signal8); 61371.1Skamil ATF_TP_ADD_TC(tp, signal9); 61381.1Skamil ATF_TP_ADD_TC(tp, signal10); 61391.1Skamil 61401.1Skamil ATF_TP_ADD_TC(tp, suspend1); 61411.1Skamil ATF_TP_ADD_TC(tp, suspend2); 61421.1Skamil 61431.1Skamil ATF_TP_ADD_TC(tp, resume1); 61441.1Skamil 61451.1Skamil ATF_TP_ADD_TC(tp, syscall1); 61461.1Skamil 61471.1Skamil ATF_TP_ADD_TC(tp, syscallemu1); 61481.1Skamil 61491.1Skamil ATF_TP_ADD_TCS_PTRACE_WAIT_AMD64(); 61501.1Skamil ATF_TP_ADD_TCS_PTRACE_WAIT_I386(); 61511.1Skamil ATF_TP_ADD_TCS_PTRACE_WAIT_X86(); 61521.1Skamil 61531.1Skamil return atf_no_error(); 61541.1Skamil} 6155