t_ptrace_wait.c revision 1.86
11.86Skamil/* $NetBSD: t_ptrace_wait.c,v 1.86 2019/02/14 06:47:32 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.86Skamil__RCSID("$NetBSD: t_ptrace_wait.c,v 1.86 2019/02/14 06:47:32 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.86Skamiltraceme_raisesignal_masked(int sigmasked) 1921.86Skamil{ 1931.86Skamil const int exitval = 5; 1941.86Skamil const int sigval = SIGSTOP; 1951.86Skamil pid_t child, wpid; 1961.86Skamil#if defined(TWAIT_HAVE_STATUS) 1971.86Skamil int status; 1981.86Skamil#endif 1991.86Skamil sigset_t intmask; 2001.86Skamil struct ptrace_siginfo info; 2011.86Skamil 2021.86Skamil memset(&info, 0, sizeof(info)); 2031.86Skamil 2041.86Skamil DPRINTF("Before forking process PID=%d\n", getpid()); 2051.86Skamil SYSCALL_REQUIRE((child = fork()) != -1); 2061.86Skamil if (child == 0) { 2071.86Skamil DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 2081.86Skamil FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 2091.86Skamil 2101.86Skamil sigemptyset(&intmask); 2111.86Skamil sigaddset(&intmask, sigmasked); 2121.86Skamil sigprocmask(SIG_BLOCK, &intmask, NULL); 2131.86Skamil 2141.86Skamil DPRINTF("Before raising %s from child\n", strsignal(sigval)); 2151.86Skamil FORKEE_ASSERT(raise(sigval) == 0); 2161.86Skamil 2171.86Skamil DPRINTF("Before raising %s breakpoint from child\n", 2181.86Skamil strsignal(sigmasked)); 2191.86Skamil FORKEE_ASSERT(raise(sigmasked) == 0); 2201.86Skamil 2211.86Skamil DPRINTF("Before exiting of the child process\n"); 2221.86Skamil _exit(exitval); 2231.86Skamil } 2241.86Skamil DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 2251.86Skamil 2261.86Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 2271.86Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 2281.86Skamil 2291.86Skamil validate_status_stopped(status, sigval); 2301.86Skamil 2311.86Skamil DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 2321.86Skamil SYSCALL_REQUIRE( 2331.86Skamil ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 2341.86Skamil 2351.86Skamil DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 2361.86Skamil DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 2371.86Skamil info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 2381.86Skamil info.psi_siginfo.si_errno); 2391.86Skamil 2401.86Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 2411.86Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 2421.86Skamil 2431.86Skamil DPRINTF("Before resuming the child process where it left off and " 2441.86Skamil "without signal to be sent\n"); 2451.86Skamil SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 2461.86Skamil 2471.86Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 2481.86Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 2491.86Skamil 2501.86Skamil validate_status_exited(status, exitval); 2511.86Skamil 2521.86Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 2531.86Skamil TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 2541.86Skamil} 2551.86Skamil 2561.86Skamil#define TRACEME_RAISESIGNAL_MASKED(test, sig) \ 2571.86SkamilATF_TC(test); \ 2581.86SkamilATF_TC_HEAD(test, tc) \ 2591.86Skamil{ \ 2601.86Skamil atf_tc_set_md_var(tc, "descr", \ 2611.86Skamil "Verify that masking (with SIG_BLOCK) " #sig " in tracee " \ 2621.86Skamil "stops tracer from catching this raised signal"); \ 2631.86Skamil} \ 2641.86Skamil \ 2651.86SkamilATF_TC_BODY(test, tc) \ 2661.86Skamil{ \ 2671.86Skamil \ 2681.86Skamil traceme_raisesignal_masked(sig); \ 2691.86Skamil} 2701.86Skamil 2711.86Skamil// A signal handler for SIGKILL and SIGSTOP cannot be masked. 2721.86SkamilTRACEME_RAISESIGNAL_MASKED(traceme_raisesignal_masked1, SIGABRT) /* abort trap */ 2731.86SkamilTRACEME_RAISESIGNAL_MASKED(traceme_raisesignal_masked2, SIGHUP) /* hangup */ 2741.86SkamilTRACEME_RAISESIGNAL_MASKED(traceme_raisesignal_masked3, SIGCONT) /* continued? */ 2751.86SkamilTRACEME_RAISESIGNAL_MASKED(traceme_raisesignal_masked4, SIGTRAP) /* crash sig. */ 2761.86SkamilTRACEME_RAISESIGNAL_MASKED(traceme_raisesignal_masked5, SIGBUS) /* crash sig. */ 2771.86SkamilTRACEME_RAISESIGNAL_MASKED(traceme_raisesignal_masked6, SIGILL) /* crash sig. */ 2781.86SkamilTRACEME_RAISESIGNAL_MASKED(traceme_raisesignal_masked7, SIGFPE) /* crash sig. */ 2791.86SkamilTRACEME_RAISESIGNAL_MASKED(traceme_raisesignal_masked8, SIGSEGV) /* crash sig. */ 2801.86Skamil 2811.86Skamil/// ---------------------------------------------------------------------------- 2821.86Skamil 2831.86Skamilstatic void 2841.59Skamiltraceme_crash(int sig) 2851.59Skamil{ 2861.59Skamil pid_t child, wpid; 2871.59Skamil#if defined(TWAIT_HAVE_STATUS) 2881.59Skamil int status; 2891.59Skamil#endif 2901.59Skamil struct ptrace_siginfo info; 2911.61Skre 2921.71Skamil#ifndef PTRACE_ILLEGAL_ASM 2931.71Skamil if (sig == SIGILL) 2941.71Skamil atf_tc_skip("PTRACE_ILLEGAL_ASM not defined"); 2951.71Skamil#endif 2961.71Skamil 2971.59Skamil memset(&info, 0, sizeof(info)); 2981.59Skamil 2991.59Skamil DPRINTF("Before forking process PID=%d\n", getpid()); 3001.59Skamil SYSCALL_REQUIRE((child = fork()) != -1); 3011.59Skamil if (child == 0) { 3021.59Skamil DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 3031.59Skamil FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 3041.59Skamil 3051.59Skamil DPRINTF("Before executing a trap\n"); 3061.59Skamil switch (sig) { 3071.59Skamil case SIGTRAP: 3081.59Skamil trigger_trap(); 3091.59Skamil break; 3101.59Skamil case SIGSEGV: 3111.59Skamil trigger_segv(); 3121.59Skamil break; 3131.59Skamil case SIGILL: 3141.59Skamil trigger_ill(); 3151.59Skamil break; 3161.59Skamil case SIGFPE: 3171.59Skamil trigger_fpe(); 3181.59Skamil break; 3191.59Skamil case SIGBUS: 3201.59Skamil trigger_bus(); 3211.59Skamil break; 3221.59Skamil default: 3231.59Skamil /* NOTREACHED */ 3241.59Skamil FORKEE_ASSERTX(0 && "This shall not be reached"); 3251.59Skamil } 3261.59Skamil 3271.59Skamil /* NOTREACHED */ 3281.59Skamil FORKEE_ASSERTX(0 && "This shall not be reached"); 3291.59Skamil } 3301.59Skamil DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 3311.59Skamil 3321.59Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 3331.59Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 3341.59Skamil 3351.59Skamil validate_status_stopped(status, sig); 3361.59Skamil 3371.59Skamil DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child"); 3381.61Skre SYSCALL_REQUIRE( 3391.61Skre ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 3401.59Skamil 3411.59Skamil DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 3421.59Skamil DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 3431.61Skre info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 3441.61Skre info.psi_siginfo.si_errno); 3451.59Skamil 3461.59Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sig); 3471.59Skamil switch (sig) { 3481.59Skamil case SIGTRAP: 3491.59Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_BRKPT); 3501.59Skamil break; 3511.59Skamil case SIGSEGV: 3521.59Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SEGV_MAPERR); 3531.59Skamil break; 3541.71Skamil case SIGILL: 3551.71Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_code, ILL_PRVOPC); 3561.71Skamil break; 3571.59Skamil case SIGFPE: 3581.59Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_code, FPE_INTDIV); 3591.59Skamil break; 3601.59Skamil case SIGBUS: 3611.59Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_code, BUS_ADRERR); 3621.59Skamil break; 3631.59Skamil } 3641.59Skamil 3651.59Skamil SYSCALL_REQUIRE(ptrace(PT_KILL, child, NULL, 0) != -1); 3661.59Skamil 3671.59Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 3681.59Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 3691.59Skamil 3701.59Skamil validate_status_signaled(status, SIGKILL, 0); 3711.59Skamil 3721.59Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 3731.59Skamil TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 3741.59Skamil} 3751.59Skamil 3761.61Skre#define TRACEME_CRASH(test, sig) \ 3771.61SkreATF_TC(test); \ 3781.61SkreATF_TC_HEAD(test, tc) \ 3791.61Skre{ \ 3801.61Skre atf_tc_set_md_var(tc, "descr", \ 3811.61Skre "Verify crash signal " #sig " in a child after PT_TRACE_ME"); \ 3821.61Skre} \ 3831.61Skre \ 3841.61SkreATF_TC_BODY(test, tc) \ 3851.61Skre{ \ 3861.61Skre \ 3871.61Skre traceme_crash(sig); \ 3881.59Skamil} 3891.59Skamil 3901.59SkamilTRACEME_CRASH(traceme_crash_trap, SIGTRAP) 3911.59SkamilTRACEME_CRASH(traceme_crash_segv, SIGSEGV) 3921.71SkamilTRACEME_CRASH(traceme_crash_ill, SIGILL) 3931.59SkamilTRACEME_CRASH(traceme_crash_fpe, SIGFPE) 3941.59SkamilTRACEME_CRASH(traceme_crash_bus, SIGBUS) 3951.59Skamil 3961.59Skamil/// ---------------------------------------------------------------------------- 3971.59Skamil 3981.59Skamilstatic void 3991.50Skamiltraceme_sendsignal_handle(int sigsent, void (*sah)(int a), int *traceme_caught) 4001.1Skamil{ 4011.1Skamil const int exitval = 5; 4021.34Skamil const int sigval = SIGSTOP; 4031.1Skamil pid_t child, wpid; 4041.1Skamil struct sigaction sa; 4051.1Skamil#if defined(TWAIT_HAVE_STATUS) 4061.1Skamil int status; 4071.1Skamil#endif 4081.61Skre struct ptrace_siginfo info; 4091.1Skamil 4101.45Skamil memset(&info, 0, sizeof(info)); 4111.45Skamil 4121.13Schristos DPRINTF("Before forking process PID=%d\n", getpid()); 4131.13Schristos SYSCALL_REQUIRE((child = fork()) != -1); 4141.1Skamil if (child == 0) { 4151.13Schristos DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 4161.1Skamil FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 4171.1Skamil 4181.34Skamil sa.sa_handler = sah; 4191.1Skamil sa.sa_flags = SA_SIGINFO; 4201.1Skamil sigemptyset(&sa.sa_mask); 4211.1Skamil 4221.1Skamil FORKEE_ASSERT(sigaction(sigsent, &sa, NULL) != -1); 4231.1Skamil 4241.13Schristos DPRINTF("Before raising %s from child\n", strsignal(sigval)); 4251.1Skamil FORKEE_ASSERT(raise(sigval) == 0); 4261.1Skamil 4271.34Skamil FORKEE_ASSERT_EQ(*traceme_caught, 1); 4281.1Skamil 4291.13Schristos DPRINTF("Before exiting of the child process\n"); 4301.1Skamil _exit(exitval); 4311.1Skamil } 4321.13Schristos DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 4331.1Skamil 4341.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4351.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4361.1Skamil 4371.1Skamil validate_status_stopped(status, sigval); 4381.1Skamil 4391.45Skamil DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 4401.61Skre SYSCALL_REQUIRE( 4411.61Skre ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 4421.45Skamil 4431.45Skamil DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 4441.45Skamil DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 4451.45Skamil info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 4461.45Skamil info.psi_siginfo.si_errno); 4471.45Skamil 4481.45Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 4491.45Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 4501.45Skamil 4511.13Schristos DPRINTF("Before resuming the child process where it left off and with " 4521.1Skamil "signal %s to be sent\n", strsignal(sigsent)); 4531.13Schristos SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigsent) != -1); 4541.1Skamil 4551.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4561.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4571.1Skamil 4581.1Skamil validate_status_exited(status, exitval); 4591.1Skamil 4601.13Schristos DPRINTF("Before calling %s() for the exited child\n", TWAIT_FNAME); 4611.1Skamil TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 4621.1Skamil} 4631.1Skamil 4641.61Skre#define TRACEME_SENDSIGNAL_HANDLE(test, sig) \ 4651.61SkreATF_TC(test); \ 4661.61SkreATF_TC_HEAD(test, tc) \ 4671.61Skre{ \ 4681.61Skre atf_tc_set_md_var(tc, "descr", \ 4691.61Skre "Verify that a signal " #sig " emitted by a tracer to a child is " \ 4701.61Skre "handled correctly and caught by a signal handler"); \ 4711.61Skre} \ 4721.61Skre \ 4731.61Skrestatic int test##_caught = 0; \ 4741.61Skre \ 4751.61Skrestatic void \ 4761.61Skretest##_sighandler(int arg) \ 4771.61Skre{ \ 4781.61Skre FORKEE_ASSERT_EQ(arg, sig); \ 4791.61Skre \ 4801.61Skre ++ test##_caught; \ 4811.61Skre} \ 4821.61Skre \ 4831.61SkreATF_TC_BODY(test, tc) \ 4841.61Skre{ \ 4851.61Skre \ 4861.61Skre traceme_sendsignal_handle(sig, test##_sighandler, & test##_caught); \ 4871.34Skamil} 4881.34Skamil 4891.34Skamil// A signal handler for SIGKILL and SIGSTOP cannot be registered. 4901.50SkamilTRACEME_SENDSIGNAL_HANDLE(traceme_sendsignal_handle1, SIGABRT) /* abort trap */ 4911.50SkamilTRACEME_SENDSIGNAL_HANDLE(traceme_sendsignal_handle2, SIGHUP) /* hangup */ 4921.50SkamilTRACEME_SENDSIGNAL_HANDLE(traceme_sendsignal_handle3, SIGCONT) /* continued? */ 4931.85SkamilTRACEME_SENDSIGNAL_HANDLE(traceme_sendsignal_handle4, SIGTRAP) /* crash sig. */ 4941.85SkamilTRACEME_SENDSIGNAL_HANDLE(traceme_sendsignal_handle5, SIGBUS) /* crash sig. */ 4951.85SkamilTRACEME_SENDSIGNAL_HANDLE(traceme_sendsignal_handle6, SIGILL) /* crash sig. */ 4961.85SkamilTRACEME_SENDSIGNAL_HANDLE(traceme_sendsignal_handle7, SIGFPE) /* crash sig. */ 4971.85SkamilTRACEME_SENDSIGNAL_HANDLE(traceme_sendsignal_handle8, SIGSEGV) /* crash sig. */ 4981.34Skamil 4991.34Skamil/// ---------------------------------------------------------------------------- 5001.34Skamil 5011.35Skamilstatic void 5021.50Skamiltraceme_sendsignal_masked(int sigsent) 5031.50Skamil{ 5041.50Skamil const int exitval = 5; 5051.50Skamil const int sigval = SIGSTOP; 5061.50Skamil pid_t child, wpid; 5071.50Skamil sigset_t set; 5081.50Skamil#if defined(TWAIT_HAVE_STATUS) 5091.50Skamil int status; 5101.50Skamil#endif 5111.61Skre struct ptrace_siginfo info; 5121.50Skamil 5131.50Skamil memset(&info, 0, sizeof(info)); 5141.50Skamil 5151.50Skamil DPRINTF("Before forking process PID=%d\n", getpid()); 5161.50Skamil SYSCALL_REQUIRE((child = fork()) != -1); 5171.50Skamil if (child == 0) { 5181.50Skamil DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 5191.50Skamil FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 5201.50Skamil 5211.50Skamil sigemptyset(&set); 5221.50Skamil sigaddset(&set, sigsent); 5231.50Skamil FORKEE_ASSERT(sigprocmask(SIG_BLOCK, &set, NULL) != -1); 5241.50Skamil 5251.50Skamil DPRINTF("Before raising %s from child\n", strsignal(sigval)); 5261.50Skamil FORKEE_ASSERT(raise(sigval) == 0); 5271.50Skamil 5281.50Skamil _exit(exitval); 5291.50Skamil } 5301.50Skamil DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 5311.50Skamil 5321.50Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 5331.50Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5341.50Skamil 5351.50Skamil validate_status_stopped(status, sigval); 5361.50Skamil 5371.50Skamil DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 5381.61Skre SYSCALL_REQUIRE( 5391.61Skre ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 5401.50Skamil 5411.50Skamil DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 5421.50Skamil DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 5431.50Skamil info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 5441.50Skamil info.psi_siginfo.si_errno); 5451.50Skamil 5461.50Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 5471.50Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 5481.50Skamil 5491.50Skamil DPRINTF("Before resuming the child process where it left off and with " 5501.50Skamil "signal %s to be sent\n", strsignal(sigsent)); 5511.50Skamil SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigsent) != -1); 5521.50Skamil 5531.50Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 5541.50Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5551.50Skamil 5561.50Skamil validate_status_exited(status, exitval); 5571.50Skamil 5581.50Skamil DPRINTF("Before calling %s() for the exited child\n", TWAIT_FNAME); 5591.50Skamil TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 5601.50Skamil} 5611.50Skamil 5621.61Skre#define TRACEME_SENDSIGNAL_MASKED(test, sig) \ 5631.61SkreATF_TC(test); \ 5641.61SkreATF_TC_HEAD(test, tc) \ 5651.61Skre{ \ 5661.61Skre atf_tc_set_md_var(tc, "descr", \ 5671.61Skre "Verify that a signal " #sig " emitted by a tracer to a child is " \ 5681.61Skre "handled correctly and the signal is masked by SIG_BLOCK"); \ 5691.61Skre} \ 5701.61Skre \ 5711.61SkreATF_TC_BODY(test, tc) \ 5721.61Skre{ \ 5731.61Skre \ 5741.61Skre traceme_sendsignal_masked(sig); \ 5751.50Skamil} 5761.50Skamil 5771.50Skamil// A signal handler for SIGKILL and SIGSTOP cannot be masked. 5781.50SkamilTRACEME_SENDSIGNAL_MASKED(traceme_sendsignal_masked1, SIGABRT) /* abort trap */ 5791.50SkamilTRACEME_SENDSIGNAL_MASKED(traceme_sendsignal_masked2, SIGHUP) /* hangup */ 5801.50SkamilTRACEME_SENDSIGNAL_MASKED(traceme_sendsignal_masked3, SIGCONT) /* continued? */ 5811.85SkamilTRACEME_SENDSIGNAL_MASKED(traceme_sendsignal_masked4, SIGTRAP) /* crash sig. */ 5821.85SkamilTRACEME_SENDSIGNAL_MASKED(traceme_sendsignal_masked5, SIGBUS) /* crash sig. */ 5831.85SkamilTRACEME_SENDSIGNAL_MASKED(traceme_sendsignal_masked6, SIGILL) /* crash sig. */ 5841.85SkamilTRACEME_SENDSIGNAL_MASKED(traceme_sendsignal_masked7, SIGFPE) /* crash sig. */ 5851.85SkamilTRACEME_SENDSIGNAL_MASKED(traceme_sendsignal_masked8, SIGSEGV) /* crash sig. */ 5861.50Skamil 5871.50Skamil/// ---------------------------------------------------------------------------- 5881.50Skamil 5891.50Skamilstatic void 5901.50Skamiltraceme_sendsignal_ignored(int sigsent) 5911.50Skamil{ 5921.50Skamil const int exitval = 5; 5931.50Skamil const int sigval = SIGSTOP; 5941.50Skamil pid_t child, wpid; 5951.50Skamil struct sigaction sa; 5961.50Skamil#if defined(TWAIT_HAVE_STATUS) 5971.50Skamil int status; 5981.50Skamil#endif 5991.61Skre struct ptrace_siginfo info; 6001.50Skamil 6011.50Skamil memset(&info, 0, sizeof(info)); 6021.50Skamil 6031.50Skamil DPRINTF("Before forking process PID=%d\n", getpid()); 6041.50Skamil SYSCALL_REQUIRE((child = fork()) != -1); 6051.50Skamil if (child == 0) { 6061.50Skamil DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 6071.61Skre 6081.50Skamil FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 6091.50Skamil 6101.50Skamil memset(&sa, 0, sizeof(sa)); 6111.50Skamil sa.sa_handler = SIG_IGN; 6121.50Skamil sigemptyset(&sa.sa_mask); 6131.50Skamil FORKEE_ASSERT(sigaction(sigsent, &sa, NULL) != -1); 6141.50Skamil 6151.50Skamil DPRINTF("Before raising %s from child\n", strsignal(sigval)); 6161.50Skamil FORKEE_ASSERT(raise(sigval) == 0); 6171.50Skamil 6181.50Skamil _exit(exitval); 6191.50Skamil } 6201.50Skamil DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 6211.50Skamil 6221.50Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 6231.50Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 6241.50Skamil 6251.50Skamil validate_status_stopped(status, sigval); 6261.50Skamil 6271.50Skamil DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 6281.61Skre SYSCALL_REQUIRE( 6291.61Skre ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 6301.50Skamil 6311.50Skamil DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 6321.50Skamil DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 6331.50Skamil info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 6341.50Skamil info.psi_siginfo.si_errno); 6351.50Skamil 6361.50Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 6371.50Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 6381.50Skamil 6391.50Skamil DPRINTF("Before resuming the child process where it left off and with " 6401.50Skamil "signal %s to be sent\n", strsignal(sigsent)); 6411.50Skamil SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigsent) != -1); 6421.50Skamil 6431.50Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 6441.50Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 6451.50Skamil 6461.50Skamil validate_status_exited(status, exitval); 6471.50Skamil 6481.50Skamil DPRINTF("Before calling %s() for the exited child\n", TWAIT_FNAME); 6491.50Skamil TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 6501.50Skamil} 6511.50Skamil 6521.61Skre#define TRACEME_SENDSIGNAL_IGNORED(test, sig) \ 6531.61SkreATF_TC(test); \ 6541.61SkreATF_TC_HEAD(test, tc) \ 6551.61Skre{ \ 6561.61Skre atf_tc_set_md_var(tc, "descr", \ 6571.61Skre "Verify that a signal " #sig " emitted by a tracer to a child is " \ 6581.61Skre "handled correctly and the signal is masked by SIG_IGN"); \ 6591.61Skre} \ 6601.61Skre \ 6611.61SkreATF_TC_BODY(test, tc) \ 6621.61Skre{ \ 6631.61Skre \ 6641.61Skre traceme_sendsignal_ignored(sig); \ 6651.50Skamil} 6661.50Skamil 6671.50Skamil// A signal handler for SIGKILL and SIGSTOP cannot be ignored. 6681.61SkreTRACEME_SENDSIGNAL_IGNORED(traceme_sendsignal_ignored1, SIGABRT) /* abort */ 6691.50SkamilTRACEME_SENDSIGNAL_IGNORED(traceme_sendsignal_ignored2, SIGHUP) /* hangup */ 6701.61SkreTRACEME_SENDSIGNAL_IGNORED(traceme_sendsignal_ignored3, SIGCONT) /* continued */ 6711.85SkamilTRACEME_SENDSIGNAL_IGNORED(traceme_sendsignal_ignored4, SIGTRAP) /* crash s. */ 6721.85SkamilTRACEME_SENDSIGNAL_IGNORED(traceme_sendsignal_ignored5, SIGBUS) /* crash s. */ 6731.85SkamilTRACEME_SENDSIGNAL_IGNORED(traceme_sendsignal_ignored6, SIGILL) /* crash s. */ 6741.85SkamilTRACEME_SENDSIGNAL_IGNORED(traceme_sendsignal_ignored7, SIGFPE) /* crash s. */ 6751.85SkamilTRACEME_SENDSIGNAL_IGNORED(traceme_sendsignal_ignored8, SIGSEGV) /* crash s. */ 6761.50Skamil 6771.50Skamil/// ---------------------------------------------------------------------------- 6781.50Skamil 6791.50Skamilstatic void 6801.50Skamiltraceme_sendsignal_simple(int sigsent) 6811.1Skamil{ 6821.35Skamil const int sigval = SIGSTOP; 6831.35Skamil int exitval = 0; 6841.1Skamil pid_t child, wpid; 6851.1Skamil#if defined(TWAIT_HAVE_STATUS) 6861.1Skamil int status; 6871.85Skamil int expect_core; 6881.85Skamil 6891.85Skamil switch (sigsent) { 6901.85Skamil case SIGABRT: 6911.85Skamil case SIGTRAP: 6921.85Skamil case SIGBUS: 6931.85Skamil case SIGILL: 6941.85Skamil case SIGFPE: 6951.85Skamil case SIGSEGV: 6961.85Skamil expect_core = 1; 6971.85Skamil break; 6981.85Skamil default: 6991.85Skamil expect_core = 0; 7001.85Skamil break; 7011.85Skamil } 7021.1Skamil#endif 7031.61Skre struct ptrace_siginfo info; 7041.1Skamil 7051.45Skamil memset(&info, 0, sizeof(info)); 7061.45Skamil 7071.13Schristos DPRINTF("Before forking process PID=%d\n", getpid()); 7081.13Schristos SYSCALL_REQUIRE((child = fork()) != -1); 7091.1Skamil if (child == 0) { 7101.13Schristos DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 7111.1Skamil FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 7121.1Skamil 7131.13Schristos DPRINTF("Before raising %s from child\n", strsignal(sigval)); 7141.1Skamil FORKEE_ASSERT(raise(sigval) == 0); 7151.1Skamil 7161.35Skamil switch (sigsent) { 7171.35Skamil case SIGCONT: 7181.48Skamil case SIGSTOP: 7191.35Skamil _exit(exitval); 7201.35Skamil default: 7211.35Skamil /* NOTREACHED */ 7221.35Skamil FORKEE_ASSERTX(0 && "This shall not be reached"); 7231.35Skamil } 7241.1Skamil } 7251.13Schristos DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 7261.1Skamil 7271.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 7281.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 7291.1Skamil 7301.1Skamil validate_status_stopped(status, sigval); 7311.1Skamil 7321.45Skamil DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 7331.61Skre SYSCALL_REQUIRE( 7341.61Skre ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 7351.45Skamil 7361.45Skamil DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 7371.45Skamil DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 7381.45Skamil info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 7391.45Skamil info.psi_siginfo.si_errno); 7401.45Skamil 7411.45Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 7421.45Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 7431.45Skamil 7441.13Schristos DPRINTF("Before resuming the child process where it left off and with " 7451.1Skamil "signal %s to be sent\n", strsignal(sigsent)); 7461.13Schristos SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigsent) != -1); 7471.1Skamil 7481.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 7491.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 7501.1Skamil 7511.35Skamil switch (sigsent) { 7521.48Skamil case SIGSTOP: 7531.48Skamil validate_status_stopped(status, sigsent); 7541.48Skamil DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for " 7551.61Skre "child\n"); 7561.48Skamil SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, 7571.61Skre sizeof(info)) != -1); 7581.48Skamil 7591.48Skamil DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 7601.48Skamil DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 7611.61Skre "si_errno=%#x\n", 7621.61Skre info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 7631.61Skre info.psi_siginfo.si_errno); 7641.48Skamil 7651.48Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 7661.48Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 7671.48Skamil 7681.48Skamil DPRINTF("Before resuming the child process where it left off " 7691.61Skre "and with signal %s to be sent\n", strsignal(sigsent)); 7701.48Skamil SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 7711.48Skamil 7721.48Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 7731.48Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), 7741.61Skre child); 7751.48Skamil /* FALLTHROUGH */ 7761.35Skamil case SIGCONT: 7771.35Skamil validate_status_exited(status, exitval); 7781.35Skamil break; 7791.35Skamil default: 7801.35Skamil validate_status_signaled(status, sigsent, expect_core); 7811.35Skamil break; 7821.35Skamil } 7831.1Skamil 7841.13Schristos DPRINTF("Before calling %s() for the exited child\n", TWAIT_FNAME); 7851.1Skamil TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 7861.1Skamil} 7871.1Skamil 7881.61Skre#define TRACEME_SENDSIGNAL_SIMPLE(test, sig) \ 7891.61SkreATF_TC(test); \ 7901.61SkreATF_TC_HEAD(test, tc) \ 7911.61Skre{ \ 7921.61Skre atf_tc_set_md_var(tc, "descr", \ 7931.61Skre "Verify that a signal " #sig " emitted by a tracer to a child is " \ 7941.61Skre "handled correctly in a child without a signal handler"); \ 7951.61Skre} \ 7961.61Skre \ 7971.61SkreATF_TC_BODY(test, tc) \ 7981.61Skre{ \ 7991.61Skre \ 8001.61Skre traceme_sendsignal_simple(sig); \ 8011.35Skamil} 8021.35Skamil 8031.61SkreTRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple1, SIGKILL) /* non-maskable*/ 8041.61SkreTRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple2, SIGSTOP) /* non-maskable*/ 8051.50SkamilTRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple3, SIGABRT) /* abort trap */ 8061.50SkamilTRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple4, SIGHUP) /* hangup */ 8071.50SkamilTRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple5, SIGCONT) /* continued? */ 8081.85SkamilTRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple6, SIGTRAP) /* crash sig. */ 8091.85SkamilTRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple7, SIGBUS) /* crash sig. */ 8101.85SkamilTRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple8, SIGILL) /* crash sig. */ 8111.85SkamilTRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple9, SIGFPE) /* crash sig. */ 8121.85SkamilTRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple10, SIGSEGV) /* crash sig. */ 8131.35Skamil 8141.35Skamil/// ---------------------------------------------------------------------------- 8151.35Skamil 8161.37SkamilATF_TC(traceme_pid1_parent); 8171.37SkamilATF_TC_HEAD(traceme_pid1_parent, tc) 8181.37Skamil{ 8191.37Skamil atf_tc_set_md_var(tc, "descr", 8201.37Skamil "Verify that PT_TRACE_ME is not allowed when our parent is PID1"); 8211.37Skamil} 8221.37Skamil 8231.37SkamilATF_TC_BODY(traceme_pid1_parent, tc) 8241.37Skamil{ 8251.37Skamil struct msg_fds parent_child; 8261.37Skamil int exitval_child1 = 1, exitval_child2 = 2; 8271.37Skamil pid_t child1, child2, wpid; 8281.37Skamil uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */ 8291.37Skamil#if defined(TWAIT_HAVE_STATUS) 8301.37Skamil int status; 8311.37Skamil#endif 8321.37Skamil 8331.37Skamil SYSCALL_REQUIRE(msg_open(&parent_child) == 0); 8341.37Skamil 8351.37Skamil DPRINTF("Before forking process PID=%d\n", getpid()); 8361.37Skamil SYSCALL_REQUIRE((child1 = fork()) != -1); 8371.37Skamil if (child1 == 0) { 8381.37Skamil DPRINTF("Before forking process PID=%d\n", getpid()); 8391.37Skamil SYSCALL_REQUIRE((child2 = fork()) != -1); 8401.37Skamil if (child2 != 0) { 8411.37Skamil DPRINTF("Parent process PID=%d, child2's PID=%d\n", 8421.61Skre getpid(), child2); 8431.37Skamil _exit(exitval_child1); 8441.37Skamil } 8451.37Skamil CHILD_FROM_PARENT("exit child1", parent_child, msg); 8461.37Skamil 8471.37Skamil DPRINTF("Assert that our parent is PID1 (initproc)\n"); 8481.37Skamil FORKEE_ASSERT_EQ(getppid(), 1); 8491.37Skamil 8501.37Skamil DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 8511.37Skamil FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) == -1); 8521.37Skamil SYSCALL_REQUIRE_ERRNO(errno, EPERM); 8531.37Skamil 8541.37Skamil CHILD_TO_PARENT("child2 exiting", parent_child, msg); 8551.37Skamil 8561.37Skamil _exit(exitval_child2); 8571.37Skamil } 8581.37Skamil DPRINTF("Parent process PID=%d, child1's PID=%d\n", getpid(), child1); 8591.37Skamil 8601.37Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 8611.61Skre TWAIT_REQUIRE_SUCCESS( 8621.61Skre wpid = TWAIT_GENERIC(child1, &status, WEXITED), child1); 8631.37Skamil 8641.37Skamil validate_status_exited(status, exitval_child1); 8651.37Skamil 8661.37Skamil DPRINTF("Notify that child1 is dead\n"); 8671.37Skamil PARENT_TO_CHILD("exit child1", parent_child, msg); 8681.37Skamil 8691.37Skamil DPRINTF("Wait for exiting of child2\n"); 8701.37Skamil PARENT_FROM_CHILD("child2 exiting", parent_child, msg); 8711.37Skamil} 8721.37Skamil 8731.37Skamil/// ---------------------------------------------------------------------------- 8741.37Skamil 8751.40Skamilstatic void 8761.40Skamiltraceme_vfork_raise(int sigval) 8771.40Skamil{ 8781.46Skamil const int exitval = 5, exitval_watcher = 10; 8791.46Skamil pid_t child, parent, watcher, wpid; 8801.46Skamil int rv; 8811.40Skamil#if defined(TWAIT_HAVE_STATUS) 8821.40Skamil int status; 8831.85Skamil 8841.85Skamil /* volatile workarounds GCC -Werror=clobbered */ 8851.85Skamil volatile int expect_core; 8861.85Skamil 8871.85Skamil switch (sigval) { 8881.85Skamil case SIGABRT: 8891.85Skamil case SIGTRAP: 8901.85Skamil case SIGBUS: 8911.85Skamil case SIGILL: 8921.85Skamil case SIGFPE: 8931.85Skamil case SIGSEGV: 8941.85Skamil expect_core = 1; 8951.85Skamil break; 8961.85Skamil default: 8971.85Skamil expect_core = 0; 8981.85Skamil break; 8991.85Skamil } 9001.40Skamil#endif 9011.40Skamil 9021.46Skamil /* 9031.46Skamil * Spawn a dedicated thread to watch for a stopped child and emit 9041.46Skamil * the SIGKILL signal to it. 9051.46Skamil * 9061.46Skamil * vfork(2) might clobber watcher, this means that it's safer and 9071.46Skamil * simpler to reparent this process to initproc and forget about it. 9081.46Skamil */ 9091.46Skamil if (sigval == SIGSTOP) { 9101.46Skamil parent = getpid(); 9111.46Skamil 9121.46Skamil watcher = fork(); 9131.46Skamil ATF_REQUIRE(watcher != 1); 9141.46Skamil if (watcher == 0) { 9151.46Skamil /* Double fork(2) trick to reparent to initproc */ 9161.46Skamil watcher = fork(); 9171.46Skamil FORKEE_ASSERT_NEQ(watcher, -1); 9181.46Skamil if (watcher != 0) 9191.46Skamil _exit(exitval_watcher); 9201.46Skamil 9211.46Skamil child = await_stopped_child(parent); 9221.46Skamil 9231.46Skamil errno = 0; 9241.46Skamil rv = kill(child, SIGKILL); 9251.46Skamil FORKEE_ASSERT_EQ(rv, 0); 9261.46Skamil FORKEE_ASSERT_EQ(errno, 0); 9271.46Skamil 9281.46Skamil /* This exit value will be collected by initproc */ 9291.46Skamil _exit(0); 9301.46Skamil } 9311.46Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 9321.46Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(watcher, &status, 0), 9331.61Skre watcher); 9341.46Skamil 9351.46Skamil validate_status_exited(status, exitval_watcher); 9361.46Skamil 9371.46Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 9381.61Skre TWAIT_REQUIRE_FAILURE(ECHILD, 9391.61Skre wpid = TWAIT_GENERIC(watcher, &status, 0)); 9401.46Skamil } 9411.46Skamil 9421.40Skamil DPRINTF("Before forking process PID=%d\n", getpid()); 9431.40Skamil SYSCALL_REQUIRE((child = vfork()) != -1); 9441.40Skamil if (child == 0) { 9451.40Skamil DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 9461.40Skamil FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 9471.40Skamil 9481.40Skamil DPRINTF("Before raising %s from child\n", strsignal(sigval)); 9491.40Skamil FORKEE_ASSERT(raise(sigval) == 0); 9501.40Skamil 9511.40Skamil switch (sigval) { 9521.46Skamil case SIGSTOP: 9531.40Skamil case SIGKILL: 9541.40Skamil case SIGABRT: 9551.40Skamil case SIGHUP: 9561.85Skamil case SIGTRAP: 9571.85Skamil case SIGBUS: 9581.85Skamil case SIGILL: 9591.85Skamil case SIGFPE: 9601.85Skamil case SIGSEGV: 9611.40Skamil /* NOTREACHED */ 9621.40Skamil FORKEE_ASSERTX(0 && "This shall not be reached"); 9631.70Smrg __unreachable(); 9641.40Skamil default: 9651.40Skamil DPRINTF("Before exiting of the child process\n"); 9661.40Skamil _exit(exitval); 9671.40Skamil } 9681.40Skamil } 9691.40Skamil DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 9701.40Skamil 9711.40Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 9721.40Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 9731.40Skamil 9741.40Skamil switch (sigval) { 9751.40Skamil case SIGKILL: 9761.40Skamil case SIGABRT: 9771.40Skamil case SIGHUP: 9781.85Skamil case SIGTRAP: 9791.85Skamil case SIGBUS: 9801.85Skamil case SIGILL: 9811.85Skamil case SIGFPE: 9821.85Skamil case SIGSEGV: 9831.40Skamil validate_status_signaled(status, sigval, expect_core); 9841.40Skamil break; 9851.40Skamil case SIGSTOP: 9861.46Skamil validate_status_signaled(status, SIGKILL, 0); 9871.46Skamil break; 9881.40Skamil case SIGCONT: 9891.47Skamil case SIGTSTP: 9901.47Skamil case SIGTTIN: 9911.47Skamil case SIGTTOU: 9921.40Skamil validate_status_exited(status, exitval); 9931.40Skamil break; 9941.40Skamil default: 9951.40Skamil /* NOTREACHED */ 9961.40Skamil ATF_REQUIRE(0 && "NOT IMPLEMENTED"); 9971.40Skamil break; 9981.40Skamil } 9991.40Skamil 10001.40Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 10011.40Skamil TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 10021.40Skamil} 10031.40Skamil 10041.61Skre#define TRACEME_VFORK_RAISE(test, sig) \ 10051.61SkreATF_TC(test); \ 10061.61SkreATF_TC_HEAD(test, tc) \ 10071.61Skre{ \ 10081.61Skre atf_tc_set_md_var(tc, "descr", \ 10091.61Skre "Verify PT_TRACE_ME followed by raise of " #sig " in a " \ 10101.61Skre "vfork(2)ed child"); \ 10111.61Skre} \ 10121.61Skre \ 10131.61SkreATF_TC_BODY(test, tc) \ 10141.61Skre{ \ 10151.61Skre \ 10161.61Skre traceme_vfork_raise(sig); \ 10171.40Skamil} 10181.40Skamil 10191.40SkamilTRACEME_VFORK_RAISE(traceme_vfork_raise1, SIGKILL) /* non-maskable */ 10201.46SkamilTRACEME_VFORK_RAISE(traceme_vfork_raise2, SIGSTOP) /* non-maskable */ 10211.47SkamilTRACEME_VFORK_RAISE(traceme_vfork_raise3, SIGTSTP) /* ignored in vfork(2) */ 10221.47SkamilTRACEME_VFORK_RAISE(traceme_vfork_raise4, SIGTTIN) /* ignored in vfork(2) */ 10231.47SkamilTRACEME_VFORK_RAISE(traceme_vfork_raise5, SIGTTOU) /* ignored in vfork(2) */ 10241.47SkamilTRACEME_VFORK_RAISE(traceme_vfork_raise6, SIGABRT) /* regular abort trap */ 10251.47SkamilTRACEME_VFORK_RAISE(traceme_vfork_raise7, SIGHUP) /* hangup */ 10261.47SkamilTRACEME_VFORK_RAISE(traceme_vfork_raise8, SIGCONT) /* continued? */ 10271.85SkamilTRACEME_VFORK_RAISE(traceme_vfork_raise9, SIGTRAP) /* crash signal */ 10281.85SkamilTRACEME_VFORK_RAISE(traceme_vfork_raise10, SIGBUS) /* crash signal */ 10291.85SkamilTRACEME_VFORK_RAISE(traceme_vfork_raise11, SIGILL) /* crash signal */ 10301.85SkamilTRACEME_VFORK_RAISE(traceme_vfork_raise12, SIGFPE) /* crash signal */ 10311.85SkamilTRACEME_VFORK_RAISE(traceme_vfork_raise13, SIGSEGV) /* crash signal */ 10321.40Skamil 10331.40Skamil/// ---------------------------------------------------------------------------- 10341.40Skamil 10351.52Skamilstatic void 10361.52Skamiltraceme_vfork_crash(int sig) 10371.41Skamil{ 10381.41Skamil pid_t child, wpid; 10391.41Skamil#if defined(TWAIT_HAVE_STATUS) 10401.41Skamil int status; 10411.41Skamil#endif 10421.41Skamil 10431.71Skamil#ifndef PTRACE_ILLEGAL_ASM 10441.71Skamil if (sig == SIGILL) 10451.71Skamil atf_tc_skip("PTRACE_ILLEGAL_ASM not defined"); 10461.71Skamil#endif 10471.71Skamil 10481.41Skamil DPRINTF("Before forking process PID=%d\n", getpid()); 10491.41Skamil SYSCALL_REQUIRE((child = vfork()) != -1); 10501.41Skamil if (child == 0) { 10511.41Skamil DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 10521.41Skamil FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 10531.41Skamil 10541.52Skamil DPRINTF("Before executing a trap\n"); 10551.52Skamil switch (sig) { 10561.52Skamil case SIGTRAP: 10571.52Skamil trigger_trap(); 10581.52Skamil break; 10591.52Skamil case SIGSEGV: 10601.52Skamil trigger_segv(); 10611.52Skamil break; 10621.52Skamil case SIGILL: 10631.52Skamil trigger_ill(); 10641.52Skamil break; 10651.52Skamil case SIGFPE: 10661.52Skamil trigger_fpe(); 10671.52Skamil break; 10681.52Skamil case SIGBUS: 10691.52Skamil trigger_bus(); 10701.52Skamil break; 10711.52Skamil default: 10721.52Skamil /* NOTREACHED */ 10731.52Skamil FORKEE_ASSERTX(0 && "This shall not be reached"); 10741.52Skamil } 10751.41Skamil 10761.41Skamil /* NOTREACHED */ 10771.41Skamil FORKEE_ASSERTX(0 && "This shall not be reached"); 10781.41Skamil } 10791.41Skamil DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 10801.41Skamil 10811.41Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 10821.41Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 10831.41Skamil 10841.52Skamil validate_status_signaled(status, sig, 1); 10851.41Skamil 10861.41Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 10871.41Skamil TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 10881.41Skamil} 10891.41Skamil 10901.61Skre#define TRACEME_VFORK_CRASH(test, sig) \ 10911.61SkreATF_TC(test); \ 10921.61SkreATF_TC_HEAD(test, tc) \ 10931.61Skre{ \ 10941.61Skre atf_tc_set_md_var(tc, "descr", \ 10951.61Skre "Verify PT_TRACE_ME followed by a crash signal " #sig " in a " \ 10961.61Skre "vfork(2)ed child"); \ 10971.61Skre} \ 10981.61Skre \ 10991.61SkreATF_TC_BODY(test, tc) \ 11001.61Skre{ \ 11011.61Skre \ 11021.61Skre traceme_vfork_crash(sig); \ 11031.52Skamil} 11041.52Skamil 11051.52SkamilTRACEME_VFORK_CRASH(traceme_vfork_crash_trap, SIGTRAP) 11061.52SkamilTRACEME_VFORK_CRASH(traceme_vfork_crash_segv, SIGSEGV) 11071.71SkamilTRACEME_VFORK_CRASH(traceme_vfork_crash_ill, SIGILL) 11081.52SkamilTRACEME_VFORK_CRASH(traceme_vfork_crash_fpe, SIGFPE) 11091.52SkamilTRACEME_VFORK_CRASH(traceme_vfork_crash_bus, SIGBUS) 11101.52Skamil 11111.41Skamil/// ---------------------------------------------------------------------------- 11121.41Skamil 11131.43SkamilATF_TC(traceme_vfork_exec); 11141.43SkamilATF_TC_HEAD(traceme_vfork_exec, tc) 11151.43Skamil{ 11161.43Skamil atf_tc_set_md_var(tc, "descr", 11171.43Skamil "Verify PT_TRACE_ME followed by exec(3) in a vfork(2)ed child"); 11181.43Skamil} 11191.43Skamil 11201.43SkamilATF_TC_BODY(traceme_vfork_exec, tc) 11211.43Skamil{ 11221.43Skamil const int sigval = SIGTRAP; 11231.43Skamil pid_t child, wpid; 11241.43Skamil#if defined(TWAIT_HAVE_STATUS) 11251.43Skamil int status; 11261.43Skamil#endif 11271.61Skre struct ptrace_siginfo info; 11281.43Skamil 11291.43Skamil memset(&info, 0, sizeof(info)); 11301.43Skamil 11311.43Skamil DPRINTF("Before forking process PID=%d\n", getpid()); 11321.43Skamil SYSCALL_REQUIRE((child = vfork()) != -1); 11331.43Skamil if (child == 0) { 11341.43Skamil DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 11351.43Skamil FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 11361.43Skamil 11371.43Skamil DPRINTF("Before calling execve(2) from child\n"); 11381.43Skamil execlp("/bin/echo", "/bin/echo", NULL); 11391.43Skamil 11401.43Skamil /* NOTREACHED */ 11411.43Skamil FORKEE_ASSERTX(0 && "Not reached"); 11421.43Skamil } 11431.43Skamil DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 11441.43Skamil 11451.43Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 11461.43Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 11471.43Skamil 11481.43Skamil validate_status_stopped(status, sigval); 11491.43Skamil 11501.43Skamil DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 11511.61Skre SYSCALL_REQUIRE( 11521.61Skre ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 11531.43Skamil 11541.43Skamil DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 11551.43Skamil DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 11561.43Skamil info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 11571.43Skamil info.psi_siginfo.si_errno); 11581.43Skamil 11591.43Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 11601.43Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_EXEC); 11611.43Skamil 11621.43Skamil DPRINTF("Before resuming the child process where it left off and " 11631.43Skamil "without signal to be sent\n"); 11641.43Skamil SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 11651.43Skamil 11661.43Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 11671.43Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 11681.43Skamil 11691.43Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 11701.43Skamil TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 11711.43Skamil} 11721.43Skamil 11731.43Skamil/// ---------------------------------------------------------------------------- 11741.43Skamil 11751.1Skamil#if defined(TWAIT_HAVE_PID) 11761.51Skamilstatic void 11771.59Skamilunrelated_tracer_sees_crash(int sig) 11781.59Skamil{ 11791.59Skamil struct msg_fds parent_tracee, parent_tracer; 11801.59Skamil const int exitval = 10; 11811.59Skamil pid_t tracee, tracer, wpid; 11821.59Skamil uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */ 11831.59Skamil#if defined(TWAIT_HAVE_STATUS) 11841.59Skamil int status; 11851.59Skamil#endif 11861.59Skamil struct ptrace_siginfo info; 11871.61Skre 11881.71Skamil#ifndef PTRACE_ILLEGAL_ASM 11891.71Skamil if (sig == SIGILL) 11901.71Skamil atf_tc_skip("PTRACE_ILLEGAL_ASM not defined"); 11911.71Skamil#endif 11921.71Skamil 11931.59Skamil memset(&info, 0, sizeof(info)); 11941.59Skamil 11951.59Skamil DPRINTF("Spawn tracee\n"); 11961.59Skamil SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0); 11971.59Skamil tracee = atf_utils_fork(); 11981.59Skamil if (tracee == 0) { 11991.59Skamil // Wait for parent to let us crash 12001.59Skamil CHILD_FROM_PARENT("exit tracee", parent_tracee, msg); 12011.61Skre 12021.59Skamil DPRINTF("Before executing a trap\n"); 12031.59Skamil switch (sig) { 12041.59Skamil case SIGTRAP: 12051.59Skamil trigger_trap(); 12061.59Skamil break; 12071.59Skamil case SIGSEGV: 12081.59Skamil trigger_segv(); 12091.59Skamil break; 12101.59Skamil case SIGILL: 12111.59Skamil trigger_ill(); 12121.59Skamil break; 12131.59Skamil case SIGFPE: 12141.59Skamil trigger_fpe(); 12151.59Skamil break; 12161.59Skamil case SIGBUS: 12171.59Skamil trigger_bus(); 12181.59Skamil break; 12191.59Skamil default: 12201.59Skamil /* NOTREACHED */ 12211.59Skamil FORKEE_ASSERTX(0 && "This shall not be reached"); 12221.59Skamil } 12231.59Skamil 12241.59Skamil /* NOTREACHED */ 12251.59Skamil FORKEE_ASSERTX(0 && "This shall not be reached"); 12261.59Skamil } 12271.59Skamil 12281.59Skamil DPRINTF("Spawn debugger\n"); 12291.59Skamil SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0); 12301.59Skamil tracer = atf_utils_fork(); 12311.59Skamil if (tracer == 0) { 12321.59Skamil /* Fork again and drop parent to reattach to PID 1 */ 12331.59Skamil tracer = atf_utils_fork(); 12341.59Skamil if (tracer != 0) 12351.61Skre _exit(exitval); 12361.59Skamil 12371.59Skamil DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid()); 12381.59Skamil FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1); 12391.59Skamil 12401.59Skamil /* Wait for tracee and assert that it was stopped w/ SIGSTOP */ 12411.59Skamil FORKEE_REQUIRE_SUCCESS( 12421.59Skamil wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 12431.59Skamil 12441.59Skamil forkee_status_stopped(status, SIGSTOP); 12451.59Skamil 12461.59Skamil /* Resume tracee with PT_CONTINUE */ 12471.59Skamil FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1); 12481.59Skamil 12491.59Skamil /* Inform parent that tracer has attached to tracee */ 12501.59Skamil CHILD_TO_PARENT("tracer ready", parent_tracer, msg); 12511.59Skamil 12521.59Skamil /* Wait for parent to tell use that tracee should have exited */ 12531.59Skamil CHILD_FROM_PARENT("wait for tracee exit", parent_tracer, msg); 12541.59Skamil 12551.59Skamil /* Wait for tracee and assert that it exited */ 12561.59Skamil FORKEE_REQUIRE_SUCCESS( 12571.59Skamil wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 12581.59Skamil 12591.59Skamil validate_status_stopped(status, sig); 12601.59Skamil 12611.59Skamil DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for the " 12621.61Skre "traced process\n"); 12631.61Skre SYSCALL_REQUIRE( 12641.61Skre ptrace(PT_GET_SIGINFO, tracee, &info, sizeof(info)) != -1); 12651.59Skamil 12661.59Skamil DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 12671.59Skamil DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 12681.61Skre "si_errno=%#x\n", info.psi_siginfo.si_signo, 12691.61Skre info.psi_siginfo.si_code, info.psi_siginfo.si_errno); 12701.59Skamil 12711.59Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sig); 12721.59Skamil switch (sig) { 12731.59Skamil case SIGTRAP: 12741.59Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_BRKPT); 12751.59Skamil break; 12761.59Skamil case SIGSEGV: 12771.59Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SEGV_MAPERR); 12781.59Skamil break; 12791.71Skamil case SIGILL: 12801.71Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_code, ILL_PRVOPC); 12811.71Skamil break; 12821.59Skamil case SIGFPE: 12831.59Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_code, FPE_INTDIV); 12841.59Skamil break; 12851.59Skamil case SIGBUS: 12861.59Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_code, BUS_ADRERR); 12871.59Skamil break; 12881.59Skamil } 12891.59Skamil 12901.59Skamil FORKEE_ASSERT(ptrace(PT_KILL, tracee, NULL, 0) != -1); 12911.59Skamil DPRINTF("Before calling %s() for the tracee\n", TWAIT_FNAME); 12921.61Skre TWAIT_REQUIRE_SUCCESS( 12931.61Skre wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 12941.59Skamil 12951.59Skamil validate_status_signaled(status, SIGKILL, 0); 12961.59Skamil 12971.59Skamil DPRINTF("Before calling %s() for tracee\n", TWAIT_FNAME); 12981.59Skamil TWAIT_REQUIRE_FAILURE(ECHILD, 12991.59Skamil wpid = TWAIT_GENERIC(tracee, &status, 0)); 13001.59Skamil 13011.71Skamil /* Inform parent that tracer is exiting normally */ 13021.71Skamil CHILD_TO_PARENT("tracer done", parent_tracer, msg); 13031.71Skamil 13041.59Skamil DPRINTF("Before exiting of the tracer process\n"); 13051.59Skamil _exit(0 /* collect by initproc */); 13061.59Skamil } 13071.59Skamil 13081.59Skamil DPRINTF("Wait for the tracer process (direct child) to exit " 13091.59Skamil "calling %s()\n", TWAIT_FNAME); 13101.59Skamil TWAIT_REQUIRE_SUCCESS( 13111.59Skamil wpid = TWAIT_GENERIC(tracer, &status, 0), tracer); 13121.59Skamil 13131.59Skamil validate_status_exited(status, exitval); 13141.59Skamil 13151.59Skamil DPRINTF("Wait for the non-exited tracee process with %s()\n", 13161.59Skamil TWAIT_FNAME); 13171.59Skamil TWAIT_REQUIRE_SUCCESS( 13181.59Skamil wpid = TWAIT_GENERIC(tracee, NULL, WNOHANG), 0); 13191.59Skamil 13201.59Skamil DPRINTF("Wait for the tracer to attach to the tracee\n"); 13211.59Skamil PARENT_FROM_CHILD("tracer ready", parent_tracer, msg); 13221.59Skamil 13231.59Skamil DPRINTF("Resume the tracee and let it crash\n"); 13241.59Skamil PARENT_TO_CHILD("exit tracee", parent_tracee, msg); 13251.59Skamil 13261.59Skamil DPRINTF("Resume the tracer and let it detect crashed tracee\n"); 13271.59Skamil PARENT_TO_CHILD("Message 2", parent_tracer, msg); 13281.59Skamil 13291.59Skamil DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n", 13301.59Skamil TWAIT_FNAME); 13311.59Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 13321.59Skamil 13331.59Skamil validate_status_signaled(status, SIGKILL, 0); 13341.59Skamil 13351.71Skamil DPRINTF("Await normal exit of tracer\n"); 13361.71Skamil PARENT_FROM_CHILD("tracer done", parent_tracer, msg); 13371.71Skamil 13381.59Skamil msg_close(&parent_tracer); 13391.59Skamil msg_close(&parent_tracee); 13401.59Skamil} 13411.59Skamil 13421.61Skre#define UNRELATED_TRACER_SEES_CRASH(test, sig) \ 13431.61SkreATF_TC(test); \ 13441.61SkreATF_TC_HEAD(test, tc) \ 13451.61Skre{ \ 13461.61Skre atf_tc_set_md_var(tc, "descr", \ 13471.61Skre "Assert that an unrelated tracer sees crash signal from the " \ 13481.61Skre "debuggee"); \ 13491.61Skre} \ 13501.61Skre \ 13511.61SkreATF_TC_BODY(test, tc) \ 13521.61Skre{ \ 13531.61Skre \ 13541.61Skre unrelated_tracer_sees_crash(sig); \ 13551.59Skamil} 13561.59Skamil 13571.59SkamilUNRELATED_TRACER_SEES_CRASH(unrelated_tracer_sees_crash_trap, SIGTRAP) 13581.59SkamilUNRELATED_TRACER_SEES_CRASH(unrelated_tracer_sees_crash_segv, SIGSEGV) 13591.71SkamilUNRELATED_TRACER_SEES_CRASH(unrelated_tracer_sees_crash_ill, SIGILL) 13601.59SkamilUNRELATED_TRACER_SEES_CRASH(unrelated_tracer_sees_crash_fpe, SIGFPE) 13611.59SkamilUNRELATED_TRACER_SEES_CRASH(unrelated_tracer_sees_crash_bus, SIGBUS) 13621.59Skamil#endif 13631.59Skamil 13641.59Skamil/// ---------------------------------------------------------------------------- 13651.59Skamil 13661.59Skamil#if defined(TWAIT_HAVE_PID) 13671.59Skamilstatic void 13681.67Skamiltracer_sees_terminaton_before_the_parent_raw(bool notimeout, bool unrelated, 13691.67Skamil bool stopped) 13701.1Skamil{ 13711.51Skamil /* 13721.51Skamil * notimeout - disable timeout in await zombie function 13731.51Skamil * unrelated - attach from unrelated tracer reparented to initproc 13741.67Skamil * stopped - attach to a stopped process 13751.51Skamil */ 13761.1Skamil 13771.1Skamil struct msg_fds parent_tracee, parent_tracer; 13781.1Skamil const int exitval_tracee = 5; 13791.1Skamil const int exitval_tracer = 10; 13801.1Skamil pid_t tracee, tracer, wpid; 13811.1Skamil uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */ 13821.1Skamil#if defined(TWAIT_HAVE_STATUS) 13831.1Skamil int status; 13841.1Skamil#endif 13851.1Skamil 13861.67Skamil /* 13871.67Skamil * Only a subset of options are supported. 13881.67Skamil */ 13891.67Skamil ATF_REQUIRE((!notimeout && !unrelated && !stopped) || 13901.67Skamil (!notimeout && unrelated && !stopped) || 13911.67Skamil (notimeout && !unrelated && !stopped) || 13921.67Skamil (!notimeout && unrelated && stopped)); 13931.67Skamil 13941.13Schristos DPRINTF("Spawn tracee\n"); 13951.13Schristos SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0); 13961.1Skamil tracee = atf_utils_fork(); 13971.1Skamil if (tracee == 0) { 13981.67Skamil if (stopped) { 13991.67Skamil DPRINTF("Stop self PID %d\n", getpid()); 14001.67Skamil raise(SIGSTOP); 14011.67Skamil } 14021.67Skamil 14031.1Skamil // Wait for parent to let us exit 14041.1Skamil CHILD_FROM_PARENT("exit tracee", parent_tracee, msg); 14051.1Skamil _exit(exitval_tracee); 14061.1Skamil } 14071.1Skamil 14081.13Schristos DPRINTF("Spawn debugger\n"); 14091.13Schristos SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0); 14101.1Skamil tracer = atf_utils_fork(); 14111.1Skamil if (tracer == 0) { 14121.51Skamil if(unrelated) { 14131.51Skamil /* Fork again and drop parent to reattach to PID 1 */ 14141.51Skamil tracer = atf_utils_fork(); 14151.51Skamil if (tracer != 0) 14161.51Skamil _exit(exitval_tracer); 14171.51Skamil } 14181.51Skamil 14191.67Skamil if (stopped) { 14201.67Skamil DPRINTF("Await for a stopped parent PID %d\n", tracee); 14211.67Skamil await_stopped(tracee); 14221.67Skamil } 14231.67Skamil 14241.13Schristos DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid()); 14251.1Skamil FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1); 14261.1Skamil 14271.1Skamil /* Wait for tracee and assert that it was stopped w/ SIGSTOP */ 14281.1Skamil FORKEE_REQUIRE_SUCCESS( 14291.1Skamil wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 14301.1Skamil 14311.1Skamil forkee_status_stopped(status, SIGSTOP); 14321.1Skamil 14331.1Skamil /* Resume tracee with PT_CONTINUE */ 14341.1Skamil FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1); 14351.1Skamil 14361.1Skamil /* Inform parent that tracer has attached to tracee */ 14371.1Skamil CHILD_TO_PARENT("tracer ready", parent_tracer, msg); 14381.1Skamil 14391.1Skamil /* Wait for parent to tell use that tracee should have exited */ 14401.1Skamil CHILD_FROM_PARENT("wait for tracee exit", parent_tracer, msg); 14411.1Skamil 14421.1Skamil /* Wait for tracee and assert that it exited */ 14431.1Skamil FORKEE_REQUIRE_SUCCESS( 14441.1Skamil wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 14451.1Skamil 14461.1Skamil forkee_status_exited(status, exitval_tracee); 14471.13Schristos DPRINTF("Tracee %d exited with %d\n", tracee, exitval_tracee); 14481.1Skamil 14491.13Schristos DPRINTF("Before exiting of the tracer process\n"); 14501.51Skamil _exit(unrelated ? 0 /* collect by initproc */ : exitval_tracer); 14511.51Skamil } 14521.51Skamil 14531.51Skamil if (unrelated) { 14541.51Skamil DPRINTF("Wait for the tracer process (direct child) to exit " 14551.51Skamil "calling %s()\n", TWAIT_FNAME); 14561.51Skamil TWAIT_REQUIRE_SUCCESS( 14571.51Skamil wpid = TWAIT_GENERIC(tracer, &status, 0), tracer); 14581.51Skamil 14591.51Skamil validate_status_exited(status, exitval_tracer); 14601.51Skamil 14611.51Skamil DPRINTF("Wait for the non-exited tracee process with %s()\n", 14621.51Skamil TWAIT_FNAME); 14631.51Skamil TWAIT_REQUIRE_SUCCESS( 14641.51Skamil wpid = TWAIT_GENERIC(tracee, NULL, WNOHANG), 0); 14651.1Skamil } 14661.1Skamil 14671.13Schristos DPRINTF("Wait for the tracer to attach to the tracee\n"); 14681.1Skamil PARENT_FROM_CHILD("tracer ready", parent_tracer, msg); 14691.1Skamil 14701.13Schristos DPRINTF("Resume the tracee and let it exit\n"); 14711.1Skamil PARENT_TO_CHILD("exit tracee", parent_tracee, msg); 14721.1Skamil 14731.13Schristos DPRINTF("Detect that tracee is zombie\n"); 14741.51Skamil if (notimeout) 14751.26Skamil await_zombie_raw(tracee, 0); 14761.26Skamil else 14771.26Skamil await_zombie(tracee); 14781.1Skamil 14791.13Schristos DPRINTF("Assert that there is no status about tracee %d - " 14801.1Skamil "Tracer must detect zombie first - calling %s()\n", tracee, 14811.1Skamil TWAIT_FNAME); 14821.1Skamil TWAIT_REQUIRE_SUCCESS( 14831.1Skamil wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0); 14841.1Skamil 14851.51Skamil if (unrelated) { 14861.51Skamil DPRINTF("Resume the tracer and let it detect exited tracee\n"); 14871.51Skamil PARENT_TO_CHILD("Message 2", parent_tracer, msg); 14881.51Skamil } else { 14891.51Skamil DPRINTF("Tell the tracer child should have exited\n"); 14901.51Skamil PARENT_TO_CHILD("wait for tracee exit", parent_tracer, msg); 14911.51Skamil DPRINTF("Wait for tracer to finish its job and exit - calling " 14921.59Skamil "%s()\n", TWAIT_FNAME); 14931.51Skamil 14941.51Skamil DPRINTF("Wait from tracer child to complete waiting for " 14951.59Skamil "tracee\n"); 14961.51Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0), 14971.51Skamil tracer); 14981.1Skamil 14991.51Skamil validate_status_exited(status, exitval_tracer); 15001.51Skamil } 15011.1Skamil 15021.13Schristos DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n", 15031.1Skamil TWAIT_FNAME); 15041.51Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 15051.1Skamil 15061.1Skamil validate_status_exited(status, exitval_tracee); 15071.1Skamil 15081.1Skamil msg_close(&parent_tracer); 15091.1Skamil msg_close(&parent_tracee); 15101.1Skamil} 15111.26Skamil 15121.51SkamilATF_TC(tracer_sees_terminaton_before_the_parent); 15131.51SkamilATF_TC_HEAD(tracer_sees_terminaton_before_the_parent, tc) 15141.51Skamil{ 15151.51Skamil atf_tc_set_md_var(tc, "descr", 15161.51Skamil "Assert that tracer sees process termination before the parent"); 15171.51Skamil} 15181.51Skamil 15191.51SkamilATF_TC_BODY(tracer_sees_terminaton_before_the_parent, tc) 15201.26Skamil{ 15211.26Skamil 15221.67Skamil tracer_sees_terminaton_before_the_parent_raw(false, false, false); 15231.26Skamil} 15241.26Skamil 15251.51SkamilATF_TC(tracer_sysctl_lookup_without_duplicates); 15261.51SkamilATF_TC_HEAD(tracer_sysctl_lookup_without_duplicates, tc) 15271.1Skamil{ 15281.1Skamil atf_tc_set_md_var(tc, "descr", 15291.51Skamil "Assert that await_zombie() in attach1 always finds a single " 15301.51Skamil "process and no other error is reported"); 15311.1Skamil} 15321.1Skamil 15331.51SkamilATF_TC_BODY(tracer_sysctl_lookup_without_duplicates, tc) 15341.1Skamil{ 15351.51Skamil time_t start, end; 15361.51Skamil double diff; 15371.51Skamil unsigned long N = 0; 15381.1Skamil 15391.51Skamil /* 15401.51Skamil * Reuse this test with tracer_sees_terminaton_before_the_parent_raw(). 15411.51Skamil * This test body isn't specific to this race, however it's just good 15421.51Skamil * enough for this purposes, no need to invent a dedicated code flow. 15431.51Skamil */ 15441.1Skamil 15451.51Skamil start = time(NULL); 15461.51Skamil while (true) { 15471.51Skamil DPRINTF("Step: %lu\n", N); 15481.67Skamil tracer_sees_terminaton_before_the_parent_raw(true, false, 15491.67Skamil false); 15501.51Skamil end = time(NULL); 15511.51Skamil diff = difftime(end, start); 15521.51Skamil if (diff >= 5.0) 15531.51Skamil break; 15541.51Skamil ++N; 15551.1Skamil } 15561.51Skamil DPRINTF("Iterations: %lu\n", N); 15571.51Skamil} 15581.1Skamil 15591.51SkamilATF_TC(unrelated_tracer_sees_terminaton_before_the_parent); 15601.51SkamilATF_TC_HEAD(unrelated_tracer_sees_terminaton_before_the_parent, tc) 15611.51Skamil{ 15621.51Skamil atf_tc_set_md_var(tc, "descr", 15631.51Skamil "Assert that tracer sees process termination before the parent"); 15641.51Skamil} 15651.1Skamil 15661.51SkamilATF_TC_BODY(unrelated_tracer_sees_terminaton_before_the_parent, tc) 15671.51Skamil{ 15681.1Skamil 15691.67Skamil tracer_sees_terminaton_before_the_parent_raw(false, true, false); 15701.67Skamil} 15711.67Skamil 15721.67SkamilATF_TC(tracer_attach_to_unrelated_stopped_process); 15731.67SkamilATF_TC_HEAD(tracer_attach_to_unrelated_stopped_process, tc) 15741.67Skamil{ 15751.67Skamil atf_tc_set_md_var(tc, "descr", 15761.67Skamil "Assert that tracer can attach to an unrelated stopped process"); 15771.67Skamil} 15781.67Skamil 15791.67SkamilATF_TC_BODY(tracer_attach_to_unrelated_stopped_process, tc) 15801.67Skamil{ 15811.67Skamil 15821.67Skamil tracer_sees_terminaton_before_the_parent_raw(false, true, true); 15831.1Skamil} 15841.1Skamil#endif 15851.1Skamil 15861.51Skamil/// ---------------------------------------------------------------------------- 15871.51Skamil 15881.66Skamilstatic void 15891.66Skamilparent_attach_to_its_child(bool stopped) 15901.1Skamil{ 15911.1Skamil struct msg_fds parent_tracee; 15921.1Skamil const int exitval_tracee = 5; 15931.1Skamil pid_t tracee, wpid; 15941.1Skamil uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */ 15951.1Skamil#if defined(TWAIT_HAVE_STATUS) 15961.1Skamil int status; 15971.1Skamil#endif 15981.1Skamil 15991.13Schristos DPRINTF("Spawn tracee\n"); 16001.13Schristos SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0); 16011.1Skamil tracee = atf_utils_fork(); 16021.1Skamil if (tracee == 0) { 16031.1Skamil CHILD_FROM_PARENT("Message 1", parent_tracee, msg); 16041.13Schristos DPRINTF("Parent should now attach to tracee\n"); 16051.1Skamil 16061.66Skamil if (stopped) { 16071.66Skamil DPRINTF("Stop self PID %d\n", getpid()); 16081.66Skamil SYSCALL_REQUIRE(raise(SIGSTOP) != -1); 16091.66Skamil } 16101.66Skamil 16111.1Skamil CHILD_FROM_PARENT("Message 2", parent_tracee, msg); 16121.1Skamil /* Wait for message from the parent */ 16131.1Skamil _exit(exitval_tracee); 16141.1Skamil } 16151.1Skamil PARENT_TO_CHILD("Message 1", parent_tracee, msg); 16161.57Skamil 16171.66Skamil if (stopped) { 16181.66Skamil DPRINTF("Await for a stopped tracee PID %d\n", tracee); 16191.66Skamil await_stopped(tracee); 16201.66Skamil } 16211.66Skamil 16221.13Schristos DPRINTF("Before calling PT_ATTACH for tracee %d\n", tracee); 16231.13Schristos SYSCALL_REQUIRE(ptrace(PT_ATTACH, tracee, NULL, 0) != -1); 16241.1Skamil 16251.13Schristos DPRINTF("Wait for the stopped tracee process with %s()\n", 16261.1Skamil TWAIT_FNAME); 16271.1Skamil TWAIT_REQUIRE_SUCCESS( 16281.1Skamil wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 16291.1Skamil 16301.1Skamil validate_status_stopped(status, SIGSTOP); 16311.1Skamil 16321.13Schristos DPRINTF("Resume tracee with PT_CONTINUE\n"); 16331.13Schristos SYSCALL_REQUIRE(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1); 16341.1Skamil 16351.13Schristos DPRINTF("Let the tracee exit now\n"); 16361.1Skamil PARENT_TO_CHILD("Message 2", parent_tracee, msg); 16371.1Skamil 16381.13Schristos DPRINTF("Wait for tracee to exit with %s()\n", TWAIT_FNAME); 16391.1Skamil TWAIT_REQUIRE_SUCCESS( 16401.1Skamil wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 16411.1Skamil 16421.1Skamil validate_status_exited(status, exitval_tracee); 16431.1Skamil 16441.13Schristos DPRINTF("Before calling %s() for tracee\n", TWAIT_FNAME); 16451.1Skamil TWAIT_REQUIRE_FAILURE(ECHILD, 16461.1Skamil wpid = TWAIT_GENERIC(tracee, &status, 0)); 16471.1Skamil 16481.1Skamil msg_close(&parent_tracee); 16491.1Skamil} 16501.1Skamil 16511.66SkamilATF_TC(parent_attach_to_its_child); 16521.66SkamilATF_TC_HEAD(parent_attach_to_its_child, tc) 16531.66Skamil{ 16541.66Skamil atf_tc_set_md_var(tc, "descr", 16551.66Skamil "Assert that tracer parent can PT_ATTACH to its child"); 16561.66Skamil} 16571.66Skamil 16581.66SkamilATF_TC_BODY(parent_attach_to_its_child, tc) 16591.66Skamil{ 16601.66Skamil 16611.66Skamil parent_attach_to_its_child(false); 16621.66Skamil} 16631.66Skamil 16641.66SkamilATF_TC(parent_attach_to_its_stopped_child); 16651.66SkamilATF_TC_HEAD(parent_attach_to_its_stopped_child, tc) 16661.66Skamil{ 16671.66Skamil atf_tc_set_md_var(tc, "descr", 16681.66Skamil "Assert that tracer parent can PT_ATTACH to its stopped child"); 16691.66Skamil} 16701.66Skamil 16711.66SkamilATF_TC_BODY(parent_attach_to_its_stopped_child, tc) 16721.66Skamil{ 16731.66Skamil 16741.66Skamil parent_attach_to_its_child(true); 16751.66Skamil} 16761.66Skamil 16771.51Skamil/// ---------------------------------------------------------------------------- 16781.51Skamil 16791.65Skamilstatic void 16801.65Skamilchild_attach_to_its_parent(bool stopped) 16811.1Skamil{ 16821.1Skamil struct msg_fds parent_tracee; 16831.1Skamil const int exitval_tracer = 5; 16841.1Skamil pid_t tracer, wpid; 16851.1Skamil uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */ 16861.1Skamil#if defined(TWAIT_HAVE_STATUS) 16871.1Skamil int status; 16881.1Skamil#endif 16891.1Skamil 16901.13Schristos DPRINTF("Spawn tracer\n"); 16911.13Schristos SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0); 16921.1Skamil tracer = atf_utils_fork(); 16931.1Skamil if (tracer == 0) { 16941.1Skamil /* Wait for message from the parent */ 16951.1Skamil CHILD_FROM_PARENT("Message 1", parent_tracee, msg); 16961.1Skamil 16971.65Skamil if (stopped) { 16981.65Skamil DPRINTF("Await for a stopped parent PID %d\n", 16991.65Skamil getppid()); 17001.65Skamil await_stopped(getppid()); 17011.65Skamil } 17021.65Skamil 17031.13Schristos DPRINTF("Attach to parent PID %d with PT_ATTACH from child\n", 17041.1Skamil getppid()); 17051.1Skamil FORKEE_ASSERT(ptrace(PT_ATTACH, getppid(), NULL, 0) != -1); 17061.1Skamil 17071.13Schristos DPRINTF("Wait for the stopped parent process with %s()\n", 17081.1Skamil TWAIT_FNAME); 17091.1Skamil FORKEE_REQUIRE_SUCCESS( 17101.1Skamil wpid = TWAIT_GENERIC(getppid(), &status, 0), getppid()); 17111.1Skamil 17121.1Skamil forkee_status_stopped(status, SIGSTOP); 17131.1Skamil 17141.13Schristos DPRINTF("Resume parent with PT_DETACH\n"); 17151.1Skamil FORKEE_ASSERT(ptrace(PT_DETACH, getppid(), (void *)1, 0) 17161.1Skamil != -1); 17171.1Skamil 17181.1Skamil /* Tell parent we are ready */ 17191.1Skamil CHILD_TO_PARENT("Message 1", parent_tracee, msg); 17201.1Skamil 17211.1Skamil _exit(exitval_tracer); 17221.1Skamil } 17231.1Skamil 17241.13Schristos DPRINTF("Wait for the tracer to become ready\n"); 17251.1Skamil PARENT_TO_CHILD("Message 1", parent_tracee, msg); 17261.65Skamil 17271.65Skamil if (stopped) { 17281.65Skamil DPRINTF("Stop self PID %d\n", getpid()); 17291.65Skamil SYSCALL_REQUIRE(raise(SIGSTOP) != -1); 17301.65Skamil } 17311.65Skamil 17321.13Schristos DPRINTF("Allow the tracer to exit now\n"); 17331.1Skamil PARENT_FROM_CHILD("Message 1", parent_tracee, msg); 17341.1Skamil 17351.13Schristos DPRINTF("Wait for tracer to exit with %s()\n", TWAIT_FNAME); 17361.1Skamil TWAIT_REQUIRE_SUCCESS( 17371.1Skamil wpid = TWAIT_GENERIC(tracer, &status, 0), tracer); 17381.1Skamil 17391.1Skamil validate_status_exited(status, exitval_tracer); 17401.1Skamil 17411.13Schristos DPRINTF("Before calling %s() for tracer\n", TWAIT_FNAME); 17421.1Skamil TWAIT_REQUIRE_FAILURE(ECHILD, 17431.1Skamil wpid = TWAIT_GENERIC(tracer, &status, 0)); 17441.1Skamil 17451.1Skamil msg_close(&parent_tracee); 17461.1Skamil} 17471.1Skamil 17481.65SkamilATF_TC(child_attach_to_its_parent); 17491.65SkamilATF_TC_HEAD(child_attach_to_its_parent, tc) 17501.65Skamil{ 17511.65Skamil atf_tc_set_md_var(tc, "descr", 17521.65Skamil "Assert that tracer child can PT_ATTACH to its parent"); 17531.65Skamil} 17541.65Skamil 17551.65SkamilATF_TC_BODY(child_attach_to_its_parent, tc) 17561.65Skamil{ 17571.65Skamil 17581.65Skamil child_attach_to_its_parent(false); 17591.65Skamil} 17601.65Skamil 17611.65SkamilATF_TC(child_attach_to_its_stopped_parent); 17621.65SkamilATF_TC_HEAD(child_attach_to_its_stopped_parent, tc) 17631.65Skamil{ 17641.65Skamil atf_tc_set_md_var(tc, "descr", 17651.65Skamil "Assert that tracer child can PT_ATTACH to its stopped parent"); 17661.65Skamil} 17671.65Skamil 17681.65SkamilATF_TC_BODY(child_attach_to_its_stopped_parent, tc) 17691.65Skamil{ 17701.65Skamil /* 17711.65Skamil * The ATF framework (atf-run) does not tolerate raise(SIGSTOP), as 17721.65Skamil * this causes a pipe (established from atf-run) to be broken. 17731.65Skamil * atf-run uses this mechanism to monitor whether a test is alive. 17741.65Skamil * 17751.65Skamil * As a workaround spawn this test as a subprocess. 17761.65Skamil */ 17771.65Skamil 17781.65Skamil const int exitval = 15; 17791.65Skamil pid_t child, wpid; 17801.65Skamil#if defined(TWAIT_HAVE_STATUS) 17811.65Skamil int status; 17821.65Skamil#endif 17831.65Skamil 17841.65Skamil SYSCALL_REQUIRE((child = fork()) != -1); 17851.65Skamil if (child == 0) { 17861.65Skamil child_attach_to_its_parent(true); 17871.65Skamil _exit(exitval); 17881.65Skamil } else { 17891.65Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 17901.65Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 17911.65Skamil 17921.65Skamil validate_status_exited(status, exitval); 17931.65Skamil 17941.65Skamil DPRINTF("Before calling %s() for the exited child\n", TWAIT_FNAME); 17951.65Skamil TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 17961.65Skamil } 17971.65Skamil} 17981.65Skamil 17991.51Skamil/// ---------------------------------------------------------------------------- 18001.51Skamil 18011.1Skamil#if defined(TWAIT_HAVE_PID) 18021.1Skamil 18031.51Skamilenum tracee_sees_its_original_parent_type { 18041.51Skamil TRACEE_SEES_ITS_ORIGINAL_PARENT_GETPPID, 18051.51Skamil TRACEE_SEES_ITS_ORIGINAL_PARENT_SYSCTL_KINFO_PROC2, 18061.51Skamil TRACEE_SEES_ITS_ORIGINAL_PARENT_PROCFS_STATUS 18071.51Skamil}; 18081.51Skamil 18091.51Skamilstatic void 18101.51Skamiltracee_sees_its_original_parent(enum tracee_sees_its_original_parent_type type) 18111.1Skamil{ 18121.1Skamil struct msg_fds parent_tracer, parent_tracee; 18131.1Skamil const int exitval_tracee = 5; 18141.1Skamil const int exitval_tracer = 10; 18151.1Skamil pid_t parent, tracee, tracer, wpid; 18161.1Skamil uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */ 18171.1Skamil#if defined(TWAIT_HAVE_STATUS) 18181.1Skamil int status; 18191.1Skamil#endif 18201.51Skamil /* sysctl(3) - kinfo_proc2 */ 18211.51Skamil int name[CTL_MAXNAME]; 18221.51Skamil struct kinfo_proc2 kp; 18231.51Skamil size_t len = sizeof(kp); 18241.51Skamil unsigned int namelen; 18251.51Skamil 18261.51Skamil /* procfs - status */ 18271.51Skamil FILE *fp; 18281.51Skamil struct stat st; 18291.51Skamil const char *fname = "/proc/curproc/status"; 18301.51Skamil char s_executable[MAXPATHLEN]; 18311.51Skamil int s_pid, s_ppid; 18321.51Skamil int rv; 18331.51Skamil 18341.51Skamil if (type == TRACEE_SEES_ITS_ORIGINAL_PARENT_PROCFS_STATUS) { 18351.61Skre SYSCALL_REQUIRE( 18361.61Skre (rv = stat(fname, &st)) == 0 || (errno == ENOENT)); 18371.61Skre if (rv != 0) 18381.51Skamil atf_tc_skip("/proc/curproc/status not found"); 18391.51Skamil } 18401.1Skamil 18411.13Schristos DPRINTF("Spawn tracee\n"); 18421.13Schristos SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0); 18431.13Schristos SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0); 18441.1Skamil tracee = atf_utils_fork(); 18451.1Skamil if (tracee == 0) { 18461.1Skamil parent = getppid(); 18471.1Skamil 18481.1Skamil /* Emit message to the parent */ 18491.1Skamil CHILD_TO_PARENT("tracee ready", parent_tracee, msg); 18501.1Skamil CHILD_FROM_PARENT("exit tracee", parent_tracee, msg); 18511.1Skamil 18521.51Skamil switch (type) { 18531.51Skamil case TRACEE_SEES_ITS_ORIGINAL_PARENT_GETPPID: 18541.51Skamil FORKEE_ASSERT_EQ(parent, getppid()); 18551.51Skamil break; 18561.51Skamil case TRACEE_SEES_ITS_ORIGINAL_PARENT_SYSCTL_KINFO_PROC2: 18571.51Skamil namelen = 0; 18581.51Skamil name[namelen++] = CTL_KERN; 18591.51Skamil name[namelen++] = KERN_PROC2; 18601.51Skamil name[namelen++] = KERN_PROC_PID; 18611.51Skamil name[namelen++] = getpid(); 18621.51Skamil name[namelen++] = len; 18631.51Skamil name[namelen++] = 1; 18641.51Skamil 18651.61Skre FORKEE_ASSERT_EQ( 18661.61Skre sysctl(name, namelen, &kp, &len, NULL, 0), 0); 18671.51Skamil FORKEE_ASSERT_EQ(parent, kp.p_ppid); 18681.51Skamil break; 18691.51Skamil case TRACEE_SEES_ITS_ORIGINAL_PARENT_PROCFS_STATUS: 18701.51Skamil /* 18711.51Skamil * Format: 18721.51Skamil * EXECUTABLE PID PPID ... 18731.51Skamil */ 18741.51Skamil FORKEE_ASSERT((fp = fopen(fname, "r")) != NULL); 18751.51Skamil fscanf(fp, "%s %d %d", s_executable, &s_pid, &s_ppid); 18761.51Skamil FORKEE_ASSERT_EQ(fclose(fp), 0); 18771.51Skamil FORKEE_ASSERT_EQ(parent, s_ppid); 18781.51Skamil break; 18791.51Skamil } 18801.1Skamil 18811.1Skamil _exit(exitval_tracee); 18821.1Skamil } 18831.13Schristos DPRINTF("Wait for child to record its parent identifier (pid)\n"); 18841.1Skamil PARENT_FROM_CHILD("tracee ready", parent_tracee, msg); 18851.1Skamil 18861.13Schristos DPRINTF("Spawn debugger\n"); 18871.1Skamil tracer = atf_utils_fork(); 18881.1Skamil if (tracer == 0) { 18891.1Skamil /* No IPC to communicate with the child */ 18901.13Schristos DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid()); 18911.1Skamil FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1); 18921.1Skamil 18931.1Skamil /* Wait for tracee and assert that it was stopped w/ SIGSTOP */ 18941.1Skamil FORKEE_REQUIRE_SUCCESS( 18951.1Skamil wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 18961.1Skamil 18971.1Skamil forkee_status_stopped(status, SIGSTOP); 18981.1Skamil 18991.1Skamil /* Resume tracee with PT_CONTINUE */ 19001.1Skamil FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1); 19011.1Skamil 19021.1Skamil /* Inform parent that tracer has attached to tracee */ 19031.1Skamil CHILD_TO_PARENT("tracer ready", parent_tracer, msg); 19041.1Skamil 19051.1Skamil /* Wait for parent to tell use that tracee should have exited */ 19061.1Skamil CHILD_FROM_PARENT("wait for tracee exit", parent_tracer, msg); 19071.1Skamil 19081.1Skamil /* Wait for tracee and assert that it exited */ 19091.1Skamil FORKEE_REQUIRE_SUCCESS( 19101.1Skamil wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 19111.1Skamil 19121.1Skamil forkee_status_exited(status, exitval_tracee); 19131.1Skamil 19141.13Schristos DPRINTF("Before exiting of the tracer process\n"); 19151.1Skamil _exit(exitval_tracer); 19161.1Skamil } 19171.1Skamil 19181.13Schristos DPRINTF("Wait for the tracer to attach to the tracee\n"); 19191.1Skamil PARENT_FROM_CHILD("tracer ready", parent_tracer, msg); 19201.1Skamil 19211.13Schristos DPRINTF("Resume the tracee and let it exit\n"); 19221.1Skamil PARENT_TO_CHILD("exit tracee", parent_tracee, msg); 19231.1Skamil 19241.13Schristos DPRINTF("Detect that tracee is zombie\n"); 19251.1Skamil await_zombie(tracee); 19261.1Skamil 19271.13Schristos DPRINTF("Assert that there is no status about tracee - " 19281.1Skamil "Tracer must detect zombie first - calling %s()\n", TWAIT_FNAME); 19291.1Skamil TWAIT_REQUIRE_SUCCESS( 19301.1Skamil wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0); 19311.1Skamil 19321.13Schristos DPRINTF("Tell the tracer child should have exited\n"); 19331.1Skamil PARENT_TO_CHILD("wait for tracee exit", parent_tracer, msg); 19341.1Skamil 19351.13Schristos DPRINTF("Wait from tracer child to complete waiting for tracee\n"); 19361.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0), 19371.1Skamil tracer); 19381.1Skamil 19391.1Skamil validate_status_exited(status, exitval_tracer); 19401.1Skamil 19411.13Schristos DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n", 19421.1Skamil TWAIT_FNAME); 19431.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 19441.1Skamil tracee); 19451.1Skamil 19461.1Skamil validate_status_exited(status, exitval_tracee); 19471.1Skamil 19481.1Skamil msg_close(&parent_tracer); 19491.1Skamil msg_close(&parent_tracee); 19501.1Skamil} 19511.1Skamil 19521.61Skre#define TRACEE_SEES_ITS_ORIGINAL_PARENT(test, type, descr) \ 19531.61SkreATF_TC(test); \ 19541.61SkreATF_TC_HEAD(test, tc) \ 19551.61Skre{ \ 19561.61Skre atf_tc_set_md_var(tc, "descr", \ 19571.61Skre "Assert that tracee sees its original parent when being traced " \ 19581.61Skre "(check " descr ")"); \ 19591.61Skre} \ 19601.61Skre \ 19611.61SkreATF_TC_BODY(test, tc) \ 19621.61Skre{ \ 19631.61Skre \ 19641.61Skre tracee_sees_its_original_parent(type); \ 19651.1Skamil} 19661.1Skamil 19671.51SkamilTRACEE_SEES_ITS_ORIGINAL_PARENT( 19681.51Skamil tracee_sees_its_original_parent_getppid, 19691.51Skamil TRACEE_SEES_ITS_ORIGINAL_PARENT_GETPPID, 19701.51Skamil "getppid(2)"); 19711.51SkamilTRACEE_SEES_ITS_ORIGINAL_PARENT( 19721.51Skamil tracee_sees_its_original_parent_sysctl_kinfo_proc2, 19731.51Skamil TRACEE_SEES_ITS_ORIGINAL_PARENT_SYSCTL_KINFO_PROC2, 19741.51Skamil "sysctl(3) and kinfo_proc2"); 19751.51SkamilTRACEE_SEES_ITS_ORIGINAL_PARENT( 19761.51Skamil tracee_sees_its_original_parent_procfs_status, 19771.51Skamil TRACEE_SEES_ITS_ORIGINAL_PARENT_PROCFS_STATUS, 19781.51Skamil "the status file in procfs"); 19791.1Skamil#endif 19801.1Skamil 19811.51Skamil/// ---------------------------------------------------------------------------- 19821.1Skamil 19831.53Skamilstatic void 19841.53Skamileventmask_preserved(int event) 19851.1Skamil{ 19861.1Skamil const int exitval = 5; 19871.1Skamil const int sigval = SIGSTOP; 19881.1Skamil pid_t child, wpid; 19891.1Skamil#if defined(TWAIT_HAVE_STATUS) 19901.1Skamil int status; 19911.1Skamil#endif 19921.1Skamil ptrace_event_t set_event, get_event; 19931.1Skamil const int len = sizeof(ptrace_event_t); 19941.1Skamil 19951.13Schristos DPRINTF("Before forking process PID=%d\n", getpid()); 19961.13Schristos SYSCALL_REQUIRE((child = fork()) != -1); 19971.1Skamil if (child == 0) { 19981.13Schristos DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 19991.1Skamil FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 20001.1Skamil 20011.13Schristos DPRINTF("Before raising %s from child\n", strsignal(sigval)); 20021.1Skamil FORKEE_ASSERT(raise(sigval) == 0); 20031.1Skamil 20041.13Schristos DPRINTF("Before exiting of the child process\n"); 20051.1Skamil _exit(exitval); 20061.1Skamil } 20071.13Schristos DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 20081.1Skamil 20091.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 20101.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 20111.1Skamil 20121.1Skamil validate_status_stopped(status, sigval); 20131.1Skamil 20141.53Skamil set_event.pe_set_event = event; 20151.61Skre SYSCALL_REQUIRE( 20161.61Skre ptrace(PT_SET_EVENT_MASK, child, &set_event, len) != -1); 20171.61Skre SYSCALL_REQUIRE( 20181.61Skre ptrace(PT_GET_EVENT_MASK, child, &get_event, len) != -1); 20191.1Skamil ATF_REQUIRE(memcmp(&set_event, &get_event, len) == 0); 20201.1Skamil 20211.13Schristos DPRINTF("Before resuming the child process where it left off and " 20221.1Skamil "without signal to be sent\n"); 20231.13Schristos SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 20241.1Skamil 20251.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 20261.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 20271.1Skamil 20281.1Skamil validate_status_exited(status, exitval); 20291.1Skamil 20301.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 20311.1Skamil TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 20321.1Skamil} 20331.1Skamil 20341.61Skre#define EVENTMASK_PRESERVED(test, event) \ 20351.61SkreATF_TC(test); \ 20361.61SkreATF_TC_HEAD(test, tc) \ 20371.61Skre{ \ 20381.61Skre atf_tc_set_md_var(tc, "descr", \ 20391.61Skre "Verify that eventmask " #event " is preserved"); \ 20401.61Skre} \ 20411.61Skre \ 20421.61SkreATF_TC_BODY(test, tc) \ 20431.61Skre{ \ 20441.61Skre \ 20451.61Skre eventmask_preserved(event); \ 20461.1Skamil} 20471.1Skamil 20481.53SkamilEVENTMASK_PRESERVED(eventmask_preserved_empty, 0) 20491.53SkamilEVENTMASK_PRESERVED(eventmask_preserved_fork, PTRACE_FORK) 20501.53SkamilEVENTMASK_PRESERVED(eventmask_preserved_vfork, PTRACE_VFORK) 20511.53SkamilEVENTMASK_PRESERVED(eventmask_preserved_vfork_done, PTRACE_VFORK_DONE) 20521.53SkamilEVENTMASK_PRESERVED(eventmask_preserved_lwp_create, PTRACE_LWP_CREATE) 20531.53SkamilEVENTMASK_PRESERVED(eventmask_preserved_lwp_exit, PTRACE_LWP_EXIT) 20541.1Skamil 20551.53Skamil/// ---------------------------------------------------------------------------- 20561.1Skamil 20571.28Skamilstatic void 20581.32Skamilfork_body(pid_t (*fn)(void), bool trackfork, bool trackvfork, 20591.61Skre bool trackvforkdone, bool detachchild, bool detachparent) 20601.1Skamil{ 20611.1Skamil const int exitval = 5; 20621.1Skamil const int exitval2 = 15; 20631.1Skamil const int sigval = SIGSTOP; 20641.31Skamil pid_t child, child2 = 0, wpid; 20651.1Skamil#if defined(TWAIT_HAVE_STATUS) 20661.1Skamil int status; 20671.1Skamil#endif 20681.1Skamil ptrace_state_t state; 20691.1Skamil const int slen = sizeof(state); 20701.1Skamil ptrace_event_t event; 20711.1Skamil const int elen = sizeof(event); 20721.1Skamil 20731.13Schristos DPRINTF("Before forking process PID=%d\n", getpid()); 20741.13Schristos SYSCALL_REQUIRE((child = fork()) != -1); 20751.1Skamil if (child == 0) { 20761.13Schristos DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 20771.1Skamil FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 20781.1Skamil 20791.13Schristos DPRINTF("Before raising %s from child\n", strsignal(sigval)); 20801.1Skamil FORKEE_ASSERT(raise(sigval) == 0); 20811.1Skamil 20821.30Skamil FORKEE_ASSERT((child2 = (fn)()) != -1); 20831.1Skamil 20841.1Skamil if (child2 == 0) 20851.1Skamil _exit(exitval2); 20861.1Skamil 20871.1Skamil FORKEE_REQUIRE_SUCCESS 20881.1Skamil (wpid = TWAIT_GENERIC(child2, &status, 0), child2); 20891.1Skamil 20901.1Skamil forkee_status_exited(status, exitval2); 20911.1Skamil 20921.13Schristos DPRINTF("Before exiting of the child process\n"); 20931.1Skamil _exit(exitval); 20941.1Skamil } 20951.13Schristos DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 20961.1Skamil 20971.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 20981.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 20991.1Skamil 21001.1Skamil validate_status_stopped(status, sigval); 21011.1Skamil 21021.30Skamil DPRINTF("Set 0%s%s%s in EVENT_MASK for the child %d\n", 21031.61Skre trackfork ? "|PTRACE_FORK" : "", 21041.61Skre trackvfork ? "|PTRACE_VFORK" : "", 21051.61Skre trackvforkdone ? "|PTRACE_VFORK_DONE" : "", child); 21061.30Skamil event.pe_set_event = 0; 21071.30Skamil if (trackfork) 21081.30Skamil event.pe_set_event |= PTRACE_FORK; 21091.30Skamil if (trackvfork) 21101.30Skamil event.pe_set_event |= PTRACE_VFORK; 21111.30Skamil if (trackvforkdone) 21121.30Skamil event.pe_set_event |= PTRACE_VFORK_DONE; 21131.13Schristos SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); 21141.1Skamil 21151.13Schristos DPRINTF("Before resuming the child process where it left off and " 21161.1Skamil "without signal to be sent\n"); 21171.13Schristos SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 21181.1Skamil 21191.29Skamil#if defined(TWAIT_HAVE_PID) 21201.31Skamil if ((trackfork && fn == fork) || (trackvfork && fn == vfork)) { 21211.29Skamil DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME, 21221.61Skre child); 21231.29Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), 21241.61Skre child); 21251.1Skamil 21261.29Skamil validate_status_stopped(status, SIGTRAP); 21271.1Skamil 21281.61Skre SYSCALL_REQUIRE( 21291.61Skre ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 21301.31Skamil if (trackfork && fn == fork) { 21311.30Skamil ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK, 21321.30Skamil PTRACE_FORK); 21331.30Skamil } 21341.31Skamil if (trackvfork && fn == vfork) { 21351.30Skamil ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK, 21361.30Skamil PTRACE_VFORK); 21371.30Skamil } 21381.29Skamil 21391.29Skamil child2 = state.pe_other_pid; 21401.30Skamil DPRINTF("Reported ptrace event with forkee %d\n", child2); 21411.29Skamil 21421.29Skamil DPRINTF("Before calling %s() for the forkee %d of the child " 21431.61Skre "%d\n", TWAIT_FNAME, child2, child); 21441.29Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0), 21451.29Skamil child2); 21461.1Skamil 21471.29Skamil validate_status_stopped(status, SIGTRAP); 21481.1Skamil 21491.61Skre SYSCALL_REQUIRE( 21501.61Skre ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1); 21511.31Skamil if (trackfork && fn == fork) { 21521.30Skamil ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK, 21531.30Skamil PTRACE_FORK); 21541.30Skamil } 21551.31Skamil if (trackvfork && fn == vfork) { 21561.30Skamil ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK, 21571.30Skamil PTRACE_VFORK); 21581.30Skamil } 21591.30Skamil 21601.29Skamil ATF_REQUIRE_EQ(state.pe_other_pid, child); 21611.29Skamil 21621.29Skamil DPRINTF("Before resuming the forkee process where it left off " 21631.29Skamil "and without signal to be sent\n"); 21641.61Skre SYSCALL_REQUIRE( 21651.61Skre ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1); 21661.29Skamil 21671.29Skamil DPRINTF("Before resuming the child process where it left off " 21681.61Skre "and without signal to be sent\n"); 21691.29Skamil SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 21701.30Skamil } 21711.30Skamil#endif 21721.30Skamil 21731.31Skamil if (trackvforkdone && fn == vfork) { 21741.30Skamil DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME, 21751.61Skre child); 21761.61Skre TWAIT_REQUIRE_SUCCESS( 21771.61Skre wpid = TWAIT_GENERIC(child, &status, 0), child); 21781.30Skamil 21791.30Skamil validate_status_stopped(status, SIGTRAP); 21801.30Skamil 21811.61Skre SYSCALL_REQUIRE( 21821.61Skre ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 21831.30Skamil ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK_DONE); 21841.30Skamil 21851.30Skamil child2 = state.pe_other_pid; 21861.30Skamil DPRINTF("Reported PTRACE_VFORK_DONE event with forkee %d\n", 21871.61Skre child2); 21881.30Skamil 21891.30Skamil DPRINTF("Before resuming the child process where it left off " 21901.61Skre "and without signal to be sent\n"); 21911.30Skamil SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 21921.30Skamil } 21931.29Skamil 21941.30Skamil#if defined(TWAIT_HAVE_PID) 21951.31Skamil if ((trackfork && fn == fork) || (trackvfork && fn == vfork)) { 21961.29Skamil DPRINTF("Before calling %s() for the forkee - expected exited" 21971.61Skre "\n", TWAIT_FNAME); 21981.61Skre TWAIT_REQUIRE_SUCCESS( 21991.61Skre wpid = TWAIT_GENERIC(child2, &status, 0), child2); 22001.29Skamil 22011.29Skamil validate_status_exited(status, exitval2); 22021.29Skamil 22031.29Skamil DPRINTF("Before calling %s() for the forkee - expected no " 22041.61Skre "process\n", TWAIT_FNAME); 22051.29Skamil TWAIT_REQUIRE_FAILURE(ECHILD, 22061.29Skamil wpid = TWAIT_GENERIC(child2, &status, 0)); 22071.29Skamil } 22081.29Skamil#endif 22091.1Skamil 22101.13Schristos DPRINTF("Before calling %s() for the child - expected stopped " 22111.1Skamil "SIGCHLD\n", TWAIT_FNAME); 22121.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 22131.1Skamil 22141.1Skamil validate_status_stopped(status, SIGCHLD); 22151.1Skamil 22161.13Schristos DPRINTF("Before resuming the child process where it left off and " 22171.1Skamil "without signal to be sent\n"); 22181.13Schristos SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 22191.1Skamil 22201.13Schristos DPRINTF("Before calling %s() for the child - expected exited\n", 22211.1Skamil TWAIT_FNAME); 22221.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 22231.1Skamil 22241.1Skamil validate_status_exited(status, exitval); 22251.1Skamil 22261.13Schristos DPRINTF("Before calling %s() for the child - expected no process\n", 22271.1Skamil TWAIT_FNAME); 22281.1Skamil TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 22291.1Skamil} 22301.28Skamil 22311.61Skre#define FORK_TEST(name,descr,fun,tfork,tvfork,tvforkdone,detchild,detparent) \ 22321.61SkreATF_TC(name); \ 22331.61SkreATF_TC_HEAD(name, tc) \ 22341.61Skre{ \ 22351.61Skre atf_tc_set_md_var(tc, "descr", descr); \ 22361.61Skre} \ 22371.61Skre \ 22381.61SkreATF_TC_BODY(name, tc) \ 22391.61Skre{ \ 22401.61Skre \ 22411.61Skre fork_body(fun, tfork, tvfork, tvforkdone, detchild, detparent); \ 22421.32Skamil} 22431.32Skamil 22441.32Skamil#define F false 22451.32Skamil#define T true 22461.32Skamil 22471.32Skamil#define F_IF__0(x) 22481.32Skamil#define F_IF__1(x) x 22491.32Skamil#define F_IF__(x,y) F_IF__ ## x (y) 22501.32Skamil#define F_IF_(x,y) F_IF__(x,y) 22511.32Skamil#define F_IF(x,y) F_IF_(x,y) 22521.32Skamil 22531.61Skre#define DSCR(function,forkbit,vforkbit,vforkdonebit,dchildbit,dparentbit) \ 22541.61Skre "Verify " #function "(2) called with 0" \ 22551.61Skre F_IF(forkbit,"|PTRACE_FORK") \ 22561.61Skre F_IF(vforkbit,"|PTRACE_VFORK") \ 22571.61Skre F_IF(vforkdonebit,"|PTRACE_VFORK_DONE") \ 22581.61Skre " in EVENT_MASK." \ 22591.61Skre F_IF(dchildbit," Detach child in this test.") \ 22601.61Skre F_IF(dparentbit," Detach parent in this test.") 22611.1Skamil 22621.32SkamilFORK_TEST(fork1, DSCR(fork,0,0,0,0,0), fork, F, F, F, F, F) 22631.31Skamil#if defined(TWAIT_HAVE_PID) 22641.32SkamilFORK_TEST(fork2, DSCR(fork,1,0,0,0,0), fork, T, F, F, F, F) 22651.32SkamilFORK_TEST(fork3, DSCR(fork,0,1,0,0,0), fork, F, T, F, F, F) 22661.32SkamilFORK_TEST(fork4, DSCR(fork,1,1,0,0,0), fork, T, T, F, F, F) 22671.31Skamil#endif 22681.32SkamilFORK_TEST(fork5, DSCR(fork,0,0,1,0,0), fork, F, F, T, F, F) 22691.31Skamil#if defined(TWAIT_HAVE_PID) 22701.32SkamilFORK_TEST(fork6, DSCR(fork,1,0,1,0,0), fork, T, F, T, F, F) 22711.32SkamilFORK_TEST(fork7, DSCR(fork,0,1,1,0,0), fork, F, T, T, F, F) 22721.32SkamilFORK_TEST(fork8, DSCR(fork,1,1,1,0,0), fork, T, T, T, F, F) 22731.31Skamil#endif 22741.1Skamil 22751.32SkamilFORK_TEST(vfork1, DSCR(vfork,0,0,0,0,0), vfork, F, F, F, F, F) 22761.31Skamil#if defined(TWAIT_HAVE_PID) 22771.32SkamilFORK_TEST(vfork2, DSCR(vfork,1,0,0,0,0), vfork, T, F, F, F, F) 22781.32SkamilFORK_TEST(vfork3, DSCR(vfork,0,1,0,0,0), vfork, F, T, F, F, F) 22791.32SkamilFORK_TEST(vfork4, DSCR(vfork,1,1,0,0,0), vfork, T, T, F, F, F) 22801.31Skamil#endif 22811.32SkamilFORK_TEST(vfork5, DSCR(vfork,0,0,1,0,0), vfork, F, F, T, F, F) 22821.31Skamil#if defined(TWAIT_HAVE_PID) 22831.32SkamilFORK_TEST(vfork6, DSCR(vfork,1,0,1,0,0), vfork, T, F, T, F, F) 22841.32SkamilFORK_TEST(vfork7, DSCR(vfork,0,1,1,0,0), vfork, F, T, T, F, F) 22851.32SkamilFORK_TEST(vfork8, DSCR(vfork,1,1,1,0,0), vfork, T, T, T, F, F) 22861.31Skamil#endif 22871.31Skamil 22881.54Skamil/// ---------------------------------------------------------------------------- 22891.31Skamil 22901.54Skamilenum bytes_transfer_type { 22911.54Skamil BYTES_TRANSFER_DATA, 22921.54Skamil BYTES_TRANSFER_DATAIO, 22931.54Skamil BYTES_TRANSFER_TEXT, 22941.54Skamil BYTES_TRANSFER_TEXTIO, 22951.54Skamil BYTES_TRANSFER_AUXV 22961.54Skamil}; 22971.31Skamil 22981.54Skamilstatic int __used 22991.54Skamilbytes_transfer_dummy(int a, int b, int c, int d) 23001.54Skamil{ 23011.54Skamil int e, f, g, h; 23021.1Skamil 23031.54Skamil a *= 4; 23041.54Skamil b += 3; 23051.54Skamil c -= 2; 23061.54Skamil d /= 1; 23071.1Skamil 23081.54Skamil e = strtol("10", NULL, 10); 23091.54Skamil f = strtol("20", NULL, 10); 23101.54Skamil g = strtol("30", NULL, 10); 23111.54Skamil h = strtol("40", NULL, 10); 23121.1Skamil 23131.54Skamil return (a + b * c - d) + (e * f - g / h); 23141.1Skamil} 23151.1Skamil 23161.54Skamilstatic void 23171.55Schristosbytes_transfer(int operation, size_t size, enum bytes_transfer_type type) 23181.1Skamil{ 23191.1Skamil const int exitval = 5; 23201.1Skamil const int sigval = SIGSTOP; 23211.1Skamil pid_t child, wpid; 23221.54Skamil bool skip = false; 23231.1Skamil 23241.54Skamil int lookup_me = 0; 23251.54Skamil uint8_t lookup_me8 = 0; 23261.54Skamil uint16_t lookup_me16 = 0; 23271.54Skamil uint32_t lookup_me32 = 0; 23281.54Skamil uint64_t lookup_me64 = 0; 23291.1Skamil 23301.54Skamil int magic = 0x13579246; 23311.54Skamil uint8_t magic8 = 0xab; 23321.54Skamil uint16_t magic16 = 0x1234; 23331.54Skamil uint32_t magic32 = 0x98765432; 23341.54Skamil uint64_t magic64 = 0xabcdef0123456789; 23351.1Skamil 23361.54Skamil struct ptrace_io_desc io; 23371.1Skamil#if defined(TWAIT_HAVE_STATUS) 23381.1Skamil int status; 23391.1Skamil#endif 23401.60Skre /* 513 is just enough, for the purposes of ATF it's good enough */ 23411.60Skre AuxInfo ai[513], *aip; 23421.55Schristos 23431.55Schristos ATF_REQUIRE(size < sizeof(ai)); 23441.1Skamil 23451.54Skamil /* Prepare variables for .TEXT transfers */ 23461.54Skamil switch (type) { 23471.54Skamil case BYTES_TRANSFER_TEXT: 23481.54Skamil memcpy(&magic, bytes_transfer_dummy, sizeof(magic)); 23491.54Skamil break; 23501.54Skamil case BYTES_TRANSFER_TEXTIO: 23511.54Skamil switch (size) { 23521.54Skamil case 8: 23531.54Skamil memcpy(&magic8, bytes_transfer_dummy, sizeof(magic8)); 23541.54Skamil break; 23551.54Skamil case 16: 23561.54Skamil memcpy(&magic16, bytes_transfer_dummy, sizeof(magic16)); 23571.54Skamil break; 23581.54Skamil case 32: 23591.54Skamil memcpy(&magic32, bytes_transfer_dummy, sizeof(magic32)); 23601.54Skamil break; 23611.54Skamil case 64: 23621.54Skamil memcpy(&magic64, bytes_transfer_dummy, sizeof(magic64)); 23631.54Skamil break; 23641.54Skamil } 23651.54Skamil break; 23661.54Skamil default: 23671.54Skamil break; 23681.54Skamil } 23691.1Skamil 23701.54Skamil /* Prepare variables for PIOD and AUXV transfers */ 23711.54Skamil switch (type) { 23721.54Skamil case BYTES_TRANSFER_TEXTIO: 23731.54Skamil case BYTES_TRANSFER_DATAIO: 23741.54Skamil io.piod_op = operation; 23751.54Skamil switch (size) { 23761.54Skamil case 8: 23771.54Skamil io.piod_offs = (type == BYTES_TRANSFER_TEXTIO) ? 23781.54Skamil (void *)bytes_transfer_dummy : 23791.54Skamil &lookup_me8; 23801.54Skamil io.piod_addr = &lookup_me8; 23811.54Skamil io.piod_len = sizeof(lookup_me8); 23821.54Skamil break; 23831.54Skamil case 16: 23841.54Skamil io.piod_offs = (type == BYTES_TRANSFER_TEXTIO) ? 23851.54Skamil (void *)bytes_transfer_dummy : 23861.54Skamil &lookup_me16; 23871.54Skamil io.piod_addr = &lookup_me16; 23881.54Skamil io.piod_len = sizeof(lookup_me16); 23891.54Skamil break; 23901.54Skamil case 32: 23911.54Skamil io.piod_offs = (type == BYTES_TRANSFER_TEXTIO) ? 23921.54Skamil (void *)bytes_transfer_dummy : 23931.54Skamil &lookup_me32; 23941.54Skamil io.piod_addr = &lookup_me32; 23951.54Skamil io.piod_len = sizeof(lookup_me32); 23961.54Skamil break; 23971.54Skamil case 64: 23981.54Skamil io.piod_offs = (type == BYTES_TRANSFER_TEXTIO) ? 23991.54Skamil (void *)bytes_transfer_dummy : 24001.54Skamil &lookup_me64; 24011.54Skamil io.piod_addr = &lookup_me64; 24021.54Skamil io.piod_len = sizeof(lookup_me64); 24031.54Skamil break; 24041.54Skamil default: 24051.54Skamil break; 24061.54Skamil } 24071.54Skamil break; 24081.54Skamil case BYTES_TRANSFER_AUXV: 24091.54Skamil io.piod_op = operation; 24101.54Skamil io.piod_offs = 0; 24111.54Skamil io.piod_addr = ai; 24121.54Skamil io.piod_len = size; 24131.54Skamil break; 24141.54Skamil default: 24151.54Skamil break; 24161.1Skamil } 24171.1Skamil 24181.13Schristos DPRINTF("Before forking process PID=%d\n", getpid()); 24191.13Schristos SYSCALL_REQUIRE((child = fork()) != -1); 24201.1Skamil if (child == 0) { 24211.13Schristos DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 24221.1Skamil FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 24231.1Skamil 24241.54Skamil switch (type) { 24251.54Skamil case BYTES_TRANSFER_DATA: 24261.54Skamil switch (operation) { 24271.54Skamil case PT_READ_D: 24281.54Skamil case PT_READ_I: 24291.54Skamil lookup_me = magic; 24301.54Skamil break; 24311.54Skamil default: 24321.54Skamil break; 24331.54Skamil } 24341.54Skamil break; 24351.54Skamil case BYTES_TRANSFER_DATAIO: 24361.54Skamil switch (operation) { 24371.54Skamil case PIOD_READ_D: 24381.54Skamil case PIOD_READ_I: 24391.54Skamil switch (size) { 24401.54Skamil case 8: 24411.54Skamil lookup_me8 = magic8; 24421.54Skamil break; 24431.54Skamil case 16: 24441.54Skamil lookup_me16 = magic16; 24451.54Skamil break; 24461.54Skamil case 32: 24471.54Skamil lookup_me32 = magic32; 24481.54Skamil break; 24491.54Skamil case 64: 24501.54Skamil lookup_me64 = magic64; 24511.54Skamil break; 24521.54Skamil default: 24531.54Skamil break; 24541.54Skamil } 24551.54Skamil break; 24561.54Skamil default: 24571.54Skamil break; 24581.54Skamil } 24591.54Skamil default: 24601.54Skamil break; 24611.54Skamil } 24621.54Skamil 24631.13Schristos DPRINTF("Before raising %s from child\n", strsignal(sigval)); 24641.1Skamil FORKEE_ASSERT(raise(sigval) == 0); 24651.1Skamil 24661.54Skamil /* Handle PIOD and PT separately as operation values overlap */ 24671.54Skamil switch (type) { 24681.54Skamil case BYTES_TRANSFER_DATA: 24691.54Skamil switch (operation) { 24701.54Skamil case PT_WRITE_D: 24711.54Skamil case PT_WRITE_I: 24721.54Skamil FORKEE_ASSERT_EQ(lookup_me, magic); 24731.54Skamil break; 24741.54Skamil default: 24751.54Skamil break; 24761.54Skamil } 24771.54Skamil break; 24781.54Skamil case BYTES_TRANSFER_DATAIO: 24791.54Skamil switch (operation) { 24801.54Skamil case PIOD_WRITE_D: 24811.54Skamil case PIOD_WRITE_I: 24821.54Skamil switch (size) { 24831.54Skamil case 8: 24841.54Skamil FORKEE_ASSERT_EQ(lookup_me8, magic8); 24851.54Skamil break; 24861.54Skamil case 16: 24871.54Skamil FORKEE_ASSERT_EQ(lookup_me16, magic16); 24881.54Skamil break; 24891.54Skamil case 32: 24901.54Skamil FORKEE_ASSERT_EQ(lookup_me32, magic32); 24911.54Skamil break; 24921.54Skamil case 64: 24931.54Skamil FORKEE_ASSERT_EQ(lookup_me64, magic64); 24941.54Skamil break; 24951.54Skamil default: 24961.54Skamil break; 24971.54Skamil } 24981.54Skamil break; 24991.54Skamil default: 25001.54Skamil break; 25011.54Skamil } 25021.54Skamil break; 25031.54Skamil case BYTES_TRANSFER_TEXT: 25041.54Skamil FORKEE_ASSERT(memcmp(&magic, bytes_transfer_dummy, 25051.54Skamil sizeof(magic)) == 0); 25061.54Skamil break; 25071.54Skamil case BYTES_TRANSFER_TEXTIO: 25081.54Skamil switch (size) { 25091.54Skamil case 8: 25101.54Skamil FORKEE_ASSERT(memcmp(&magic8, 25111.54Skamil bytes_transfer_dummy, 25121.54Skamil sizeof(magic8)) == 0); 25131.54Skamil break; 25141.54Skamil case 16: 25151.54Skamil FORKEE_ASSERT(memcmp(&magic16, 25161.54Skamil bytes_transfer_dummy, 25171.54Skamil sizeof(magic16)) == 0); 25181.54Skamil break; 25191.54Skamil case 32: 25201.54Skamil FORKEE_ASSERT(memcmp(&magic32, 25211.54Skamil bytes_transfer_dummy, 25221.54Skamil sizeof(magic32)) == 0); 25231.54Skamil break; 25241.54Skamil case 64: 25251.54Skamil FORKEE_ASSERT(memcmp(&magic64, 25261.54Skamil bytes_transfer_dummy, 25271.54Skamil sizeof(magic64)) == 0); 25281.54Skamil break; 25291.54Skamil } 25301.54Skamil break; 25311.54Skamil default: 25321.54Skamil break; 25331.54Skamil } 25341.54Skamil 25351.13Schristos DPRINTF("Before exiting of the child process\n"); 25361.1Skamil _exit(exitval); 25371.1Skamil } 25381.13Schristos DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 25391.1Skamil 25401.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 25411.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 25421.1Skamil 25431.1Skamil validate_status_stopped(status, sigval); 25441.1Skamil 25451.54Skamil /* Check PaX MPROTECT */ 25461.54Skamil if (!can_we_write_to_text(child)) { 25471.54Skamil switch (type) { 25481.54Skamil case BYTES_TRANSFER_TEXTIO: 25491.54Skamil switch (operation) { 25501.54Skamil case PIOD_WRITE_D: 25511.54Skamil case PIOD_WRITE_I: 25521.54Skamil skip = true; 25531.54Skamil break; 25541.54Skamil default: 25551.54Skamil break; 25561.54Skamil } 25571.54Skamil break; 25581.54Skamil case BYTES_TRANSFER_TEXT: 25591.54Skamil switch (operation) { 25601.54Skamil case PT_WRITE_D: 25611.54Skamil case PT_WRITE_I: 25621.54Skamil skip = true; 25631.54Skamil break; 25641.54Skamil default: 25651.54Skamil break; 25661.54Skamil } 25671.54Skamil break; 25681.54Skamil default: 25691.54Skamil break; 25701.54Skamil } 25711.54Skamil } 25721.1Skamil 25731.54Skamil /* Bailout cleanly killing the child process */ 25741.54Skamil if (skip) { 25751.54Skamil SYSCALL_REQUIRE(ptrace(PT_KILL, child, (void *)1, 0) != -1); 25761.54Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 25771.54Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), 25781.54Skamil child); 25791.1Skamil 25801.54Skamil validate_status_signaled(status, SIGKILL, 0); 25811.1Skamil 25821.54Skamil atf_tc_skip("PaX MPROTECT setup prevents writes to .text"); 25831.54Skamil } 25841.1Skamil 25851.54Skamil DPRINTF("Calling operation to transfer bytes between child=%d and " 25861.54Skamil "parent=%d\n", child, getpid()); 25871.1Skamil 25881.54Skamil switch (type) { 25891.54Skamil case BYTES_TRANSFER_TEXTIO: 25901.54Skamil case BYTES_TRANSFER_DATAIO: 25911.54Skamil case BYTES_TRANSFER_AUXV: 25921.54Skamil switch (operation) { 25931.54Skamil case PIOD_WRITE_D: 25941.54Skamil case PIOD_WRITE_I: 25951.54Skamil switch (size) { 25961.54Skamil case 8: 25971.54Skamil lookup_me8 = magic8; 25981.54Skamil break; 25991.54Skamil case 16: 26001.54Skamil lookup_me16 = magic16; 26011.54Skamil break; 26021.54Skamil case 32: 26031.54Skamil lookup_me32 = magic32; 26041.54Skamil break; 26051.54Skamil case 64: 26061.54Skamil lookup_me64 = magic64; 26071.54Skamil break; 26081.54Skamil default: 26091.54Skamil break; 26101.54Skamil } 26111.54Skamil break; 26121.54Skamil default: 26131.54Skamil break; 26141.54Skamil } 26151.54Skamil SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1); 26161.54Skamil switch (operation) { 26171.54Skamil case PIOD_READ_D: 26181.54Skamil case PIOD_READ_I: 26191.54Skamil switch (size) { 26201.54Skamil case 8: 26211.54Skamil ATF_REQUIRE_EQ(lookup_me8, magic8); 26221.54Skamil break; 26231.54Skamil case 16: 26241.54Skamil ATF_REQUIRE_EQ(lookup_me16, magic16); 26251.54Skamil break; 26261.54Skamil case 32: 26271.54Skamil ATF_REQUIRE_EQ(lookup_me32, magic32); 26281.54Skamil break; 26291.54Skamil case 64: 26301.54Skamil ATF_REQUIRE_EQ(lookup_me64, magic64); 26311.54Skamil break; 26321.54Skamil default: 26331.54Skamil break; 26341.54Skamil } 26351.54Skamil break; 26361.54Skamil case PIOD_READ_AUXV: 26371.54Skamil DPRINTF("Asserting that AUXV length (%zu) is > 0\n", 26381.54Skamil io.piod_len); 26391.54Skamil ATF_REQUIRE(io.piod_len > 0); 26401.54Skamil for (aip = ai; aip->a_type != AT_NULL; aip++) 26411.54Skamil DPRINTF("a_type=%#llx a_v=%#llx\n", 26421.54Skamil (long long int)aip->a_type, 26431.54Skamil (long long int)aip->a_v); 26441.54Skamil break; 26451.54Skamil default: 26461.54Skamil break; 26471.54Skamil } 26481.54Skamil break; 26491.54Skamil case BYTES_TRANSFER_TEXT: 26501.54Skamil switch (operation) { 26511.54Skamil case PT_READ_D: 26521.54Skamil case PT_READ_I: 26531.54Skamil errno = 0; 26541.54Skamil lookup_me = ptrace(operation, child, 26551.54Skamil bytes_transfer_dummy, 0); 26561.54Skamil ATF_REQUIRE_EQ(lookup_me, magic); 26571.54Skamil SYSCALL_REQUIRE_ERRNO(errno, 0); 26581.54Skamil break; 26591.54Skamil case PT_WRITE_D: 26601.54Skamil case PT_WRITE_I: 26611.54Skamil SYSCALL_REQUIRE(ptrace(operation, child, 26621.54Skamil bytes_transfer_dummy, magic) 26631.54Skamil != -1); 26641.54Skamil break; 26651.54Skamil default: 26661.54Skamil break; 26671.54Skamil } 26681.54Skamil break; 26691.54Skamil case BYTES_TRANSFER_DATA: 26701.54Skamil switch (operation) { 26711.54Skamil case PT_READ_D: 26721.54Skamil case PT_READ_I: 26731.54Skamil errno = 0; 26741.54Skamil lookup_me = ptrace(operation, child, &lookup_me, 0); 26751.54Skamil ATF_REQUIRE_EQ(lookup_me, magic); 26761.54Skamil SYSCALL_REQUIRE_ERRNO(errno, 0); 26771.54Skamil break; 26781.54Skamil case PT_WRITE_D: 26791.54Skamil case PT_WRITE_I: 26801.54Skamil lookup_me = magic; 26811.54Skamil SYSCALL_REQUIRE(ptrace(operation, child, &lookup_me, 26821.54Skamil magic) != -1); 26831.54Skamil break; 26841.54Skamil default: 26851.54Skamil break; 26861.54Skamil } 26871.54Skamil break; 26881.54Skamil default: 26891.54Skamil break; 26901.54Skamil } 26911.1Skamil 26921.13Schristos DPRINTF("Before resuming the child process where it left off and " 26931.1Skamil "without signal to be sent\n"); 26941.13Schristos SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 26951.1Skamil 26961.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 26971.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 26981.1Skamil 26991.1Skamil validate_status_exited(status, exitval); 27001.1Skamil 27011.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 27021.1Skamil TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 27031.1Skamil} 27041.1Skamil 27051.61Skre#define BYTES_TRANSFER(test, operation, size, type) \ 27061.61SkreATF_TC(test); \ 27071.61SkreATF_TC_HEAD(test, tc) \ 27081.61Skre{ \ 27091.61Skre atf_tc_set_md_var(tc, "descr", \ 27101.61Skre "Verify bytes transfer operation" #operation " and size " #size \ 27111.61Skre " of type " #type); \ 27121.61Skre} \ 27131.61Skre \ 27141.61SkreATF_TC_BODY(test, tc) \ 27151.61Skre{ \ 27161.61Skre \ 27171.61Skre bytes_transfer(operation, size, BYTES_TRANSFER_##type); \ 27181.1Skamil} 27191.1Skamil 27201.54Skamil// DATA 27211.1Skamil 27221.54SkamilBYTES_TRANSFER(bytes_transfer_piod_read_d_8, PIOD_READ_D, 8, DATAIO) 27231.54SkamilBYTES_TRANSFER(bytes_transfer_piod_read_d_16, PIOD_READ_D, 16, DATAIO) 27241.54SkamilBYTES_TRANSFER(bytes_transfer_piod_read_d_32, PIOD_READ_D, 32, DATAIO) 27251.54SkamilBYTES_TRANSFER(bytes_transfer_piod_read_d_64, PIOD_READ_D, 64, DATAIO) 27261.54Skamil 27271.54SkamilBYTES_TRANSFER(bytes_transfer_piod_read_i_8, PIOD_READ_I, 8, DATAIO) 27281.54SkamilBYTES_TRANSFER(bytes_transfer_piod_read_i_16, PIOD_READ_I, 16, DATAIO) 27291.54SkamilBYTES_TRANSFER(bytes_transfer_piod_read_i_32, PIOD_READ_I, 32, DATAIO) 27301.54SkamilBYTES_TRANSFER(bytes_transfer_piod_read_i_64, PIOD_READ_I, 64, DATAIO) 27311.54Skamil 27321.54SkamilBYTES_TRANSFER(bytes_transfer_piod_write_d_8, PIOD_WRITE_D, 8, DATAIO) 27331.54SkamilBYTES_TRANSFER(bytes_transfer_piod_write_d_16, PIOD_WRITE_D, 16, DATAIO) 27341.54SkamilBYTES_TRANSFER(bytes_transfer_piod_write_d_32, PIOD_WRITE_D, 32, DATAIO) 27351.54SkamilBYTES_TRANSFER(bytes_transfer_piod_write_d_64, PIOD_WRITE_D, 64, DATAIO) 27361.54Skamil 27371.54SkamilBYTES_TRANSFER(bytes_transfer_piod_write_i_8, PIOD_WRITE_I, 8, DATAIO) 27381.54SkamilBYTES_TRANSFER(bytes_transfer_piod_write_i_16, PIOD_WRITE_I, 16, DATAIO) 27391.54SkamilBYTES_TRANSFER(bytes_transfer_piod_write_i_32, PIOD_WRITE_I, 32, DATAIO) 27401.54SkamilBYTES_TRANSFER(bytes_transfer_piod_write_i_64, PIOD_WRITE_I, 64, DATAIO) 27411.54Skamil 27421.54SkamilBYTES_TRANSFER(bytes_transfer_read_d, PT_READ_D, 32, DATA) 27431.54SkamilBYTES_TRANSFER(bytes_transfer_read_i, PT_READ_I, 32, DATA) 27441.54SkamilBYTES_TRANSFER(bytes_transfer_write_d, PT_WRITE_D, 32, DATA) 27451.54SkamilBYTES_TRANSFER(bytes_transfer_write_i, PT_WRITE_I, 32, DATA) 27461.54Skamil 27471.54Skamil// TEXT 27481.54Skamil 27491.54SkamilBYTES_TRANSFER(bytes_transfer_piod_read_d_8_text, PIOD_READ_D, 8, TEXTIO) 27501.54SkamilBYTES_TRANSFER(bytes_transfer_piod_read_d_16_text, PIOD_READ_D, 16, TEXTIO) 27511.54SkamilBYTES_TRANSFER(bytes_transfer_piod_read_d_32_text, PIOD_READ_D, 32, TEXTIO) 27521.54SkamilBYTES_TRANSFER(bytes_transfer_piod_read_d_64_text, PIOD_READ_D, 64, TEXTIO) 27531.54Skamil 27541.54SkamilBYTES_TRANSFER(bytes_transfer_piod_read_i_8_text, PIOD_READ_I, 8, TEXTIO) 27551.54SkamilBYTES_TRANSFER(bytes_transfer_piod_read_i_16_text, PIOD_READ_I, 16, TEXTIO) 27561.54SkamilBYTES_TRANSFER(bytes_transfer_piod_read_i_32_text, PIOD_READ_I, 32, TEXTIO) 27571.54SkamilBYTES_TRANSFER(bytes_transfer_piod_read_i_64_text, PIOD_READ_I, 64, TEXTIO) 27581.54Skamil 27591.54SkamilBYTES_TRANSFER(bytes_transfer_piod_write_d_8_text, PIOD_WRITE_D, 8, TEXTIO) 27601.54SkamilBYTES_TRANSFER(bytes_transfer_piod_write_d_16_text, PIOD_WRITE_D, 16, TEXTIO) 27611.54SkamilBYTES_TRANSFER(bytes_transfer_piod_write_d_32_text, PIOD_WRITE_D, 32, TEXTIO) 27621.54SkamilBYTES_TRANSFER(bytes_transfer_piod_write_d_64_text, PIOD_WRITE_D, 64, TEXTIO) 27631.54Skamil 27641.54SkamilBYTES_TRANSFER(bytes_transfer_piod_write_i_8_text, PIOD_WRITE_I, 8, TEXTIO) 27651.54SkamilBYTES_TRANSFER(bytes_transfer_piod_write_i_16_text, PIOD_WRITE_I, 16, TEXTIO) 27661.54SkamilBYTES_TRANSFER(bytes_transfer_piod_write_i_32_text, PIOD_WRITE_I, 32, TEXTIO) 27671.54SkamilBYTES_TRANSFER(bytes_transfer_piod_write_i_64_text, PIOD_WRITE_I, 64, TEXTIO) 27681.54Skamil 27691.54SkamilBYTES_TRANSFER(bytes_transfer_read_d_text, PT_READ_D, 32, TEXT) 27701.54SkamilBYTES_TRANSFER(bytes_transfer_read_i_text, PT_READ_I, 32, TEXT) 27711.54SkamilBYTES_TRANSFER(bytes_transfer_write_d_text, PT_WRITE_D, 32, TEXT) 27721.54SkamilBYTES_TRANSFER(bytes_transfer_write_i_text, PT_WRITE_I, 32, TEXT) 27731.1Skamil 27741.54Skamil// AUXV 27751.1Skamil 27761.54SkamilBYTES_TRANSFER(bytes_transfer_piod_read_auxv, PIOD_READ_AUXV, 4096, AUXV) 27771.1Skamil 27781.54Skamil/// ---------------------------------------------------------------------------- 27791.1Skamil 27801.76Sscole#if defined(HAVE_GPREGS) || defined(HAVE_FPREGS) 27811.72Skamilstatic void 27821.72Skamilaccess_regs(const char *regset, const char *aux) 27831.1Skamil{ 27841.1Skamil const int exitval = 5; 27851.1Skamil const int sigval = SIGSTOP; 27861.1Skamil pid_t child, wpid; 27871.1Skamil#if defined(TWAIT_HAVE_STATUS) 27881.1Skamil int status; 27891.1Skamil#endif 27901.72Skamil#if defined(HAVE_GPREGS) 27911.72Skamil struct reg gpr; 27921.76Sscole register_t rgstr; 27931.1Skamil#endif 27941.72Skamil#if defined(HAVE_FPREGS) 27951.72Skamil struct fpreg fpr; 27961.1Skamil#endif 27971.76Sscole 27981.72Skamil#if !defined(HAVE_GPREGS) 27991.72Skamil if (strcmp(regset, "regs") == 0) 28001.72Skamil atf_tc_fail("Impossible test scenario!"); 28011.1Skamil#endif 28021.1Skamil 28031.72Skamil#if !defined(HAVE_FPREGS) 28041.72Skamil if (strcmp(regset, "fpregs") == 0) 28051.72Skamil atf_tc_fail("Impossible test scenario!"); 28061.1Skamil#endif 28071.1Skamil 28081.13Schristos DPRINTF("Before forking process PID=%d\n", getpid()); 28091.13Schristos SYSCALL_REQUIRE((child = fork()) != -1); 28101.1Skamil if (child == 0) { 28111.13Schristos DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 28121.1Skamil FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 28131.1Skamil 28141.13Schristos DPRINTF("Before raising %s from child\n", strsignal(sigval)); 28151.1Skamil FORKEE_ASSERT(raise(sigval) == 0); 28161.1Skamil 28171.13Schristos DPRINTF("Before exiting of the child process\n"); 28181.1Skamil _exit(exitval); 28191.1Skamil } 28201.13Schristos DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 28211.1Skamil 28221.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 28231.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 28241.1Skamil 28251.1Skamil validate_status_stopped(status, sigval); 28261.1Skamil 28271.1Skamil#if defined(HAVE_GPREGS) 28281.72Skamil if (strcmp(regset, "regs") == 0) { 28291.72Skamil DPRINTF("Call GETREGS for the child process\n"); 28301.72Skamil SYSCALL_REQUIRE(ptrace(PT_GETREGS, child, &gpr, 0) != -1); 28311.72Skamil 28321.72Skamil if (strcmp(aux, "none") == 0) { 28331.72Skamil DPRINTF("Retrieved registers\n"); 28341.72Skamil } else if (strcmp(aux, "pc") == 0) { 28351.72Skamil rgstr = PTRACE_REG_PC(&gpr); 28361.72Skamil DPRINTF("Retrieved %" PRIxREGISTER "\n", rgstr); 28371.72Skamil } else if (strcmp(aux, "set_pc") == 0) { 28381.72Skamil rgstr = PTRACE_REG_PC(&gpr); 28391.72Skamil PTRACE_REG_SET_PC(&gpr, rgstr); 28401.72Skamil } else if (strcmp(aux, "sp") == 0) { 28411.72Skamil rgstr = PTRACE_REG_SP(&gpr); 28421.72Skamil DPRINTF("Retrieved %" PRIxREGISTER "\n", rgstr); 28431.72Skamil } else if (strcmp(aux, "intrv") == 0) { 28441.72Skamil rgstr = PTRACE_REG_INTRV(&gpr); 28451.72Skamil DPRINTF("Retrieved %" PRIxREGISTER "\n", rgstr); 28461.72Skamil } else if (strcmp(aux, "setregs") == 0) { 28471.72Skamil DPRINTF("Call SETREGS for the child process\n"); 28481.72Skamil SYSCALL_REQUIRE( 28491.72Skamil ptrace(PT_GETREGS, child, &gpr, 0) != -1); 28501.72Skamil } 28511.72Skamil } 28521.1Skamil#endif 28531.1Skamil 28541.72Skamil#if defined(HAVE_FPREGS) 28551.72Skamil if (strcmp(regset, "fpregs") == 0) { 28561.72Skamil DPRINTF("Call GETFPREGS for the child process\n"); 28571.72Skamil SYSCALL_REQUIRE(ptrace(PT_GETFPREGS, child, &fpr, 0) != -1); 28581.72Skamil 28591.72Skamil if (strcmp(aux, "getfpregs") == 0) { 28601.72Skamil DPRINTF("Retrieved FP registers\n"); 28611.72Skamil } else if (strcmp(aux, "setfpregs") == 0) { 28621.72Skamil DPRINTF("Call SETFPREGS for the child\n"); 28631.72Skamil SYSCALL_REQUIRE( 28641.72Skamil ptrace(PT_SETFPREGS, child, &fpr, 0) != -1); 28651.72Skamil } 28661.1Skamil } 28671.1Skamil#endif 28681.1Skamil 28691.13Schristos DPRINTF("Before resuming the child process where it left off and " 28701.1Skamil "without signal to be sent\n"); 28711.13Schristos SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 28721.1Skamil 28731.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 28741.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 28751.1Skamil 28761.1Skamil validate_status_exited(status, exitval); 28771.1Skamil 28781.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 28791.1Skamil TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 28801.1Skamil} 28811.1Skamil 28821.72Skamil#define ACCESS_REGS(test, regset, aux) \ 28831.72SkamilATF_TC(test); \ 28841.72SkamilATF_TC_HEAD(test, tc) \ 28851.72Skamil{ \ 28861.72Skamil atf_tc_set_md_var(tc, "descr", \ 28871.72Skamil "Verify " regset " with auxiliary operation: " aux); \ 28881.72Skamil} \ 28891.72Skamil \ 28901.72SkamilATF_TC_BODY(test, tc) \ 28911.72Skamil{ \ 28921.72Skamil \ 28931.72Skamil access_regs(regset, aux); \ 28941.1Skamil} 28951.1Skamil#endif 28961.1Skamil 28971.72Skamil#if defined(HAVE_GPREGS) 28981.72SkamilACCESS_REGS(access_regs1, "regs", "none") 28991.72SkamilACCESS_REGS(access_regs2, "regs", "pc") 29001.72SkamilACCESS_REGS(access_regs3, "regs", "set_pc") 29011.72SkamilACCESS_REGS(access_regs4, "regs", "sp") 29021.72SkamilACCESS_REGS(access_regs5, "regs", "intrv") 29031.72SkamilACCESS_REGS(access_regs6, "regs", "setregs") 29041.1Skamil#endif 29051.1Skamil#if defined(HAVE_FPREGS) 29061.72SkamilACCESS_REGS(access_fpregs1, "fpregs", "getfpregs") 29071.72SkamilACCESS_REGS(access_fpregs2, "fpregs", "setfpregs") 29081.1Skamil#endif 29091.1Skamil 29101.72Skamil/// ---------------------------------------------------------------------------- 29111.1Skamil 29121.1Skamil#if defined(PT_STEP) 29131.1Skamilstatic void 29141.2Skamilptrace_step(int N, int setstep) 29151.1Skamil{ 29161.1Skamil const int exitval = 5; 29171.1Skamil const int sigval = SIGSTOP; 29181.1Skamil pid_t child, wpid; 29191.1Skamil#if defined(TWAIT_HAVE_STATUS) 29201.1Skamil int status; 29211.1Skamil#endif 29221.1Skamil int happy; 29231.81Skamil struct ptrace_siginfo info; 29241.1Skamil 29251.1Skamil#if defined(__arm__) 29261.1Skamil /* PT_STEP not supported on arm 32-bit */ 29271.1Skamil atf_tc_expect_fail("PR kern/52119"); 29281.1Skamil#endif 29291.1Skamil 29301.13Schristos DPRINTF("Before forking process PID=%d\n", getpid()); 29311.13Schristos SYSCALL_REQUIRE((child = fork()) != -1); 29321.1Skamil if (child == 0) { 29331.13Schristos DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 29341.1Skamil FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 29351.1Skamil 29361.1Skamil happy = check_happy(999); 29371.1Skamil 29381.13Schristos DPRINTF("Before raising %s from child\n", strsignal(sigval)); 29391.1Skamil FORKEE_ASSERT(raise(sigval) == 0); 29401.1Skamil 29411.1Skamil FORKEE_ASSERT_EQ(happy, check_happy(999)); 29421.1Skamil 29431.13Schristos DPRINTF("Before exiting of the child process\n"); 29441.1Skamil _exit(exitval); 29451.1Skamil } 29461.13Schristos DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 29471.1Skamil 29481.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 29491.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 29501.1Skamil 29511.1Skamil validate_status_stopped(status, sigval); 29521.1Skamil 29531.81Skamil DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 29541.81Skamil SYSCALL_REQUIRE( 29551.81Skamil ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 29561.81Skamil 29571.81Skamil DPRINTF("Before checking siginfo_t\n"); 29581.81Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 29591.81Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 29601.81Skamil 29611.1Skamil while (N --> 0) { 29621.2Skamil if (setstep) { 29631.13Schristos DPRINTF("Before resuming the child process where it " 29641.2Skamil "left off and without signal to be sent (use " 29651.9Skamil "PT_SETSTEP and PT_CONTINUE)\n"); 29661.13Schristos SYSCALL_REQUIRE(ptrace(PT_SETSTEP, child, 0, 0) != -1); 29671.13Schristos SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) 29681.2Skamil != -1); 29691.2Skamil } else { 29701.13Schristos DPRINTF("Before resuming the child process where it " 29711.2Skamil "left off and without signal to be sent (use " 29721.2Skamil "PT_STEP)\n"); 29731.13Schristos SYSCALL_REQUIRE(ptrace(PT_STEP, child, (void *)1, 0) 29741.2Skamil != -1); 29751.2Skamil } 29761.1Skamil 29771.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 29781.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), 29791.1Skamil child); 29801.1Skamil 29811.1Skamil validate_status_stopped(status, SIGTRAP); 29821.2Skamil 29831.81Skamil DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 29841.81Skamil SYSCALL_REQUIRE( 29851.81Skamil ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 29861.81Skamil 29871.81Skamil DPRINTF("Before checking siginfo_t\n"); 29881.81Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); 29891.81Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_TRACE); 29901.81Skamil 29911.2Skamil if (setstep) { 29921.13Schristos SYSCALL_REQUIRE(ptrace(PT_CLEARSTEP, child, 0, 0) != -1); 29931.2Skamil } 29941.1Skamil } 29951.1Skamil 29961.13Schristos DPRINTF("Before resuming the child process where it left off and " 29971.1Skamil "without signal to be sent\n"); 29981.13Schristos SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 29991.1Skamil 30001.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 30011.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 30021.1Skamil 30031.1Skamil validate_status_exited(status, exitval); 30041.1Skamil 30051.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 30061.1Skamil TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 30071.1Skamil} 30081.1Skamil 30091.73Skamil#define PTRACE_STEP(test, N, setstep) \ 30101.73SkamilATF_TC(test); \ 30111.73SkamilATF_TC_HEAD(test, tc) \ 30121.73Skamil{ \ 30131.73Skamil atf_tc_set_md_var(tc, "descr", \ 30141.74Skamil "Verify " #N " (PT_SETSTEP set to: " #setstep ")"); \ 30151.73Skamil} \ 30161.73Skamil \ 30171.73SkamilATF_TC_BODY(test, tc) \ 30181.73Skamil{ \ 30191.73Skamil \ 30201.73Skamil ptrace_step(N, setstep); \ 30211.1Skamil} 30221.1Skamil 30231.73SkamilPTRACE_STEP(step1, 1, 0) 30241.73SkamilPTRACE_STEP(step2, 2, 0) 30251.73SkamilPTRACE_STEP(step3, 3, 0) 30261.73SkamilPTRACE_STEP(step4, 4, 0) 30271.73SkamilPTRACE_STEP(setstep1, 1, 1) 30281.73SkamilPTRACE_STEP(setstep2, 2, 1) 30291.73SkamilPTRACE_STEP(setstep3, 3, 1) 30301.73SkamilPTRACE_STEP(setstep4, 4, 1) 30311.1Skamil#endif 30321.1Skamil 30331.73Skamil/// ---------------------------------------------------------------------------- 30341.1Skamil 30351.75Skamilstatic void 30361.75Skamilptrace_kill(const char *type) 30371.1Skamil{ 30381.75Skamil const int sigval = SIGSTOP; 30391.1Skamil pid_t child, wpid; 30401.1Skamil#if defined(TWAIT_HAVE_STATUS) 30411.1Skamil int status; 30421.1Skamil#endif 30431.1Skamil 30441.13Schristos DPRINTF("Before forking process PID=%d\n", getpid()); 30451.13Schristos SYSCALL_REQUIRE((child = fork()) != -1); 30461.1Skamil if (child == 0) { 30471.13Schristos DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 30481.1Skamil FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 30491.1Skamil 30501.13Schristos DPRINTF("Before raising %s from child\n", strsignal(sigval)); 30511.1Skamil FORKEE_ASSERT(raise(sigval) == 0); 30521.1Skamil 30531.1Skamil /* NOTREACHED */ 30541.1Skamil FORKEE_ASSERTX(0 && 30551.1Skamil "Child should be terminated by a signal from its parent"); 30561.1Skamil } 30571.13Schristos DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 30581.1Skamil 30591.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 30601.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 30611.1Skamil 30621.1Skamil validate_status_stopped(status, sigval); 30631.1Skamil 30641.75Skamil DPRINTF("Before killing the child process with %s\n", type); 30651.75Skamil if (strcmp(type, "ptrace(PT_KILL)") == 0) { 30661.75Skamil SYSCALL_REQUIRE(ptrace(PT_KILL, child, (void*)1, 0) != -1); 30671.75Skamil } else if (strcmp(type, "kill(SIGKILL)") == 0) { 30681.75Skamil kill(child, SIGKILL); 30691.75Skamil } else if (strcmp(type, "killpg(SIGKILL)") == 0) { 30701.75Skamil setpgid(child, 0); 30711.75Skamil killpg(getpgid(child), SIGKILL); 30721.75Skamil } 30731.1Skamil 30741.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 30751.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 30761.1Skamil 30771.75Skamil validate_status_signaled(status, SIGKILL, 0); 30781.1Skamil 30791.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 30801.1Skamil TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 30811.1Skamil} 30821.1Skamil 30831.75Skamil#define PTRACE_KILL(test, type) \ 30841.75SkamilATF_TC(test); \ 30851.75SkamilATF_TC_HEAD(test, tc) \ 30861.75Skamil{ \ 30871.75Skamil atf_tc_set_md_var(tc, "descr", \ 30881.75Skamil "Verify killing the child with " type); \ 30891.75Skamil} \ 30901.75Skamil \ 30911.75SkamilATF_TC_BODY(test, tc) \ 30921.75Skamil{ \ 30931.75Skamil \ 30941.75Skamil ptrace_kill(type); \ 30951.1Skamil} 30961.1Skamil 30971.75Skamil// PT_CONTINUE with SIGKILL is covered by traceme_sendsignal_simple1 30981.75SkamilPTRACE_KILL(kill1, "ptrace(PT_KILL)") 30991.75SkamilPTRACE_KILL(kill2, "kill(SIGKILL)") 31001.75SkamilPTRACE_KILL(kill3, "killpg(SIGKILL)") 31011.1Skamil 31021.75Skamil/// ---------------------------------------------------------------------------- 31031.1Skamil 31041.77Skamilstatic void 31051.77Skamiltraceme_lwpinfo(const int threads) 31061.1Skamil{ 31071.1Skamil const int sigval = SIGSTOP; 31081.77Skamil const int sigval2 = SIGINT; 31091.1Skamil pid_t child, wpid; 31101.1Skamil#if defined(TWAIT_HAVE_STATUS) 31111.1Skamil int status; 31121.1Skamil#endif 31131.77Skamil struct ptrace_lwpinfo lwp = {0, 0}; 31141.77Skamil struct ptrace_siginfo info; 31151.77Skamil 31161.77Skamil /* Maximum number of supported threads in this test */ 31171.77Skamil pthread_t t[3]; 31181.77Skamil int n, rv; 31191.77Skamil 31201.77Skamil ATF_REQUIRE((int)__arraycount(t) >= threads); 31211.1Skamil 31221.13Schristos DPRINTF("Before forking process PID=%d\n", getpid()); 31231.13Schristos SYSCALL_REQUIRE((child = fork()) != -1); 31241.1Skamil if (child == 0) { 31251.13Schristos DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 31261.1Skamil FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 31271.1Skamil 31281.13Schristos DPRINTF("Before raising %s from child\n", strsignal(sigval)); 31291.1Skamil FORKEE_ASSERT(raise(sigval) == 0); 31301.1Skamil 31311.77Skamil for (n = 0; n < threads; n++) { 31321.77Skamil rv = pthread_create(&t[n], NULL, infinite_thread, NULL); 31331.77Skamil FORKEE_ASSERT(rv == 0); 31341.77Skamil } 31351.77Skamil 31361.77Skamil DPRINTF("Before raising %s from child\n", strsignal(sigval2)); 31371.77Skamil FORKEE_ASSERT(raise(sigval2) == 0); 31381.77Skamil 31391.77Skamil /* NOTREACHED */ 31401.77Skamil FORKEE_ASSERTX(0 && "Not reached"); 31411.1Skamil } 31421.13Schristos DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 31431.1Skamil 31441.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 31451.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 31461.1Skamil 31471.1Skamil validate_status_stopped(status, sigval); 31481.1Skamil 31491.77Skamil DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child"); 31501.77Skamil SYSCALL_REQUIRE( 31511.77Skamil ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 31521.77Skamil 31531.77Skamil DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 31541.77Skamil DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 31551.77Skamil info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 31561.77Skamil info.psi_siginfo.si_errno); 31571.77Skamil 31581.77Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 31591.77Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 31601.77Skamil 31611.13Schristos DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n"); 31621.77Skamil SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &lwp, sizeof(lwp)) != -1); 31631.1Skamil 31641.77Skamil DPRINTF("Assert that there exists a single thread only\n"); 31651.77Skamil ATF_REQUIRE(lwp.pl_lwpid > 0); 31661.1Skamil 31671.13Schristos DPRINTF("Assert that lwp thread %d received event PL_EVENT_SIGNAL\n", 31681.77Skamil lwp.pl_lwpid); 31691.77Skamil FORKEE_ASSERT_EQ(lwp.pl_event, PL_EVENT_SIGNAL); 31701.1Skamil 31711.13Schristos DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n"); 31721.77Skamil SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &lwp, sizeof(lwp)) != -1); 31731.1Skamil 31741.77Skamil DPRINTF("Assert that there exists a single thread only\n"); 31751.77Skamil ATF_REQUIRE_EQ(lwp.pl_lwpid, 0); 31761.1Skamil 31771.13Schristos DPRINTF("Before resuming the child process where it left off and " 31781.1Skamil "without signal to be sent\n"); 31791.13Schristos SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 31801.1Skamil 31811.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 31821.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 31831.1Skamil 31841.77Skamil validate_status_stopped(status, sigval2); 31851.77Skamil 31861.77Skamil DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child"); 31871.77Skamil SYSCALL_REQUIRE( 31881.77Skamil ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 31891.77Skamil 31901.77Skamil DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 31911.77Skamil DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 31921.77Skamil info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 31931.77Skamil info.psi_siginfo.si_errno); 31941.77Skamil 31951.77Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval2); 31961.77Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 31971.77Skamil 31981.77Skamil memset(&lwp, 0, sizeof(lwp)); 31991.77Skamil 32001.77Skamil for (n = 0; n <= threads; n++) { 32011.77Skamil DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n"); 32021.77Skamil SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &lwp, sizeof(lwp)) != -1); 32031.77Skamil DPRINTF("LWP=%d\n", lwp.pl_lwpid); 32041.77Skamil 32051.77Skamil DPRINTF("Assert that the thread exists\n"); 32061.77Skamil ATF_REQUIRE(lwp.pl_lwpid > 0); 32071.77Skamil 32081.77Skamil DPRINTF("Assert that lwp thread %d received expected event\n", 32091.77Skamil lwp.pl_lwpid); 32101.77Skamil FORKEE_ASSERT_EQ(lwp.pl_event, info.psi_lwpid == lwp.pl_lwpid ? 32111.77Skamil PL_EVENT_SIGNAL : PL_EVENT_NONE); 32121.77Skamil } 32131.77Skamil DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n"); 32141.77Skamil SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &lwp, sizeof(lwp)) != -1); 32151.77Skamil DPRINTF("LWP=%d\n", lwp.pl_lwpid); 32161.77Skamil 32171.77Skamil DPRINTF("Assert that there are no more threads\n"); 32181.77Skamil ATF_REQUIRE_EQ(lwp.pl_lwpid, 0); 32191.77Skamil 32201.77Skamil DPRINTF("Before resuming the child process where it left off and " 32211.77Skamil "without signal to be sent\n"); 32221.77Skamil SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, SIGKILL) != -1); 32231.77Skamil 32241.77Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 32251.77Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 32261.77Skamil 32271.77Skamil validate_status_signaled(status, SIGKILL, 0); 32281.1Skamil 32291.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 32301.1Skamil TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 32311.1Skamil} 32321.1Skamil 32331.77Skamil#define TRACEME_LWPINFO(test, threads) \ 32341.77SkamilATF_TC(test); \ 32351.77SkamilATF_TC_HEAD(test, tc) \ 32361.77Skamil{ \ 32371.77Skamil atf_tc_set_md_var(tc, "descr", \ 32381.77Skamil "Verify LWPINFO with the child with " #threads \ 32391.77Skamil " spawned extra threads"); \ 32401.77Skamil} \ 32411.77Skamil \ 32421.77SkamilATF_TC_BODY(test, tc) \ 32431.77Skamil{ \ 32441.77Skamil \ 32451.77Skamil traceme_lwpinfo(threads); \ 32461.1Skamil} 32471.1Skamil 32481.77SkamilTRACEME_LWPINFO(traceme_lwpinfo0, 0) 32491.77SkamilTRACEME_LWPINFO(traceme_lwpinfo1, 1) 32501.77SkamilTRACEME_LWPINFO(traceme_lwpinfo2, 2) 32511.77SkamilTRACEME_LWPINFO(traceme_lwpinfo3, 3) 32521.77Skamil 32531.77Skamil/// ---------------------------------------------------------------------------- 32541.77Skamil 32551.77Skamil#if defined(TWAIT_HAVE_PID) 32561.77Skamilstatic void 32571.77Skamilattach_lwpinfo(const int threads) 32581.1Skamil{ 32591.77Skamil const int sigval = SIGINT; 32601.1Skamil struct msg_fds parent_tracee, parent_tracer; 32611.1Skamil const int exitval_tracer = 10; 32621.1Skamil pid_t tracee, tracer, wpid; 32631.1Skamil uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */ 32641.1Skamil#if defined(TWAIT_HAVE_STATUS) 32651.1Skamil int status; 32661.1Skamil#endif 32671.77Skamil struct ptrace_lwpinfo lwp = {0, 0}; 32681.77Skamil struct ptrace_siginfo info; 32691.77Skamil 32701.77Skamil /* Maximum number of supported threads in this test */ 32711.77Skamil pthread_t t[3]; 32721.77Skamil int n, rv; 32731.1Skamil 32741.13Schristos DPRINTF("Spawn tracee\n"); 32751.13Schristos SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0); 32761.13Schristos SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0); 32771.1Skamil tracee = atf_utils_fork(); 32781.1Skamil if (tracee == 0) { 32791.1Skamil /* Wait for message from the parent */ 32801.1Skamil CHILD_TO_PARENT("tracee ready", parent_tracee, msg); 32811.1Skamil 32821.77Skamil CHILD_FROM_PARENT("spawn threads", parent_tracee, msg); 32831.77Skamil 32841.77Skamil for (n = 0; n < threads; n++) { 32851.77Skamil rv = pthread_create(&t[n], NULL, infinite_thread, NULL); 32861.77Skamil FORKEE_ASSERT(rv == 0); 32871.77Skamil } 32881.77Skamil 32891.77Skamil CHILD_TO_PARENT("tracee exit", parent_tracee, msg); 32901.77Skamil 32911.77Skamil DPRINTF("Before raising %s from child\n", strsignal(sigval)); 32921.77Skamil FORKEE_ASSERT(raise(sigval) == 0); 32931.77Skamil 32941.77Skamil /* NOTREACHED */ 32951.77Skamil FORKEE_ASSERTX(0 && "Not reached"); 32961.1Skamil } 32971.1Skamil PARENT_FROM_CHILD("tracee ready", parent_tracee, msg); 32981.1Skamil 32991.13Schristos DPRINTF("Spawn debugger\n"); 33001.1Skamil tracer = atf_utils_fork(); 33011.1Skamil if (tracer == 0) { 33021.1Skamil /* No IPC to communicate with the child */ 33031.13Schristos DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid()); 33041.1Skamil FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1); 33051.1Skamil 33061.1Skamil /* Wait for tracee and assert that it was stopped w/ SIGSTOP */ 33071.1Skamil FORKEE_REQUIRE_SUCCESS( 33081.1Skamil wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 33091.1Skamil 33101.1Skamil forkee_status_stopped(status, SIGSTOP); 33111.1Skamil 33121.77Skamil DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for " 33131.77Skamil "tracee"); 33141.77Skamil FORKEE_ASSERT( 33151.77Skamil ptrace(PT_GET_SIGINFO, tracee, &info, sizeof(info)) != -1); 33161.77Skamil 33171.77Skamil DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 33181.77Skamil DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 33191.77Skamil "si_errno=%#x\n", 33201.77Skamil info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 33211.77Skamil info.psi_siginfo.si_errno); 33221.77Skamil 33231.77Skamil FORKEE_ASSERT_EQ(info.psi_siginfo.si_signo, SIGSTOP); 33241.77Skamil FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, SI_USER); 33251.77Skamil 33261.13Schristos DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n"); 33271.77Skamil FORKEE_ASSERT(ptrace(PT_LWPINFO, tracee, &lwp, sizeof(lwp)) 33281.1Skamil != -1); 33291.1Skamil 33301.13Schristos DPRINTF("Assert that there exists a thread\n"); 33311.77Skamil FORKEE_ASSERTX(lwp.pl_lwpid > 0); 33321.1Skamil 33331.13Schristos DPRINTF("Assert that lwp thread %d received event " 33341.77Skamil "PL_EVENT_SIGNAL\n", lwp.pl_lwpid); 33351.77Skamil FORKEE_ASSERT_EQ(lwp.pl_event, PL_EVENT_SIGNAL); 33361.1Skamil 33371.77Skamil DPRINTF("Before calling ptrace(2) with PT_LWPINFO for " 33381.77Skamil "tracee\n"); 33391.77Skamil FORKEE_ASSERT(ptrace(PT_LWPINFO, tracee, &lwp, sizeof(lwp)) 33401.1Skamil != -1); 33411.1Skamil 33421.77Skamil DPRINTF("Assert that there are no more lwp threads in " 33431.77Skamil "tracee\n"); 33441.77Skamil FORKEE_ASSERT_EQ(lwp.pl_lwpid, 0); 33451.1Skamil 33461.1Skamil /* Resume tracee with PT_CONTINUE */ 33471.1Skamil FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1); 33481.1Skamil 33491.1Skamil /* Inform parent that tracer has attached to tracee */ 33501.1Skamil CHILD_TO_PARENT("tracer ready", parent_tracer, msg); 33511.77Skamil 33521.1Skamil /* Wait for parent */ 33531.1Skamil CHILD_FROM_PARENT("tracer wait", parent_tracer, msg); 33541.1Skamil 33551.77Skamil /* Wait for tracee and assert that it raised a signal */ 33561.77Skamil FORKEE_REQUIRE_SUCCESS( 33571.77Skamil wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 33581.77Skamil 33591.77Skamil forkee_status_stopped(status, SIGINT); 33601.77Skamil 33611.77Skamil DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for " 33621.77Skamil "child"); 33631.77Skamil FORKEE_ASSERT( 33641.77Skamil ptrace(PT_GET_SIGINFO, tracee, &info, sizeof(info)) != -1); 33651.77Skamil 33661.77Skamil DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 33671.77Skamil DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 33681.77Skamil "si_errno=%#x\n", 33691.77Skamil info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 33701.77Skamil info.psi_siginfo.si_errno); 33711.77Skamil 33721.77Skamil FORKEE_ASSERT_EQ(info.psi_siginfo.si_signo, sigval); 33731.77Skamil FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, SI_LWP); 33741.77Skamil 33751.77Skamil memset(&lwp, 0, sizeof(lwp)); 33761.77Skamil 33771.77Skamil for (n = 0; n <= threads; n++) { 33781.77Skamil DPRINTF("Before calling ptrace(2) with PT_LWPINFO for " 33791.77Skamil "child\n"); 33801.77Skamil FORKEE_ASSERT(ptrace(PT_LWPINFO, tracee, &lwp, 33811.77Skamil sizeof(lwp)) != -1); 33821.77Skamil DPRINTF("LWP=%d\n", lwp.pl_lwpid); 33831.77Skamil 33841.77Skamil DPRINTF("Assert that the thread exists\n"); 33851.77Skamil FORKEE_ASSERT(lwp.pl_lwpid > 0); 33861.77Skamil 33871.77Skamil DPRINTF("Assert that lwp thread %d received expected " 33881.77Skamil "event\n", lwp.pl_lwpid); 33891.77Skamil FORKEE_ASSERT_EQ(lwp.pl_event, 33901.77Skamil info.psi_lwpid == lwp.pl_lwpid ? 33911.77Skamil PL_EVENT_SIGNAL : PL_EVENT_NONE); 33921.77Skamil } 33931.77Skamil DPRINTF("Before calling ptrace(2) with PT_LWPINFO for " 33941.77Skamil "tracee\n"); 33951.77Skamil FORKEE_ASSERT(ptrace(PT_LWPINFO, tracee, &lwp, sizeof(lwp)) 33961.77Skamil != -1); 33971.77Skamil DPRINTF("LWP=%d\n", lwp.pl_lwpid); 33981.77Skamil 33991.77Skamil DPRINTF("Assert that there are no more threads\n"); 34001.77Skamil FORKEE_ASSERT_EQ(lwp.pl_lwpid, 0); 34011.77Skamil 34021.77Skamil DPRINTF("Before resuming the child process where it left off " 34031.77Skamil "and without signal to be sent\n"); 34041.77Skamil FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, SIGKILL) 34051.77Skamil != -1); 34061.77Skamil 34071.1Skamil /* Wait for tracee and assert that it exited */ 34081.1Skamil FORKEE_REQUIRE_SUCCESS( 34091.1Skamil wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 34101.1Skamil 34111.77Skamil forkee_status_signaled(status, SIGKILL, 0); 34121.1Skamil 34131.13Schristos DPRINTF("Before exiting of the tracer process\n"); 34141.1Skamil _exit(exitval_tracer); 34151.1Skamil } 34161.1Skamil 34171.13Schristos DPRINTF("Wait for the tracer to attach to the tracee\n"); 34181.1Skamil PARENT_FROM_CHILD("tracer ready", parent_tracer, msg); 34191.1Skamil 34201.77Skamil DPRINTF("Resume the tracee and spawn threads\n"); 34211.77Skamil PARENT_TO_CHILD("spawn threads", parent_tracee, msg); 34221.77Skamil 34231.13Schristos DPRINTF("Resume the tracee and let it exit\n"); 34241.77Skamil PARENT_FROM_CHILD("tracee exit", parent_tracee, msg); 34251.1Skamil 34261.77Skamil DPRINTF("Resume the tracer and let it detect multiple threads\n"); 34271.1Skamil PARENT_TO_CHILD("tracer wait", parent_tracer, msg); 34281.1Skamil 34291.13Schristos DPRINTF("Wait for tracer to finish its job and exit - calling %s()\n", 34301.1Skamil TWAIT_FNAME); 34311.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0), 34321.1Skamil tracer); 34331.1Skamil 34341.1Skamil validate_status_exited(status, exitval_tracer); 34351.1Skamil 34361.13Schristos DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n", 34371.1Skamil TWAIT_FNAME); 34381.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 34391.1Skamil tracee); 34401.1Skamil 34411.77Skamil validate_status_signaled(status, SIGKILL, 0); 34421.1Skamil 34431.1Skamil msg_close(&parent_tracer); 34441.1Skamil msg_close(&parent_tracee); 34451.1Skamil} 34461.77Skamil 34471.77Skamil#define ATTACH_LWPINFO(test, threads) \ 34481.77SkamilATF_TC(test); \ 34491.77SkamilATF_TC_HEAD(test, tc) \ 34501.77Skamil{ \ 34511.77Skamil atf_tc_set_md_var(tc, "descr", \ 34521.77Skamil "Verify LWPINFO with the child with " #threads \ 34531.77Skamil " spawned extra threads (tracer is not the original " \ 34541.77Skamil "parent)"); \ 34551.77Skamil} \ 34561.77Skamil \ 34571.77SkamilATF_TC_BODY(test, tc) \ 34581.77Skamil{ \ 34591.77Skamil \ 34601.77Skamil attach_lwpinfo(threads); \ 34611.77Skamil} 34621.77Skamil 34631.77SkamilATTACH_LWPINFO(attach_lwpinfo0, 0) 34641.77SkamilATTACH_LWPINFO(attach_lwpinfo1, 1) 34651.77SkamilATTACH_LWPINFO(attach_lwpinfo2, 2) 34661.77SkamilATTACH_LWPINFO(attach_lwpinfo3, 3) 34671.1Skamil#endif 34681.1Skamil 34691.77Skamil/// ---------------------------------------------------------------------------- 34701.77Skamil 34711.1Skamilstatic void 34721.79Skamilptrace_siginfo(bool faked, void (*sah)(int a, siginfo_t *b, void *c), int *signal_caught) 34731.1Skamil{ 34741.1Skamil const int exitval = 5; 34751.1Skamil const int sigval = SIGINT; 34761.1Skamil const int sigfaked = SIGTRAP; 34771.1Skamil const int sicodefaked = TRAP_BRKPT; 34781.1Skamil pid_t child, wpid; 34791.1Skamil struct sigaction sa; 34801.1Skamil#if defined(TWAIT_HAVE_STATUS) 34811.1Skamil int status; 34821.1Skamil#endif 34831.1Skamil struct ptrace_siginfo info; 34841.1Skamil memset(&info, 0, sizeof(info)); 34851.1Skamil 34861.13Schristos DPRINTF("Before forking process PID=%d\n", getpid()); 34871.13Schristos SYSCALL_REQUIRE((child = fork()) != -1); 34881.1Skamil if (child == 0) { 34891.13Schristos DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 34901.1Skamil FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 34911.1Skamil 34921.79Skamil sa.sa_sigaction = sah; 34931.1Skamil sa.sa_flags = SA_SIGINFO; 34941.1Skamil sigemptyset(&sa.sa_mask); 34951.1Skamil 34961.79Skamil FORKEE_ASSERT(sigaction(faked ? sigfaked : sigval, &sa, NULL) 34971.79Skamil != -1); 34981.1Skamil 34991.13Schristos DPRINTF("Before raising %s from child\n", strsignal(sigval)); 35001.1Skamil FORKEE_ASSERT(raise(sigval) == 0); 35011.1Skamil 35021.79Skamil FORKEE_ASSERT_EQ(*signal_caught, 1); 35031.1Skamil 35041.13Schristos DPRINTF("Before exiting of the child process\n"); 35051.1Skamil _exit(exitval); 35061.1Skamil } 35071.13Schristos DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 35081.1Skamil 35091.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 35101.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 35111.1Skamil 35121.1Skamil validate_status_stopped(status, sigval); 35131.1Skamil 35141.13Schristos DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 35151.61Skre SYSCALL_REQUIRE( 35161.61Skre ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 35171.1Skamil 35181.13Schristos DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 35191.13Schristos DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 35201.1Skamil info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 35211.1Skamil info.psi_siginfo.si_errno); 35221.1Skamil 35231.79Skamil if (faked) { 35241.79Skamil DPRINTF("Before setting new faked signal to signo=%d " 35251.79Skamil "si_code=%d\n", sigfaked, sicodefaked); 35261.79Skamil info.psi_siginfo.si_signo = sigfaked; 35271.79Skamil info.psi_siginfo.si_code = sicodefaked; 35281.79Skamil } 35291.1Skamil 35301.13Schristos DPRINTF("Before calling ptrace(2) with PT_SET_SIGINFO for child\n"); 35311.61Skre SYSCALL_REQUIRE( 35321.61Skre ptrace(PT_SET_SIGINFO, child, &info, sizeof(info)) != -1); 35331.1Skamil 35341.79Skamil if (faked) { 35351.79Skamil DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for " 35361.79Skamil "child\n"); 35371.79Skamil SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, 35381.79Skamil sizeof(info)) != -1); 35391.1Skamil 35401.79Skamil DPRINTF("Before checking siginfo_t\n"); 35411.79Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigfaked); 35421.79Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_code, sicodefaked); 35431.79Skamil } 35441.1Skamil 35451.13Schristos DPRINTF("Before resuming the child process where it left off and " 35461.1Skamil "without signal to be sent\n"); 35471.79Skamil SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 35481.79Skamil faked ? sigfaked : sigval) != -1); 35491.1Skamil 35501.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 35511.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 35521.1Skamil 35531.1Skamil validate_status_exited(status, exitval); 35541.1Skamil 35551.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 35561.1Skamil TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 35571.1Skamil} 35581.1Skamil 35591.79Skamil#define PTRACE_SIGINFO(test, faked) \ 35601.79SkamilATF_TC(test); \ 35611.79SkamilATF_TC_HEAD(test, tc) \ 35621.79Skamil{ \ 35631.79Skamil atf_tc_set_md_var(tc, "descr", \ 35641.79Skamil "Verify basic PT_GET_SIGINFO and PT_SET_SIGINFO calls" \ 35651.79Skamil "with%s setting signal to new value", faked ? "" : "out"); \ 35661.79Skamil} \ 35671.79Skamil \ 35681.79Skamilstatic int test##_caught = 0; \ 35691.79Skamil \ 35701.79Skamilstatic void \ 35711.79Skamiltest##_sighandler(int sig, siginfo_t *info, void *ctx) \ 35721.79Skamil{ \ 35731.79Skamil if (faked) { \ 35741.79Skamil FORKEE_ASSERT_EQ(sig, SIGTRAP); \ 35751.79Skamil FORKEE_ASSERT_EQ(info->si_signo, SIGTRAP); \ 35761.79Skamil FORKEE_ASSERT_EQ(info->si_code, TRAP_BRKPT); \ 35771.79Skamil } else { \ 35781.79Skamil FORKEE_ASSERT_EQ(sig, SIGINT); \ 35791.79Skamil FORKEE_ASSERT_EQ(info->si_signo, SIGINT); \ 35801.79Skamil FORKEE_ASSERT_EQ(info->si_code, SI_LWP); \ 35811.79Skamil } \ 35821.79Skamil \ 35831.79Skamil ++ test##_caught; \ 35841.79Skamil} \ 35851.79Skamil \ 35861.79SkamilATF_TC_BODY(test, tc) \ 35871.79Skamil{ \ 35881.79Skamil \ 35891.79Skamil ptrace_siginfo(faked, test##_sighandler, & test##_caught); \ 35901.79Skamil} 35911.79Skamil 35921.79SkamilPTRACE_SIGINFO(siginfo_set_unmodified, false) 35931.79SkamilPTRACE_SIGINFO(siginfo_set_faked, true) 35941.79Skamil 35951.79Skamil/// ---------------------------------------------------------------------------- 35961.79Skamil 35971.82SkamilATF_TC(traceme_exec); 35981.82SkamilATF_TC_HEAD(traceme_exec, tc) 35991.1Skamil{ 36001.1Skamil atf_tc_set_md_var(tc, "descr", 36011.1Skamil "Detect SIGTRAP TRAP_EXEC from tracee"); 36021.1Skamil} 36031.1Skamil 36041.82SkamilATF_TC_BODY(traceme_exec, tc) 36051.1Skamil{ 36061.1Skamil const int sigval = SIGTRAP; 36071.1Skamil pid_t child, wpid; 36081.1Skamil#if defined(TWAIT_HAVE_STATUS) 36091.1Skamil int status; 36101.1Skamil#endif 36111.1Skamil 36121.1Skamil struct ptrace_siginfo info; 36131.1Skamil memset(&info, 0, sizeof(info)); 36141.1Skamil 36151.13Schristos DPRINTF("Before forking process PID=%d\n", getpid()); 36161.13Schristos SYSCALL_REQUIRE((child = fork()) != -1); 36171.1Skamil if (child == 0) { 36181.13Schristos DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 36191.1Skamil FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 36201.1Skamil 36211.13Schristos DPRINTF("Before calling execve(2) from child\n"); 36221.1Skamil execlp("/bin/echo", "/bin/echo", NULL); 36231.1Skamil 36241.1Skamil FORKEE_ASSERT(0 && "Not reached"); 36251.1Skamil } 36261.13Schristos DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 36271.1Skamil 36281.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 36291.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 36301.1Skamil 36311.1Skamil validate_status_stopped(status, sigval); 36321.1Skamil 36331.13Schristos DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 36341.61Skre SYSCALL_REQUIRE( 36351.61Skre ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 36361.1Skamil 36371.13Schristos DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 36381.13Schristos DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 36391.1Skamil info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 36401.1Skamil info.psi_siginfo.si_errno); 36411.1Skamil 36421.1Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 36431.1Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_EXEC); 36441.1Skamil 36451.13Schristos DPRINTF("Before resuming the child process where it left off and " 36461.1Skamil "without signal to be sent\n"); 36471.13Schristos SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 36481.1Skamil 36491.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 36501.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 36511.1Skamil 36521.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 36531.1Skamil TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 36541.1Skamil} 36551.1Skamil 36561.82Skamil/// ---------------------------------------------------------------------------- 36571.82Skamil 36581.83Skamilstatic volatile int done; 36591.1Skamil 36601.83Skamilstatic void * 36611.83Skamiltrace_threads_cb(void *arg __unused) 36621.1Skamil{ 36631.1Skamil 36641.83Skamil done++; 36651.83Skamil 36661.83Skamil while (done < 3) 36671.83Skamil continue; 36681.83Skamil 36691.83Skamil return NULL; 36701.1Skamil} 36711.1Skamil 36721.83Skamilstatic void 36731.83Skamiltrace_threads(bool trace_create, bool trace_exit) 36741.1Skamil{ 36751.1Skamil const int sigval = SIGSTOP; 36761.1Skamil pid_t child, wpid; 36771.1Skamil#if defined(TWAIT_HAVE_STATUS) 36781.1Skamil int status; 36791.1Skamil#endif 36801.1Skamil ptrace_state_t state; 36811.1Skamil const int slen = sizeof(state); 36821.1Skamil ptrace_event_t event; 36831.1Skamil const int elen = sizeof(event); 36841.83Skamil struct ptrace_siginfo info; 36851.83Skamil 36861.83Skamil pthread_t t[3]; 36871.83Skamil int rv; 36881.83Skamil size_t n; 36891.1Skamil lwpid_t lid; 36901.83Skamil 36911.83Skamil /* Track created and exited threads */ 36921.83Skamil bool traced_lwps[__arraycount(t)]; 36931.83Skamil 36941.83Skamil atf_tc_skip("PR kern/51995"); 36951.1Skamil 36961.13Schristos DPRINTF("Before forking process PID=%d\n", getpid()); 36971.13Schristos SYSCALL_REQUIRE((child = fork()) != -1); 36981.1Skamil if (child == 0) { 36991.13Schristos DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 37001.1Skamil FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 37011.1Skamil 37021.13Schristos DPRINTF("Before raising %s from child\n", strsignal(sigval)); 37031.1Skamil FORKEE_ASSERT(raise(sigval) == 0); 37041.1Skamil 37051.83Skamil for (n = 0; n < __arraycount(t); n++) { 37061.83Skamil rv = pthread_create(&t[n], NULL, trace_threads_cb, 37071.83Skamil NULL); 37081.83Skamil FORKEE_ASSERT(rv == 0); 37091.83Skamil } 37101.1Skamil 37111.83Skamil for (n = 0; n < __arraycount(t); n++) { 37121.83Skamil rv = pthread_join(t[n], NULL); 37131.83Skamil FORKEE_ASSERT(rv == 0); 37141.83Skamil } 37151.1Skamil 37161.83Skamil /* 37171.83Skamil * There is race between _exit() and pthread_join() detaching 37181.83Skamil * a thread. For simplicity kill the process after detecting 37191.83Skamil * LWP events. 37201.83Skamil */ 37211.83Skamil while (true) 37221.83Skamil continue; 37231.1Skamil 37241.83Skamil FORKEE_ASSERT(0 && "Not reached"); 37251.1Skamil } 37261.13Schristos DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 37271.1Skamil 37281.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 37291.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 37301.1Skamil 37311.1Skamil validate_status_stopped(status, sigval); 37321.1Skamil 37331.83Skamil DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 37341.83Skamil SYSCALL_REQUIRE( 37351.83Skamil ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 37361.1Skamil 37371.83Skamil DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 37381.83Skamil DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 37391.83Skamil info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 37401.83Skamil info.psi_siginfo.si_errno); 37411.1Skamil 37421.83Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 37431.83Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 37441.1Skamil 37451.83Skamil DPRINTF("Set LWP event mask for the child %d\n", child); 37461.83Skamil memset(&event, 0, sizeof(event)); 37471.83Skamil if (trace_create) 37481.83Skamil event.pe_set_event |= PTRACE_LWP_CREATE; 37491.83Skamil if (trace_exit) 37501.83Skamil event.pe_set_event |= PTRACE_LWP_EXIT; 37511.83Skamil SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); 37521.1Skamil 37531.13Schristos DPRINTF("Before resuming the child process where it left off and " 37541.1Skamil "without signal to be sent\n"); 37551.13Schristos SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 37561.1Skamil 37571.83Skamil memset(traced_lwps, 0, sizeof(traced_lwps)); 37581.1Skamil 37591.83Skamil for (n = 0; n < (trace_create ? __arraycount(t) : 0); n++) { 37601.83Skamil DPRINTF("Before calling %s() for the child - expected stopped " 37611.83Skamil "SIGTRAP\n", TWAIT_FNAME); 37621.83Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), 37631.83Skamil child); 37641.1Skamil 37651.83Skamil validate_status_stopped(status, SIGTRAP); 37661.1Skamil 37671.83Skamil DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for " 37681.83Skamil "child\n"); 37691.83Skamil SYSCALL_REQUIRE( 37701.83Skamil ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 37711.1Skamil 37721.83Skamil DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 37731.83Skamil DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 37741.83Skamil "si_errno=%#x\n", 37751.83Skamil info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 37761.83Skamil info.psi_siginfo.si_errno); 37771.1Skamil 37781.83Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); 37791.83Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_LWP); 37801.1Skamil 37811.83Skamil SYSCALL_REQUIRE( 37821.83Skamil ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 37831.1Skamil 37841.83Skamil ATF_REQUIRE_EQ_MSG(state.pe_report_event, PTRACE_LWP_CREATE, 37851.83Skamil "%d != %d", state.pe_report_event, PTRACE_LWP_CREATE); 37861.1Skamil 37871.83Skamil lid = state.pe_lwp; 37881.83Skamil DPRINTF("Reported PTRACE_LWP_CREATE event with lid %d\n", lid); 37891.1Skamil 37901.83Skamil traced_lwps[lid - 1] = true; 37911.1Skamil 37921.83Skamil DPRINTF("Before resuming the child process where it left off " 37931.83Skamil "and without signal to be sent\n"); 37941.83Skamil SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 37951.83Skamil } 37961.1Skamil 37971.83Skamil for (n = 0; n < (trace_exit ? __arraycount(t) : 0); n++) { 37981.83Skamil DPRINTF("Before calling %s() for the child - expected stopped " 37991.83Skamil "SIGTRAP\n", TWAIT_FNAME); 38001.83Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), 38011.83Skamil child); 38021.1Skamil 38031.83Skamil validate_status_stopped(status, SIGTRAP); 38041.1Skamil 38051.83Skamil DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for " 38061.83Skamil "child\n"); 38071.83Skamil SYSCALL_REQUIRE( 38081.83Skamil ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 38091.1Skamil 38101.83Skamil DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 38111.83Skamil DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 38121.83Skamil "si_errno=%#x\n", 38131.83Skamil info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 38141.83Skamil info.psi_siginfo.si_errno); 38151.1Skamil 38161.83Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); 38171.83Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_LWP); 38181.1Skamil 38191.83Skamil SYSCALL_REQUIRE( 38201.83Skamil ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 38211.1Skamil 38221.83Skamil ATF_REQUIRE_EQ_MSG(state.pe_report_event, PTRACE_LWP_EXIT, 38231.83Skamil "%d != %d", state.pe_report_event, PTRACE_LWP_EXIT); 38241.1Skamil 38251.83Skamil lid = state.pe_lwp; 38261.83Skamil DPRINTF("Reported PTRACE_LWP_EXIT event with lid %d\n", lid); 38271.1Skamil 38281.83Skamil if (trace_create) { 38291.83Skamil ATF_REQUIRE(traced_lwps[lid - 1] == true); 38301.83Skamil traced_lwps[lid - 1] = false; 38311.83Skamil } 38321.1Skamil 38331.83Skamil DPRINTF("Before resuming the child process where it left off " 38341.83Skamil "and without signal to be sent\n"); 38351.83Skamil SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 38361.83Skamil } 38371.1Skamil 38381.83Skamil kill(child, SIGKILL); 38391.1Skamil 38401.13Schristos DPRINTF("Before calling %s() for the child - expected exited\n", 38411.1Skamil TWAIT_FNAME); 38421.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 38431.1Skamil 38441.83Skamil validate_status_signaled(status, SIGKILL, 0); 38451.1Skamil 38461.13Schristos DPRINTF("Before calling %s() for the child - expected no process\n", 38471.1Skamil TWAIT_FNAME); 38481.1Skamil TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 38491.1Skamil} 38501.1Skamil 38511.83Skamil#define TRACE_THREADS(test, trace_create, trace_exit) \ 38521.83SkamilATF_TC(test); \ 38531.83SkamilATF_TC_HEAD(test, tc) \ 38541.83Skamil{ \ 38551.83Skamil atf_tc_set_md_var(tc, "descr", \ 38561.83Skamil "Verify spawning threads with%s tracing LWP create and" \ 38571.83Skamil "with%s tracing LWP exit", trace_create ? "" : "out", \ 38581.83Skamil trace_exit ? "" : "out"); \ 38591.83Skamil} \ 38601.83Skamil \ 38611.83SkamilATF_TC_BODY(test, tc) \ 38621.83Skamil{ \ 38631.83Skamil \ 38641.83Skamil trace_threads(trace_create, trace_exit); \ 38651.83Skamil} 38661.83Skamil 38671.83SkamilTRACE_THREADS(trace_thread1, false, false) 38681.83SkamilTRACE_THREADS(trace_thread2, false, true) 38691.83SkamilTRACE_THREADS(trace_thread3, true, false) 38701.83SkamilTRACE_THREADS(trace_thread4, true, true) 38711.83Skamil 38721.83Skamil/// ---------------------------------------------------------------------------- 38731.83Skamil 38741.84SkamilATF_TC(signal_mask_unrelated); 38751.84SkamilATF_TC_HEAD(signal_mask_unrelated, tc) 38761.1Skamil{ 38771.1Skamil atf_tc_set_md_var(tc, "descr", 38781.1Skamil "Verify that masking single unrelated signal does not stop tracer " 38791.1Skamil "from catching other signals"); 38801.1Skamil} 38811.1Skamil 38821.84SkamilATF_TC_BODY(signal_mask_unrelated, tc) 38831.1Skamil{ 38841.1Skamil const int exitval = 5; 38851.1Skamil const int sigval = SIGSTOP; 38861.1Skamil const int sigmasked = SIGTRAP; 38871.1Skamil const int signotmasked = SIGINT; 38881.1Skamil pid_t child, wpid; 38891.1Skamil#if defined(TWAIT_HAVE_STATUS) 38901.1Skamil int status; 38911.1Skamil#endif 38921.1Skamil sigset_t intmask; 38931.1Skamil 38941.13Schristos DPRINTF("Before forking process PID=%d\n", getpid()); 38951.13Schristos SYSCALL_REQUIRE((child = fork()) != -1); 38961.1Skamil if (child == 0) { 38971.13Schristos DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 38981.1Skamil FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 38991.1Skamil 39001.1Skamil sigemptyset(&intmask); 39011.1Skamil sigaddset(&intmask, sigmasked); 39021.1Skamil sigprocmask(SIG_BLOCK, &intmask, NULL); 39031.1Skamil 39041.13Schristos DPRINTF("Before raising %s from child\n", strsignal(sigval)); 39051.1Skamil FORKEE_ASSERT(raise(sigval) == 0); 39061.1Skamil 39071.13Schristos DPRINTF("Before raising %s from child\n", 39081.1Skamil strsignal(signotmasked)); 39091.1Skamil FORKEE_ASSERT(raise(signotmasked) == 0); 39101.1Skamil 39111.13Schristos DPRINTF("Before exiting of the child process\n"); 39121.1Skamil _exit(exitval); 39131.1Skamil } 39141.13Schristos DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 39151.1Skamil 39161.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 39171.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 39181.1Skamil 39191.1Skamil validate_status_stopped(status, sigval); 39201.1Skamil 39211.13Schristos DPRINTF("Before resuming the child process where it left off and " 39221.1Skamil "without signal to be sent\n"); 39231.13Schristos SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 39241.1Skamil 39251.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 39261.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 39271.1Skamil 39281.1Skamil validate_status_stopped(status, signotmasked); 39291.1Skamil 39301.13Schristos DPRINTF("Before resuming the child process where it left off and " 39311.1Skamil "without signal to be sent\n"); 39321.13Schristos SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 39331.1Skamil 39341.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 39351.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 39361.1Skamil 39371.1Skamil validate_status_exited(status, exitval); 39381.1Skamil 39391.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 39401.1Skamil TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 39411.1Skamil} 39421.1Skamil 39431.84Skamil/// ---------------------------------------------------------------------------- 39441.84Skamil 39451.1SkamilATF_TC(signal3); 39461.1SkamilATF_TC_HEAD(signal3, tc) 39471.1Skamil{ 39481.7Skamil atf_tc_set_md_var(tc, "timeout", "5"); 39491.1Skamil atf_tc_set_md_var(tc, "descr", 39501.1Skamil "Verify that masking SIGTRAP in tracee does not stop tracer from " 39511.1Skamil "catching software breakpoints"); 39521.1Skamil} 39531.1Skamil 39541.1SkamilATF_TC_BODY(signal3, tc) 39551.1Skamil{ 39561.1Skamil const int exitval = 5; 39571.1Skamil const int sigval = SIGSTOP; 39581.1Skamil const int sigmasked = SIGTRAP; 39591.1Skamil pid_t child, wpid; 39601.1Skamil#if defined(TWAIT_HAVE_STATUS) 39611.1Skamil int status; 39621.1Skamil#endif 39631.1Skamil sigset_t intmask; 39641.1Skamil 39651.13Schristos DPRINTF("Before forking process PID=%d\n", getpid()); 39661.13Schristos SYSCALL_REQUIRE((child = fork()) != -1); 39671.1Skamil if (child == 0) { 39681.13Schristos DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 39691.1Skamil FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 39701.1Skamil 39711.1Skamil sigemptyset(&intmask); 39721.1Skamil sigaddset(&intmask, sigmasked); 39731.1Skamil sigprocmask(SIG_BLOCK, &intmask, NULL); 39741.1Skamil 39751.13Schristos DPRINTF("Before raising %s from child\n", strsignal(sigval)); 39761.1Skamil FORKEE_ASSERT(raise(sigval) == 0); 39771.1Skamil 39781.13Schristos DPRINTF("Before raising software breakpoint from child\n"); 39791.52Skamil trigger_trap(); 39801.1Skamil 39811.13Schristos DPRINTF("Before exiting of the child process\n"); 39821.1Skamil _exit(exitval); 39831.1Skamil } 39841.13Schristos DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 39851.1Skamil 39861.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 39871.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 39881.1Skamil 39891.1Skamil validate_status_stopped(status, sigval); 39901.1Skamil 39911.13Schristos DPRINTF("Before resuming the child process where it left off and " 39921.1Skamil "without signal to be sent\n"); 39931.13Schristos SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 39941.1Skamil 39951.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 39961.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 39971.1Skamil 39981.1Skamil validate_status_stopped(status, sigmasked); 39991.1Skamil 40001.13Schristos DPRINTF("Before resuming the child process where it left off and " 40011.1Skamil "without signal to be sent\n"); 40021.49Skamil SYSCALL_REQUIRE(ptrace(PT_KILL, child, NULL, 0) != -1); 40031.1Skamil 40041.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 40051.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 40061.1Skamil 40071.49Skamil validate_status_signaled(status, SIGKILL, 0); 40081.1Skamil 40091.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 40101.1Skamil TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 40111.1Skamil} 40121.1Skamil 40131.1Skamil#if defined(PT_STEP) 40141.1SkamilATF_TC(signal4); 40151.1SkamilATF_TC_HEAD(signal4, tc) 40161.1Skamil{ 40171.1Skamil atf_tc_set_md_var(tc, "descr", 40181.1Skamil "Verify that masking SIGTRAP in tracee does not stop tracer from " 40191.1Skamil "catching single step trap"); 40201.1Skamil} 40211.1Skamil 40221.1SkamilATF_TC_BODY(signal4, tc) 40231.1Skamil{ 40241.1Skamil const int exitval = 5; 40251.1Skamil const int sigval = SIGSTOP; 40261.1Skamil const int sigmasked = SIGTRAP; 40271.1Skamil pid_t child, wpid; 40281.1Skamil#if defined(TWAIT_HAVE_STATUS) 40291.1Skamil int status; 40301.1Skamil#endif 40311.1Skamil sigset_t intmask; 40321.1Skamil int happy; 40331.1Skamil 40341.1Skamil#if defined(__arm__) 40351.5Skamil /* PT_STEP not supported on arm 32-bit */ 40361.5Skamil atf_tc_expect_fail("PR kern/51918 PR kern/52119"); 40371.1Skamil#endif 40381.1Skamil 40391.13Schristos DPRINTF("Before forking process PID=%d\n", getpid()); 40401.13Schristos SYSCALL_REQUIRE((child = fork()) != -1); 40411.1Skamil if (child == 0) { 40421.13Schristos DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 40431.1Skamil FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 40441.1Skamil 40451.1Skamil happy = check_happy(100); 40461.1Skamil 40471.1Skamil sigemptyset(&intmask); 40481.1Skamil sigaddset(&intmask, sigmasked); 40491.1Skamil sigprocmask(SIG_BLOCK, &intmask, NULL); 40501.1Skamil 40511.13Schristos DPRINTF("Before raising %s from child\n", strsignal(sigval)); 40521.1Skamil FORKEE_ASSERT(raise(sigval) == 0); 40531.1Skamil 40541.1Skamil FORKEE_ASSERT_EQ(happy, check_happy(100)); 40551.1Skamil 40561.13Schristos DPRINTF("Before exiting of the child process\n"); 40571.1Skamil _exit(exitval); 40581.1Skamil } 40591.13Schristos DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 40601.1Skamil 40611.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 40621.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 40631.1Skamil 40641.1Skamil validate_status_stopped(status, sigval); 40651.1Skamil 40661.13Schristos DPRINTF("Before resuming the child process where it left off and " 40671.1Skamil "without signal to be sent\n"); 40681.13Schristos SYSCALL_REQUIRE(ptrace(PT_STEP, child, (void *)1, 0) != -1); 40691.1Skamil 40701.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 40711.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 40721.1Skamil 40731.1Skamil validate_status_stopped(status, sigmasked); 40741.1Skamil 40751.13Schristos DPRINTF("Before resuming the child process where it left off and " 40761.1Skamil "without signal to be sent\n"); 40771.13Schristos SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 40781.1Skamil 40791.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 40801.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 40811.1Skamil 40821.1Skamil validate_status_exited(status, exitval); 40831.1Skamil 40841.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 40851.1Skamil TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 40861.1Skamil} 40871.1Skamil#endif 40881.1Skamil 40891.1SkamilATF_TC(signal5); 40901.1SkamilATF_TC_HEAD(signal5, tc) 40911.1Skamil{ 40921.1Skamil atf_tc_set_md_var(tc, "descr", 40931.1Skamil "Verify that masking SIGTRAP in tracee does not stop tracer from " 40941.1Skamil "catching exec() breakpoint"); 40951.1Skamil} 40961.1Skamil 40971.1SkamilATF_TC_BODY(signal5, tc) 40981.1Skamil{ 40991.1Skamil const int sigval = SIGSTOP; 41001.1Skamil const int sigmasked = SIGTRAP; 41011.1Skamil pid_t child, wpid; 41021.1Skamil#if defined(TWAIT_HAVE_STATUS) 41031.1Skamil int status; 41041.1Skamil#endif 41051.58Skamil struct ptrace_siginfo info; 41061.1Skamil sigset_t intmask; 41071.1Skamil 41081.58Skamil memset(&info, 0, sizeof(info)); 41091.14Schristos 41101.13Schristos DPRINTF("Before forking process PID=%d\n", getpid()); 41111.13Schristos SYSCALL_REQUIRE((child = fork()) != -1); 41121.1Skamil if (child == 0) { 41131.13Schristos DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 41141.1Skamil FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 41151.1Skamil 41161.1Skamil sigemptyset(&intmask); 41171.1Skamil sigaddset(&intmask, sigmasked); 41181.1Skamil sigprocmask(SIG_BLOCK, &intmask, NULL); 41191.1Skamil 41201.13Schristos DPRINTF("Before raising %s from child\n", strsignal(sigval)); 41211.1Skamil FORKEE_ASSERT(raise(sigval) == 0); 41221.1Skamil 41231.13Schristos DPRINTF("Before calling execve(2) from child\n"); 41241.1Skamil execlp("/bin/echo", "/bin/echo", NULL); 41251.1Skamil 41261.58Skamil /* NOTREACHED */ 41271.58Skamil FORKEE_ASSERTX(0 && "Not reached"); 41281.1Skamil } 41291.13Schristos DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 41301.1Skamil 41311.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 41321.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 41331.1Skamil 41341.1Skamil validate_status_stopped(status, sigval); 41351.1Skamil 41361.13Schristos DPRINTF("Before resuming the child process where it left off and " 41371.1Skamil "without signal to be sent\n"); 41381.13Schristos SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 41391.1Skamil 41401.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 41411.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 41421.1Skamil 41431.1Skamil validate_status_stopped(status, sigmasked); 41441.1Skamil 41451.58Skamil DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 41461.61Skre SYSCALL_REQUIRE( 41471.61Skre ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 41481.58Skamil 41491.58Skamil DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 41501.58Skamil DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 41511.58Skamil info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 41521.58Skamil info.psi_siginfo.si_errno); 41531.58Skamil 41541.58Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigmasked); 41551.58Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_EXEC); 41561.58Skamil 41571.13Schristos DPRINTF("Before resuming the child process where it left off and " 41581.1Skamil "without signal to be sent\n"); 41591.13Schristos SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 41601.1Skamil 41611.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 41621.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 41631.1Skamil 41641.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 41651.1Skamil TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 41661.1Skamil} 41671.1Skamil 41681.1Skamil#if defined(TWAIT_HAVE_PID) 41691.1SkamilATF_TC(signal6); 41701.1SkamilATF_TC_HEAD(signal6, tc) 41711.1Skamil{ 41721.1Skamil atf_tc_set_md_var(tc, "timeout", "5"); 41731.1Skamil atf_tc_set_md_var(tc, "descr", 41741.1Skamil "Verify that masking SIGTRAP in tracee does not stop tracer from " 41751.1Skamil "catching PTRACE_FORK breakpoint"); 41761.1Skamil} 41771.1Skamil 41781.1SkamilATF_TC_BODY(signal6, tc) 41791.1Skamil{ 41801.1Skamil const int exitval = 5; 41811.1Skamil const int exitval2 = 15; 41821.1Skamil const int sigval = SIGSTOP; 41831.1Skamil const int sigmasked = SIGTRAP; 41841.1Skamil pid_t child, child2, wpid; 41851.1Skamil#if defined(TWAIT_HAVE_STATUS) 41861.1Skamil int status; 41871.1Skamil#endif 41881.1Skamil sigset_t intmask; 41891.1Skamil ptrace_state_t state; 41901.1Skamil const int slen = sizeof(state); 41911.1Skamil ptrace_event_t event; 41921.1Skamil const int elen = sizeof(event); 41931.1Skamil 41941.38Skamil atf_tc_expect_fail("PR kern/51918"); 41951.14Schristos 41961.13Schristos DPRINTF("Before forking process PID=%d\n", getpid()); 41971.13Schristos SYSCALL_REQUIRE((child = fork()) != -1); 41981.1Skamil if (child == 0) { 41991.13Schristos DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 42001.1Skamil FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 42011.1Skamil 42021.1Skamil sigemptyset(&intmask); 42031.1Skamil sigaddset(&intmask, sigmasked); 42041.1Skamil sigprocmask(SIG_BLOCK, &intmask, NULL); 42051.1Skamil 42061.13Schristos DPRINTF("Before raising %s from child\n", strsignal(sigval)); 42071.1Skamil FORKEE_ASSERT(raise(sigval) == 0); 42081.1Skamil 42091.1Skamil FORKEE_ASSERT((child2 = fork()) != -1); 42101.1Skamil 42111.1Skamil if (child2 == 0) 42121.1Skamil _exit(exitval2); 42131.1Skamil 42141.1Skamil FORKEE_REQUIRE_SUCCESS 42151.1Skamil (wpid = TWAIT_GENERIC(child2, &status, 0), child2); 42161.1Skamil 42171.1Skamil forkee_status_exited(status, exitval2); 42181.1Skamil 42191.13Schristos DPRINTF("Before exiting of the child process\n"); 42201.1Skamil _exit(exitval); 42211.1Skamil } 42221.13Schristos DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 42231.1Skamil 42241.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 42251.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 42261.1Skamil 42271.1Skamil validate_status_stopped(status, sigval); 42281.1Skamil 42291.13Schristos DPRINTF("Enable PTRACE_FORK in EVENT_MASK for the child %d\n", child); 42301.1Skamil event.pe_set_event = PTRACE_FORK; 42311.13Schristos SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); 42321.1Skamil 42331.13Schristos DPRINTF("Before resuming the child process where it left off and " 42341.1Skamil "without signal to be sent\n"); 42351.13Schristos SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 42361.1Skamil 42371.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 42381.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 42391.1Skamil 42401.1Skamil validate_status_stopped(status, sigmasked); 42411.1Skamil 42421.13Schristos SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 42431.1Skamil ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_FORK); 42441.1Skamil 42451.1Skamil child2 = state.pe_other_pid; 42461.13Schristos DPRINTF("Reported PTRACE_FORK event with forkee %d\n", child2); 42471.1Skamil 42481.13Schristos DPRINTF("Before calling %s() for the child2\n", TWAIT_FNAME); 42491.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0), 42501.1Skamil child2); 42511.1Skamil 42521.1Skamil validate_status_stopped(status, SIGTRAP); 42531.1Skamil 42541.13Schristos SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1); 42551.1Skamil ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_FORK); 42561.1Skamil ATF_REQUIRE_EQ(state.pe_other_pid, child); 42571.1Skamil 42581.13Schristos DPRINTF("Before resuming the forkee process where it left off and " 42591.1Skamil "without signal to be sent\n"); 42601.13Schristos SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1); 42611.1Skamil 42621.13Schristos DPRINTF("Before resuming the child process where it left off and " 42631.1Skamil "without signal to be sent\n"); 42641.13Schristos SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 42651.1Skamil 42661.13Schristos DPRINTF("Before calling %s() for the forkee - expected exited\n", 42671.1Skamil TWAIT_FNAME); 42681.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0), 42691.57Skamil child2); 42701.1Skamil 42711.1Skamil validate_status_exited(status, exitval2); 42721.1Skamil 42731.13Schristos DPRINTF("Before calling %s() for the forkee - expected no process\n", 42741.1Skamil TWAIT_FNAME); 42751.1Skamil TWAIT_REQUIRE_FAILURE(ECHILD, 42761.1Skamil wpid = TWAIT_GENERIC(child2, &status, 0)); 42771.1Skamil 42781.13Schristos DPRINTF("Before calling %s() for the child - expected stopped " 42791.1Skamil "SIGCHLD\n", TWAIT_FNAME); 42801.57Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 42811.1Skamil 42821.1Skamil validate_status_stopped(status, SIGCHLD); 42831.1Skamil 42841.57Skamil DPRINTF("Before resuming the child process where it left off and " 42851.1Skamil "without signal to be sent\n"); 42861.13Schristos SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 42871.1Skamil 42881.13Schristos DPRINTF("Before calling %s() for the child - expected exited\n", 42891.1Skamil TWAIT_FNAME); 42901.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 42911.1Skamil 42921.1Skamil validate_status_exited(status, exitval); 42931.1Skamil 42941.13Schristos DPRINTF("Before calling %s() for the child - expected no process\n", 42951.57Skamil TWAIT_FNAME); 42961.1Skamil TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 42971.1Skamil} 42981.1Skamil#endif 42991.1Skamil 43001.1Skamil#if defined(TWAIT_HAVE_PID) 43011.1SkamilATF_TC(signal7); 43021.1SkamilATF_TC_HEAD(signal7, tc) 43031.1Skamil{ 43041.1Skamil atf_tc_set_md_var(tc, "descr", 43051.1Skamil "Verify that masking SIGTRAP in tracee does not stop tracer from " 43061.1Skamil "catching PTRACE_VFORK breakpoint"); 43071.1Skamil} 43081.1Skamil 43091.1SkamilATF_TC_BODY(signal7, tc) 43101.1Skamil{ 43111.1Skamil const int exitval = 5; 43121.1Skamil const int exitval2 = 15; 43131.1Skamil const int sigval = SIGSTOP; 43141.1Skamil const int sigmasked = SIGTRAP; 43151.1Skamil pid_t child, child2, wpid; 43161.1Skamil#if defined(TWAIT_HAVE_STATUS) 43171.1Skamil int status; 43181.1Skamil#endif 43191.1Skamil sigset_t intmask; 43201.1Skamil ptrace_state_t state; 43211.1Skamil const int slen = sizeof(state); 43221.1Skamil ptrace_event_t event; 43231.1Skamil const int elen = sizeof(event); 43241.1Skamil 43251.38Skamil atf_tc_expect_fail("PR kern/51918"); 43261.14Schristos 43271.13Schristos DPRINTF("Before forking process PID=%d\n", getpid()); 43281.13Schristos SYSCALL_REQUIRE((child = fork()) != -1); 43291.1Skamil if (child == 0) { 43301.13Schristos DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 43311.1Skamil FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 43321.1Skamil 43331.1Skamil sigemptyset(&intmask); 43341.1Skamil sigaddset(&intmask, sigmasked); 43351.1Skamil sigprocmask(SIG_BLOCK, &intmask, NULL); 43361.1Skamil 43371.13Schristos DPRINTF("Before raising %s from child\n", strsignal(sigval)); 43381.1Skamil FORKEE_ASSERT(raise(sigval) == 0); 43391.1Skamil 43401.1Skamil FORKEE_ASSERT((child2 = fork()) != -1); 43411.1Skamil 43421.1Skamil if (child2 == 0) 43431.1Skamil _exit(exitval2); 43441.1Skamil 43451.1Skamil FORKEE_REQUIRE_SUCCESS 43461.1Skamil (wpid = TWAIT_GENERIC(child2, &status, 0), child2); 43471.1Skamil 43481.1Skamil forkee_status_exited(status, exitval2); 43491.1Skamil 43501.13Schristos DPRINTF("Before exiting of the child process\n"); 43511.1Skamil _exit(exitval); 43521.1Skamil } 43531.13Schristos DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 43541.1Skamil 43551.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 43561.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 43571.1Skamil 43581.1Skamil validate_status_stopped(status, sigval); 43591.1Skamil 43601.13Schristos DPRINTF("Enable PTRACE_VFORK in EVENT_MASK for the child %d\n", child); 43611.1Skamil event.pe_set_event = PTRACE_VFORK; 43621.61Skre SYSCALL_REQUIRE( 43631.61Skre ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1 || 43641.61Skre errno == ENOTSUP); 43651.1Skamil 43661.13Schristos DPRINTF("Before resuming the child process where it left off and " 43671.1Skamil "without signal to be sent\n"); 43681.13Schristos SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 43691.1Skamil 43701.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 43711.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 43721.1Skamil 43731.1Skamil validate_status_stopped(status, sigmasked); 43741.1Skamil 43751.61Skre SYSCALL_REQUIRE( 43761.61Skre ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 43771.1Skamil ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK); 43781.1Skamil 43791.1Skamil child2 = state.pe_other_pid; 43801.13Schristos DPRINTF("Reported PTRACE_VFORK event with forkee %d\n", child2); 43811.1Skamil 43821.13Schristos DPRINTF("Before calling %s() for the child2\n", TWAIT_FNAME); 43831.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0), 43841.1Skamil child2); 43851.1Skamil 43861.1Skamil validate_status_stopped(status, SIGTRAP); 43871.1Skamil 43881.61Skre SYSCALL_REQUIRE( 43891.61Skre ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1); 43901.1Skamil ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK); 43911.1Skamil ATF_REQUIRE_EQ(state.pe_other_pid, child); 43921.1Skamil 43931.13Schristos DPRINTF("Before resuming the forkee process where it left off and " 43941.1Skamil "without signal to be sent\n"); 43951.13Schristos SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1); 43961.1Skamil 43971.13Schristos DPRINTF("Before resuming the child process where it left off and " 43981.1Skamil "without signal to be sent\n"); 43991.13Schristos SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 44001.1Skamil 44011.13Schristos DPRINTF("Before calling %s() for the forkee - expected exited\n", 44021.1Skamil TWAIT_FNAME); 44031.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0), 44041.57Skamil child2); 44051.1Skamil 44061.1Skamil validate_status_exited(status, exitval2); 44071.1Skamil 44081.13Schristos DPRINTF("Before calling %s() for the forkee - expected no process\n", 44091.1Skamil TWAIT_FNAME); 44101.1Skamil TWAIT_REQUIRE_FAILURE(ECHILD, 44111.1Skamil wpid = TWAIT_GENERIC(child2, &status, 0)); 44121.1Skamil 44131.13Schristos DPRINTF("Before calling %s() for the child - expected stopped " 44141.1Skamil "SIGCHLD\n", TWAIT_FNAME); 44151.57Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 44161.1Skamil 44171.1Skamil validate_status_stopped(status, SIGCHLD); 44181.1Skamil 44191.57Skamil DPRINTF("Before resuming the child process where it left off and " 44201.1Skamil "without signal to be sent\n"); 44211.13Schristos SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 44221.1Skamil 44231.13Schristos DPRINTF("Before calling %s() for the child - expected exited\n", 44241.1Skamil TWAIT_FNAME); 44251.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 44261.1Skamil 44271.1Skamil validate_status_exited(status, exitval); 44281.1Skamil 44291.13Schristos DPRINTF("Before calling %s() for the child - expected no process\n", 44301.57Skamil TWAIT_FNAME); 44311.1Skamil TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 44321.1Skamil} 44331.1Skamil#endif 44341.1Skamil 44351.1SkamilATF_TC(signal8); 44361.1SkamilATF_TC_HEAD(signal8, tc) 44371.1Skamil{ 44381.1Skamil atf_tc_set_md_var(tc, "descr", 44391.1Skamil "Verify that masking SIGTRAP in tracee does not stop tracer from " 44401.1Skamil "catching PTRACE_VFORK_DONE breakpoint"); 44411.1Skamil} 44421.1Skamil 44431.1SkamilATF_TC_BODY(signal8, tc) 44441.1Skamil{ 44451.1Skamil const int exitval = 5; 44461.1Skamil const int exitval2 = 15; 44471.1Skamil const int sigval = SIGSTOP; 44481.1Skamil const int sigmasked = SIGTRAP; 44491.1Skamil pid_t child, child2, wpid; 44501.1Skamil#if defined(TWAIT_HAVE_STATUS) 44511.1Skamil int status; 44521.1Skamil#endif 44531.1Skamil sigset_t intmask; 44541.1Skamil ptrace_state_t state; 44551.1Skamil const int slen = sizeof(state); 44561.1Skamil ptrace_event_t event; 44571.1Skamil const int elen = sizeof(event); 44581.1Skamil 44591.14Schristos atf_tc_expect_fail("PR kern/51918"); 44601.14Schristos 44611.13Schristos DPRINTF("Before forking process PID=%d\n", getpid()); 44621.13Schristos SYSCALL_REQUIRE((child = fork()) != -1); 44631.1Skamil if (child == 0) { 44641.13Schristos DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 44651.1Skamil FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 44661.1Skamil 44671.1Skamil sigemptyset(&intmask); 44681.1Skamil sigaddset(&intmask, sigmasked); 44691.1Skamil sigprocmask(SIG_BLOCK, &intmask, NULL); 44701.1Skamil 44711.13Schristos DPRINTF("Before raising %s from child\n", strsignal(sigval)); 44721.1Skamil FORKEE_ASSERT(raise(sigval) == 0); 44731.1Skamil 44741.1Skamil FORKEE_ASSERT((child2 = vfork()) != -1); 44751.1Skamil 44761.1Skamil if (child2 == 0) 44771.1Skamil _exit(exitval2); 44781.1Skamil 44791.1Skamil FORKEE_REQUIRE_SUCCESS 44801.1Skamil (wpid = TWAIT_GENERIC(child2, &status, 0), child2); 44811.1Skamil 44821.1Skamil forkee_status_exited(status, exitval2); 44831.1Skamil 44841.13Schristos DPRINTF("Before exiting of the child process\n"); 44851.1Skamil _exit(exitval); 44861.1Skamil } 44871.13Schristos DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 44881.1Skamil 44891.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 44901.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 44911.1Skamil 44921.1Skamil validate_status_stopped(status, sigval); 44931.1Skamil 44941.13Schristos DPRINTF("Enable PTRACE_VFORK_DONE in EVENT_MASK for the child %d\n", 44951.1Skamil child); 44961.1Skamil event.pe_set_event = PTRACE_VFORK_DONE; 44971.13Schristos SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); 44981.1Skamil 44991.13Schristos DPRINTF("Before resuming the child process where it left off and " 45001.1Skamil "without signal to be sent\n"); 45011.13Schristos SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 45021.1Skamil 45031.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 45041.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 45051.1Skamil 45061.1Skamil validate_status_stopped(status, sigmasked); 45071.1Skamil 45081.61Skre SYSCALL_REQUIRE( 45091.61Skre ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 45101.1Skamil ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK_DONE); 45111.1Skamil 45121.1Skamil child2 = state.pe_other_pid; 45131.13Schristos DPRINTF("Reported PTRACE_VFORK_DONE event with forkee %d\n", child2); 45141.1Skamil 45151.13Schristos DPRINTF("Before resuming the child process where it left off and " 45161.1Skamil "without signal to be sent\n"); 45171.13Schristos SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 45181.1Skamil 45191.13Schristos DPRINTF("Before calling %s() for the child - expected stopped " 45201.1Skamil "SIGCHLD\n", TWAIT_FNAME); 45211.57Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 45221.1Skamil 45231.1Skamil validate_status_stopped(status, SIGCHLD); 45241.1Skamil 45251.57Skamil DPRINTF("Before resuming the child process where it left off and " 45261.1Skamil "without signal to be sent\n"); 45271.13Schristos SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 45281.1Skamil 45291.13Schristos DPRINTF("Before calling %s() for the child - expected exited\n", 45301.1Skamil TWAIT_FNAME); 45311.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 45321.1Skamil 45331.1Skamil validate_status_exited(status, exitval); 45341.1Skamil 45351.13Schristos DPRINTF("Before calling %s() for the child - expected no process\n", 45361.57Skamil TWAIT_FNAME); 45371.1Skamil TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 45381.1Skamil} 45391.1Skamil 45401.83Skamilvolatile lwpid_t the_lwp_id = 0; 45411.83Skamil 45421.83Skamilstatic void 45431.83Skamillwp_main_func(void *arg) 45441.83Skamil{ 45451.83Skamil the_lwp_id = _lwp_self(); 45461.83Skamil _lwp_exit(); 45471.83Skamil} 45481.83Skamil 45491.1SkamilATF_TC(signal9); 45501.1SkamilATF_TC_HEAD(signal9, tc) 45511.1Skamil{ 45521.1Skamil atf_tc_set_md_var(tc, "descr", 45531.1Skamil "Verify that masking SIGTRAP in tracee does not stop tracer from " 45541.1Skamil "catching PTRACE_LWP_CREATE breakpoint"); 45551.1Skamil} 45561.1Skamil 45571.1SkamilATF_TC_BODY(signal9, tc) 45581.1Skamil{ 45591.1Skamil const int exitval = 5; 45601.1Skamil const int sigval = SIGSTOP; 45611.1Skamil const int sigmasked = SIGTRAP; 45621.1Skamil pid_t child, wpid; 45631.1Skamil#if defined(TWAIT_HAVE_STATUS) 45641.1Skamil int status; 45651.1Skamil#endif 45661.1Skamil sigset_t intmask; 45671.1Skamil ptrace_state_t state; 45681.1Skamil const int slen = sizeof(state); 45691.1Skamil ptrace_event_t event; 45701.1Skamil const int elen = sizeof(event); 45711.1Skamil ucontext_t uc; 45721.1Skamil lwpid_t lid; 45731.1Skamil static const size_t ssize = 16*1024; 45741.1Skamil void *stack; 45751.1Skamil 45761.14Schristos atf_tc_expect_fail("PR kern/51918"); 45771.14Schristos 45781.13Schristos DPRINTF("Before forking process PID=%d\n", getpid()); 45791.13Schristos SYSCALL_REQUIRE((child = fork()) != -1); 45801.1Skamil if (child == 0) { 45811.13Schristos DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 45821.1Skamil FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 45831.1Skamil 45841.1Skamil sigemptyset(&intmask); 45851.1Skamil sigaddset(&intmask, sigmasked); 45861.1Skamil sigprocmask(SIG_BLOCK, &intmask, NULL); 45871.1Skamil 45881.13Schristos DPRINTF("Before raising %s from child\n", strsignal(sigval)); 45891.1Skamil FORKEE_ASSERT(raise(sigval) == 0); 45901.1Skamil 45911.13Schristos DPRINTF("Before allocating memory for stack in child\n"); 45921.1Skamil FORKEE_ASSERT((stack = malloc(ssize)) != NULL); 45931.1Skamil 45941.13Schristos DPRINTF("Before making context for new lwp in child\n"); 45951.1Skamil _lwp_makecontext(&uc, lwp_main_func, NULL, NULL, stack, ssize); 45961.1Skamil 45971.13Schristos DPRINTF("Before creating new in child\n"); 45981.1Skamil FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0); 45991.1Skamil 46001.13Schristos DPRINTF("Before waiting for lwp %d to exit\n", lid); 46011.1Skamil FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0); 46021.1Skamil 46031.13Schristos DPRINTF("Before verifying that reported %d and running lid %d " 46041.1Skamil "are the same\n", lid, the_lwp_id); 46051.1Skamil FORKEE_ASSERT_EQ(lid, the_lwp_id); 46061.1Skamil 46071.13Schristos DPRINTF("Before exiting of the child process\n"); 46081.1Skamil _exit(exitval); 46091.1Skamil } 46101.13Schristos DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 46111.1Skamil 46121.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 46131.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 46141.1Skamil 46151.1Skamil validate_status_stopped(status, sigval); 46161.1Skamil 46171.13Schristos DPRINTF("Set empty EVENT_MASK for the child %d\n", child); 46181.1Skamil event.pe_set_event = PTRACE_LWP_CREATE; 46191.13Schristos SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); 46201.1Skamil 46211.13Schristos DPRINTF("Before resuming the child process where it left off and " 46221.1Skamil "without signal to be sent\n"); 46231.13Schristos SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 46241.1Skamil 46251.13Schristos DPRINTF("Before calling %s() for the child - expected stopped " 46261.1Skamil "SIGTRAP\n", TWAIT_FNAME); 46271.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 46281.1Skamil 46291.1Skamil validate_status_stopped(status, sigmasked); 46301.1Skamil 46311.13Schristos SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 46321.1Skamil 46331.1Skamil ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_LWP_CREATE); 46341.1Skamil 46351.1Skamil lid = state.pe_lwp; 46361.13Schristos DPRINTF("Reported PTRACE_LWP_CREATE event with lid %d\n", lid); 46371.1Skamil 46381.13Schristos DPRINTF("Before resuming the child process where it left off and " 46391.1Skamil "without signal to be sent\n"); 46401.13Schristos SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 46411.1Skamil 46421.13Schristos DPRINTF("Before calling %s() for the child - expected exited\n", 46431.1Skamil TWAIT_FNAME); 46441.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 46451.1Skamil 46461.1Skamil validate_status_exited(status, exitval); 46471.1Skamil 46481.13Schristos DPRINTF("Before calling %s() for the child - expected no process\n", 46491.1Skamil TWAIT_FNAME); 46501.1Skamil TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 46511.1Skamil} 46521.1Skamil 46531.1SkamilATF_TC(signal10); 46541.1SkamilATF_TC_HEAD(signal10, tc) 46551.1Skamil{ 46561.1Skamil atf_tc_set_md_var(tc, "descr", 46571.1Skamil "Verify that masking SIGTRAP in tracee does not stop tracer from " 46581.1Skamil "catching PTRACE_LWP_EXIT breakpoint"); 46591.1Skamil} 46601.1Skamil 46611.1SkamilATF_TC_BODY(signal10, tc) 46621.1Skamil{ 46631.1Skamil const int exitval = 5; 46641.1Skamil const int sigval = SIGSTOP; 46651.1Skamil const int sigmasked = SIGTRAP; 46661.1Skamil pid_t child, wpid; 46671.1Skamil#if defined(TWAIT_HAVE_STATUS) 46681.1Skamil int status; 46691.1Skamil#endif 46701.1Skamil sigset_t intmask; 46711.1Skamil ptrace_state_t state; 46721.1Skamil const int slen = sizeof(state); 46731.1Skamil ptrace_event_t event; 46741.1Skamil const int elen = sizeof(event); 46751.1Skamil ucontext_t uc; 46761.1Skamil lwpid_t lid; 46771.1Skamil static const size_t ssize = 16*1024; 46781.1Skamil void *stack; 46791.1Skamil 46801.14Schristos atf_tc_expect_fail("PR kern/51918"); 46811.14Schristos 46821.13Schristos DPRINTF("Before forking process PID=%d\n", getpid()); 46831.13Schristos SYSCALL_REQUIRE((child = fork()) != -1); 46841.1Skamil if (child == 0) { 46851.13Schristos DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 46861.1Skamil FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 46871.1Skamil 46881.1Skamil sigemptyset(&intmask); 46891.1Skamil sigaddset(&intmask, sigmasked); 46901.1Skamil sigprocmask(SIG_BLOCK, &intmask, NULL); 46911.1Skamil 46921.13Schristos DPRINTF("Before raising %s from child\n", strsignal(sigval)); 46931.1Skamil FORKEE_ASSERT(raise(sigval) == 0); 46941.1Skamil 46951.13Schristos DPRINTF("Before allocating memory for stack in child\n"); 46961.1Skamil FORKEE_ASSERT((stack = malloc(ssize)) != NULL); 46971.1Skamil 46981.13Schristos DPRINTF("Before making context for new lwp in child\n"); 46991.1Skamil _lwp_makecontext(&uc, lwp_main_func, NULL, NULL, stack, ssize); 47001.1Skamil 47011.13Schristos DPRINTF("Before creating new in child\n"); 47021.1Skamil FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0); 47031.1Skamil 47041.13Schristos DPRINTF("Before waiting for lwp %d to exit\n", lid); 47051.1Skamil FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0); 47061.1Skamil 47071.13Schristos DPRINTF("Before verifying that reported %d and running lid %d " 47081.1Skamil "are the same\n", lid, the_lwp_id); 47091.1Skamil FORKEE_ASSERT_EQ(lid, the_lwp_id); 47101.1Skamil 47111.13Schristos DPRINTF("Before exiting of the child process\n"); 47121.1Skamil _exit(exitval); 47131.1Skamil } 47141.13Schristos DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 47151.1Skamil 47161.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 47171.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 47181.1Skamil 47191.1Skamil validate_status_stopped(status, sigval); 47201.1Skamil 47211.13Schristos DPRINTF("Set empty EVENT_MASK for the child %d\n", child); 47221.1Skamil event.pe_set_event = PTRACE_LWP_EXIT; 47231.13Schristos SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); 47241.1Skamil 47251.13Schristos DPRINTF("Before resuming the child process where it left off and " 47261.1Skamil "without signal to be sent\n"); 47271.13Schristos SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 47281.1Skamil 47291.13Schristos DPRINTF("Before calling %s() for the child - expected stopped " 47301.1Skamil "SIGTRAP\n", TWAIT_FNAME); 47311.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 47321.1Skamil 47331.1Skamil validate_status_stopped(status, sigmasked); 47341.1Skamil 47351.13Schristos SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 47361.1Skamil 47371.1Skamil ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_LWP_EXIT); 47381.1Skamil 47391.1Skamil lid = state.pe_lwp; 47401.13Schristos DPRINTF("Reported PTRACE_LWP_EXIT event with lid %d\n", lid); 47411.1Skamil 47421.13Schristos DPRINTF("Before resuming the child process where it left off and " 47431.1Skamil "without signal to be sent\n"); 47441.13Schristos SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 47451.1Skamil 47461.13Schristos DPRINTF("Before calling %s() for the child - expected exited\n", 47471.1Skamil TWAIT_FNAME); 47481.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 47491.1Skamil 47501.1Skamil validate_status_exited(status, exitval); 47511.1Skamil 47521.13Schristos DPRINTF("Before calling %s() for the child - expected no process\n", 47531.1Skamil TWAIT_FNAME); 47541.1Skamil TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 47551.1Skamil} 47561.1Skamil 47571.1Skamilstatic void 47581.1Skamillwp_main_stop(void *arg) 47591.1Skamil{ 47601.1Skamil the_lwp_id = _lwp_self(); 47611.1Skamil 47621.1Skamil raise(SIGTRAP); 47631.1Skamil 47641.1Skamil _lwp_exit(); 47651.1Skamil} 47661.1Skamil 47671.1SkamilATF_TC(suspend1); 47681.1SkamilATF_TC_HEAD(suspend1, tc) 47691.1Skamil{ 47701.1Skamil atf_tc_set_md_var(tc, "descr", 47711.1Skamil "Verify that a thread can be suspended by a debugger and later " 47721.1Skamil "resumed by a tracee"); 47731.1Skamil} 47741.1Skamil 47751.1SkamilATF_TC_BODY(suspend1, tc) 47761.1Skamil{ 47771.1Skamil const int exitval = 5; 47781.1Skamil const int sigval = SIGSTOP; 47791.1Skamil pid_t child, wpid; 47801.1Skamil#if defined(TWAIT_HAVE_STATUS) 47811.1Skamil int status; 47821.1Skamil#endif 47831.1Skamil ucontext_t uc; 47841.1Skamil lwpid_t lid; 47851.1Skamil static const size_t ssize = 16*1024; 47861.1Skamil void *stack; 47871.1Skamil struct ptrace_lwpinfo pl; 47881.1Skamil struct ptrace_siginfo psi; 47891.1Skamil volatile int go = 0; 47901.1Skamil 47911.17Skamil // Feature pending for refactoring 47921.17Skamil atf_tc_expect_fail("PR kern/51995"); 47931.17Skamil 47941.16Skamil // Hangs with qemu 47951.16Skamil ATF_REQUIRE(0 && "In order to get reliable failure, abort"); 47961.16Skamil 47971.13Schristos DPRINTF("Before forking process PID=%d\n", getpid()); 47981.13Schristos SYSCALL_REQUIRE((child = fork()) != -1); 47991.1Skamil if (child == 0) { 48001.13Schristos DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 48011.1Skamil FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 48021.1Skamil 48031.13Schristos DPRINTF("Before raising %s from child\n", strsignal(sigval)); 48041.1Skamil FORKEE_ASSERT(raise(sigval) == 0); 48051.1Skamil 48061.13Schristos DPRINTF("Before allocating memory for stack in child\n"); 48071.1Skamil FORKEE_ASSERT((stack = malloc(ssize)) != NULL); 48081.1Skamil 48091.13Schristos DPRINTF("Before making context for new lwp in child\n"); 48101.1Skamil _lwp_makecontext(&uc, lwp_main_stop, NULL, NULL, stack, ssize); 48111.1Skamil 48121.13Schristos DPRINTF("Before creating new in child\n"); 48131.1Skamil FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0); 48141.1Skamil 48151.1Skamil while (go == 0) 48161.1Skamil continue; 48171.1Skamil 48181.1Skamil raise(SIGINT); 48191.1Skamil 48201.1Skamil FORKEE_ASSERT(_lwp_continue(lid) == 0); 48211.1Skamil 48221.13Schristos DPRINTF("Before waiting for lwp %d to exit\n", lid); 48231.1Skamil FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0); 48241.1Skamil 48251.13Schristos DPRINTF("Before verifying that reported %d and running lid %d " 48261.1Skamil "are the same\n", lid, the_lwp_id); 48271.1Skamil FORKEE_ASSERT_EQ(lid, the_lwp_id); 48281.1Skamil 48291.13Schristos DPRINTF("Before exiting of the child process\n"); 48301.1Skamil _exit(exitval); 48311.1Skamil } 48321.13Schristos DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 48331.1Skamil 48341.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 48351.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 48361.1Skamil 48371.1Skamil validate_status_stopped(status, sigval); 48381.1Skamil 48391.13Schristos DPRINTF("Before resuming the child process where it left off and " 48401.1Skamil "without signal to be sent\n"); 48411.13Schristos SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 48421.1Skamil 48431.13Schristos DPRINTF("Before calling %s() for the child - expected stopped " 48441.1Skamil "SIGTRAP\n", TWAIT_FNAME); 48451.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 48461.1Skamil 48471.1Skamil validate_status_stopped(status, SIGTRAP); 48481.1Skamil 48491.13Schristos DPRINTF("Before reading siginfo and lwpid_t\n"); 48501.13Schristos SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &psi, sizeof(psi)) != -1); 48511.1Skamil 48521.13Schristos DPRINTF("Before suspending LWP %d\n", psi.psi_lwpid); 48531.13Schristos SYSCALL_REQUIRE(ptrace(PT_SUSPEND, child, NULL, psi.psi_lwpid) != -1); 48541.1Skamil 48551.13Schristos DPRINTF("Write new go to tracee (PID=%d) from tracer (PID=%d)\n", 48561.1Skamil child, getpid()); 48571.13Schristos SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, __UNVOLATILE(&go), 1) != -1); 48581.1Skamil 48591.13Schristos DPRINTF("Before resuming the child process where it left off and " 48601.1Skamil "without signal to be sent\n"); 48611.13Schristos SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 48621.1Skamil 48631.13Schristos DPRINTF("Before calling %s() for the child - expected stopped " 48641.1Skamil "SIGINT\n", TWAIT_FNAME); 48651.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 48661.1Skamil 48671.1Skamil validate_status_stopped(status, SIGINT); 48681.1Skamil 48691.1Skamil pl.pl_lwpid = 0; 48701.1Skamil 48711.13Schristos SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &pl, sizeof(pl)) != -1); 48721.1Skamil while (pl.pl_lwpid != 0) { 48731.1Skamil 48741.13Schristos SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &pl, sizeof(pl)) != -1); 48751.1Skamil switch (pl.pl_lwpid) { 48761.1Skamil case 1: 48771.1Skamil ATF_REQUIRE_EQ(pl.pl_event, PL_EVENT_SIGNAL); 48781.1Skamil break; 48791.1Skamil case 2: 48801.1Skamil ATF_REQUIRE_EQ(pl.pl_event, PL_EVENT_SUSPENDED); 48811.1Skamil break; 48821.1Skamil } 48831.1Skamil } 48841.1Skamil 48851.13Schristos DPRINTF("Before resuming the child process where it left off and " 48861.1Skamil "without signal to be sent\n"); 48871.13Schristos SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 48881.1Skamil 48891.13Schristos DPRINTF("Before calling %s() for the child - expected exited\n", 48901.1Skamil TWAIT_FNAME); 48911.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 48921.1Skamil 48931.1Skamil validate_status_exited(status, exitval); 48941.1Skamil 48951.13Schristos DPRINTF("Before calling %s() for the child - expected no process\n", 48961.1Skamil TWAIT_FNAME); 48971.1Skamil TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 48981.1Skamil} 48991.1Skamil 49001.1SkamilATF_TC(suspend2); 49011.1SkamilATF_TC_HEAD(suspend2, tc) 49021.1Skamil{ 49031.1Skamil atf_tc_set_md_var(tc, "descr", 49041.1Skamil "Verify that the while the only thread within a process is " 49051.1Skamil "suspended, the whole process cannot be unstopped"); 49061.1Skamil} 49071.1Skamil 49081.1SkamilATF_TC_BODY(suspend2, tc) 49091.1Skamil{ 49101.1Skamil const int exitval = 5; 49111.1Skamil const int sigval = SIGSTOP; 49121.1Skamil pid_t child, wpid; 49131.1Skamil#if defined(TWAIT_HAVE_STATUS) 49141.1Skamil int status; 49151.1Skamil#endif 49161.1Skamil struct ptrace_siginfo psi; 49171.1Skamil 49181.17Skamil // Feature pending for refactoring 49191.17Skamil atf_tc_expect_fail("PR kern/51995"); 49201.17Skamil 49211.16Skamil // Hangs with qemu 49221.16Skamil ATF_REQUIRE(0 && "In order to get reliable failure, abort"); 49231.16Skamil 49241.13Schristos DPRINTF("Before forking process PID=%d\n", getpid()); 49251.13Schristos SYSCALL_REQUIRE((child = fork()) != -1); 49261.1Skamil if (child == 0) { 49271.13Schristos DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 49281.1Skamil FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 49291.1Skamil 49301.13Schristos DPRINTF("Before raising %s from child\n", strsignal(sigval)); 49311.1Skamil FORKEE_ASSERT(raise(sigval) == 0); 49321.1Skamil 49331.13Schristos DPRINTF("Before exiting of the child process\n"); 49341.1Skamil _exit(exitval); 49351.1Skamil } 49361.13Schristos DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 49371.1Skamil 49381.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 49391.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 49401.1Skamil 49411.1Skamil validate_status_stopped(status, sigval); 49421.1Skamil 49431.13Schristos DPRINTF("Before reading siginfo and lwpid_t\n"); 49441.13Schristos SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &psi, sizeof(psi)) != -1); 49451.1Skamil 49461.13Schristos DPRINTF("Before suspending LWP %d\n", psi.psi_lwpid); 49471.13Schristos SYSCALL_REQUIRE(ptrace(PT_SUSPEND, child, NULL, psi.psi_lwpid) != -1); 49481.1Skamil 49491.13Schristos DPRINTF("Before resuming the child process where it left off and " 49501.1Skamil "without signal to be sent\n"); 49511.1Skamil ATF_REQUIRE_ERRNO(EDEADLK, 49521.1Skamil ptrace(PT_CONTINUE, child, (void *)1, 0) == -1); 49531.1Skamil 49541.13Schristos DPRINTF("Before resuming LWP %d\n", psi.psi_lwpid); 49551.13Schristos SYSCALL_REQUIRE(ptrace(PT_RESUME, child, NULL, psi.psi_lwpid) != -1); 49561.1Skamil 49571.13Schristos DPRINTF("Before resuming the child process where it left off and " 49581.1Skamil "without signal to be sent\n"); 49591.13Schristos SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 49601.1Skamil 49611.13Schristos DPRINTF("Before calling %s() for the child - expected exited\n", 49621.1Skamil TWAIT_FNAME); 49631.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 49641.1Skamil 49651.1Skamil validate_status_exited(status, exitval); 49661.1Skamil 49671.13Schristos DPRINTF("Before calling %s() for the child - expected no process\n", 49681.1Skamil TWAIT_FNAME); 49691.1Skamil TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 49701.1Skamil} 49711.1Skamil 49721.1SkamilATF_TC(resume1); 49731.1SkamilATF_TC_HEAD(resume1, tc) 49741.1Skamil{ 49751.1Skamil atf_tc_set_md_var(tc, "timeout", "5"); 49761.1Skamil atf_tc_set_md_var(tc, "descr", 49771.1Skamil "Verify that a thread can be suspended by a debugger and later " 49781.1Skamil "resumed by the debugger"); 49791.1Skamil} 49801.1Skamil 49811.1SkamilATF_TC_BODY(resume1, tc) 49821.1Skamil{ 49831.1Skamil struct msg_fds fds; 49841.1Skamil const int exitval = 5; 49851.1Skamil const int sigval = SIGSTOP; 49861.1Skamil pid_t child, wpid; 49871.1Skamil uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */ 49881.1Skamil#if defined(TWAIT_HAVE_STATUS) 49891.1Skamil int status; 49901.1Skamil#endif 49911.1Skamil ucontext_t uc; 49921.1Skamil lwpid_t lid; 49931.1Skamil static const size_t ssize = 16*1024; 49941.1Skamil void *stack; 49951.1Skamil struct ptrace_lwpinfo pl; 49961.1Skamil struct ptrace_siginfo psi; 49971.1Skamil 49981.17Skamil // Feature pending for refactoring 49991.17Skamil atf_tc_expect_fail("PR kern/51995"); 50001.17Skamil 50011.15Schristos // Hangs with qemu 50021.15Schristos ATF_REQUIRE(0 && "In order to get reliable failure, abort"); 50031.1Skamil 50041.13Schristos SYSCALL_REQUIRE(msg_open(&fds) == 0); 50051.1Skamil 50061.13Schristos DPRINTF("Before forking process PID=%d\n", getpid()); 50071.13Schristos SYSCALL_REQUIRE((child = fork()) != -1); 50081.1Skamil if (child == 0) { 50091.13Schristos DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 50101.1Skamil FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 50111.1Skamil 50121.13Schristos DPRINTF("Before raising %s from child\n", strsignal(sigval)); 50131.1Skamil FORKEE_ASSERT(raise(sigval) == 0); 50141.1Skamil 50151.13Schristos DPRINTF("Before allocating memory for stack in child\n"); 50161.1Skamil FORKEE_ASSERT((stack = malloc(ssize)) != NULL); 50171.1Skamil 50181.13Schristos DPRINTF("Before making context for new lwp in child\n"); 50191.1Skamil _lwp_makecontext(&uc, lwp_main_stop, NULL, NULL, stack, ssize); 50201.1Skamil 50211.13Schristos DPRINTF("Before creating new in child\n"); 50221.1Skamil FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0); 50231.1Skamil 50241.1Skamil CHILD_TO_PARENT("Message", fds, msg); 50251.1Skamil 50261.1Skamil raise(SIGINT); 50271.1Skamil 50281.13Schristos DPRINTF("Before waiting for lwp %d to exit\n", lid); 50291.1Skamil FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0); 50301.1Skamil 50311.13Schristos DPRINTF("Before verifying that reported %d and running lid %d " 50321.1Skamil "are the same\n", lid, the_lwp_id); 50331.1Skamil FORKEE_ASSERT_EQ(lid, the_lwp_id); 50341.1Skamil 50351.13Schristos DPRINTF("Before exiting of the child process\n"); 50361.1Skamil _exit(exitval); 50371.1Skamil } 50381.13Schristos DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 50391.1Skamil 50401.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 50411.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 50421.1Skamil 50431.1Skamil validate_status_stopped(status, sigval); 50441.1Skamil 50451.13Schristos DPRINTF("Before resuming the child process where it left off and " 50461.1Skamil "without signal to be sent\n"); 50471.13Schristos SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 50481.1Skamil 50491.13Schristos DPRINTF("Before calling %s() for the child - expected stopped " 50501.1Skamil "SIGTRAP\n", TWAIT_FNAME); 50511.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 50521.1Skamil 50531.1Skamil validate_status_stopped(status, SIGTRAP); 50541.1Skamil 50551.13Schristos DPRINTF("Before reading siginfo and lwpid_t\n"); 50561.13Schristos SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &psi, sizeof(psi)) != -1); 50571.1Skamil 50581.13Schristos DPRINTF("Before suspending LWP %d\n", psi.psi_lwpid); 50591.13Schristos SYSCALL_REQUIRE(ptrace(PT_SUSPEND, child, NULL, psi.psi_lwpid) != -1); 50601.1Skamil 50611.1Skamil PARENT_FROM_CHILD("Message", fds, msg); 50621.1Skamil 50631.13Schristos DPRINTF("Before resuming the child process where it left off and " 50641.1Skamil "without signal to be sent\n"); 50651.13Schristos SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 50661.1Skamil 50671.13Schristos DPRINTF("Before calling %s() for the child - expected stopped " 50681.1Skamil "SIGINT\n", TWAIT_FNAME); 50691.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 50701.1Skamil 50711.1Skamil validate_status_stopped(status, SIGINT); 50721.1Skamil 50731.1Skamil pl.pl_lwpid = 0; 50741.1Skamil 50751.13Schristos SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &pl, sizeof(pl)) != -1); 50761.1Skamil while (pl.pl_lwpid != 0) { 50771.13Schristos SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &pl, sizeof(pl)) != -1); 50781.1Skamil switch (pl.pl_lwpid) { 50791.1Skamil case 1: 50801.1Skamil ATF_REQUIRE_EQ(pl.pl_event, PL_EVENT_SIGNAL); 50811.1Skamil break; 50821.1Skamil case 2: 50831.1Skamil ATF_REQUIRE_EQ(pl.pl_event, PL_EVENT_SUSPENDED); 50841.1Skamil break; 50851.1Skamil } 50861.1Skamil } 50871.1Skamil 50881.13Schristos DPRINTF("Before resuming LWP %d\n", psi.psi_lwpid); 50891.13Schristos SYSCALL_REQUIRE(ptrace(PT_RESUME, child, NULL, psi.psi_lwpid) != -1); 50901.1Skamil 50911.13Schristos DPRINTF("Before resuming the child process where it left off and " 50921.1Skamil "without signal to be sent\n"); 50931.13Schristos SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 50941.1Skamil 50951.13Schristos DPRINTF("Before calling %s() for the child - expected exited\n", 50961.1Skamil TWAIT_FNAME); 50971.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 50981.1Skamil 50991.1Skamil validate_status_exited(status, exitval); 51001.1Skamil 51011.13Schristos DPRINTF("Before calling %s() for the child - expected no process\n", 51021.1Skamil TWAIT_FNAME); 51031.1Skamil TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 51041.1Skamil 51051.1Skamil msg_close(&fds); 51061.1Skamil 51071.13Schristos DPRINTF("XXX: Test worked this time but for consistency timeout it\n"); 51081.1Skamil sleep(10); 51091.1Skamil} 51101.1Skamil 51111.1SkamilATF_TC(syscall1); 51121.1SkamilATF_TC_HEAD(syscall1, tc) 51131.1Skamil{ 51141.1Skamil atf_tc_set_md_var(tc, "descr", 51151.1Skamil "Verify that getpid(2) can be traced with PT_SYSCALL"); 51161.1Skamil} 51171.1Skamil 51181.1SkamilATF_TC_BODY(syscall1, tc) 51191.1Skamil{ 51201.1Skamil const int exitval = 5; 51211.1Skamil const int sigval = SIGSTOP; 51221.1Skamil pid_t child, wpid; 51231.1Skamil#if defined(TWAIT_HAVE_STATUS) 51241.1Skamil int status; 51251.1Skamil#endif 51261.1Skamil struct ptrace_siginfo info; 51271.1Skamil memset(&info, 0, sizeof(info)); 51281.1Skamil 51291.13Schristos DPRINTF("Before forking process PID=%d\n", getpid()); 51301.13Schristos SYSCALL_REQUIRE((child = fork()) != -1); 51311.1Skamil if (child == 0) { 51321.13Schristos DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 51331.1Skamil FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 51341.1Skamil 51351.13Schristos DPRINTF("Before raising %s from child\n", strsignal(sigval)); 51361.1Skamil FORKEE_ASSERT(raise(sigval) == 0); 51371.1Skamil 51381.1Skamil syscall(SYS_getpid); 51391.1Skamil 51401.13Schristos DPRINTF("Before exiting of the child process\n"); 51411.1Skamil _exit(exitval); 51421.1Skamil } 51431.13Schristos DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 51441.1Skamil 51451.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 51461.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 51471.1Skamil 51481.1Skamil validate_status_stopped(status, sigval); 51491.1Skamil 51501.13Schristos DPRINTF("Before resuming the child process where it left off and " 51511.1Skamil "without signal to be sent\n"); 51521.13Schristos SYSCALL_REQUIRE(ptrace(PT_SYSCALL, child, (void *)1, 0) != -1); 51531.1Skamil 51541.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 51551.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 51561.1Skamil 51571.1Skamil validate_status_stopped(status, SIGTRAP); 51581.1Skamil 51591.13Schristos DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 51601.13Schristos SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 51611.1Skamil 51621.38Skamil DPRINTF("Before checking siginfo_t and lwpid\n"); 51631.38Skamil ATF_REQUIRE_EQ(info.psi_lwpid, 1); 51641.1Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); 51651.1Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_SCE); 51661.1Skamil 51671.13Schristos DPRINTF("Before resuming the child process where it left off and " 51681.1Skamil "without signal to be sent\n"); 51691.13Schristos SYSCALL_REQUIRE(ptrace(PT_SYSCALL, child, (void *)1, 0) != -1); 51701.1Skamil 51711.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 51721.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 51731.1Skamil 51741.1Skamil validate_status_stopped(status, SIGTRAP); 51751.1Skamil 51761.13Schristos DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 51771.13Schristos SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 51781.1Skamil 51791.38Skamil DPRINTF("Before checking siginfo_t and lwpid\n"); 51801.38Skamil ATF_REQUIRE_EQ(info.psi_lwpid, 1); 51811.1Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); 51821.1Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_SCX); 51831.1Skamil 51841.13Schristos DPRINTF("Before resuming the child process where it left off and " 51851.1Skamil "without signal to be sent\n"); 51861.13Schristos SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 51871.1Skamil 51881.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 51891.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 51901.1Skamil 51911.1Skamil validate_status_exited(status, exitval); 51921.1Skamil 51931.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 51941.1Skamil TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 51951.1Skamil} 51961.1Skamil 51971.1SkamilATF_TC(syscallemu1); 51981.1SkamilATF_TC_HEAD(syscallemu1, tc) 51991.1Skamil{ 52001.1Skamil atf_tc_set_md_var(tc, "descr", 52011.1Skamil "Verify that exit(2) can be intercepted with PT_SYSCALLEMU"); 52021.1Skamil} 52031.1Skamil 52041.1SkamilATF_TC_BODY(syscallemu1, tc) 52051.1Skamil{ 52061.1Skamil const int exitval = 5; 52071.1Skamil const int sigval = SIGSTOP; 52081.1Skamil pid_t child, wpid; 52091.1Skamil#if defined(TWAIT_HAVE_STATUS) 52101.1Skamil int status; 52111.1Skamil#endif 52121.1Skamil 52131.6Skamil#if defined(__sparc__) && !defined(__sparc64__) 52141.6Skamil /* syscallemu does not work on sparc (32-bit) */ 52151.6Skamil atf_tc_expect_fail("PR kern/52166"); 52161.6Skamil#endif 52171.6Skamil 52181.13Schristos DPRINTF("Before forking process PID=%d\n", getpid()); 52191.13Schristos SYSCALL_REQUIRE((child = fork()) != -1); 52201.1Skamil if (child == 0) { 52211.13Schristos DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 52221.1Skamil FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 52231.1Skamil 52241.13Schristos DPRINTF("Before raising %s from child\n", strsignal(sigval)); 52251.1Skamil FORKEE_ASSERT(raise(sigval) == 0); 52261.1Skamil 52271.1Skamil syscall(SYS_exit, 100); 52281.1Skamil 52291.13Schristos DPRINTF("Before exiting of the child process\n"); 52301.1Skamil _exit(exitval); 52311.1Skamil } 52321.13Schristos DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 52331.1Skamil 52341.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 52351.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 52361.1Skamil 52371.1Skamil validate_status_stopped(status, sigval); 52381.1Skamil 52391.13Schristos DPRINTF("Before resuming the child process where it left off and " 52401.1Skamil "without signal to be sent\n"); 52411.13Schristos SYSCALL_REQUIRE(ptrace(PT_SYSCALL, child, (void *)1, 0) != -1); 52421.1Skamil 52431.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 52441.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 52451.1Skamil 52461.1Skamil validate_status_stopped(status, SIGTRAP); 52471.1Skamil 52481.13Schristos DPRINTF("Set SYSCALLEMU for intercepted syscall\n"); 52491.13Schristos SYSCALL_REQUIRE(ptrace(PT_SYSCALLEMU, child, (void *)1, 0) != -1); 52501.1Skamil 52511.13Schristos DPRINTF("Before resuming the child process where it left off and " 52521.1Skamil "without signal to be sent\n"); 52531.13Schristos SYSCALL_REQUIRE(ptrace(PT_SYSCALL, child, (void *)1, 0) != -1); 52541.1Skamil 52551.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 52561.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 52571.1Skamil 52581.1Skamil validate_status_stopped(status, SIGTRAP); 52591.1Skamil 52601.13Schristos DPRINTF("Before resuming the child process where it left off and " 52611.1Skamil "without signal to be sent\n"); 52621.13Schristos SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 52631.1Skamil 52641.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 52651.1Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 52661.1Skamil 52671.1Skamil validate_status_exited(status, exitval); 52681.1Skamil 52691.13Schristos DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 52701.1Skamil TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 52711.1Skamil} 52721.1Skamil 52731.1Skamil#include "t_ptrace_amd64_wait.h" 52741.1Skamil#include "t_ptrace_i386_wait.h" 52751.1Skamil#include "t_ptrace_x86_wait.h" 52761.1Skamil 52771.1SkamilATF_TP_ADD_TCS(tp) 52781.1Skamil{ 52791.1Skamil setvbuf(stdout, NULL, _IONBF, 0); 52801.1Skamil setvbuf(stderr, NULL, _IONBF, 0); 52811.33Skamil 52821.36Skamil ATF_TP_ADD_TC(tp, traceme_raise1); 52831.33Skamil ATF_TP_ADD_TC(tp, traceme_raise2); 52841.33Skamil ATF_TP_ADD_TC(tp, traceme_raise3); 52851.33Skamil ATF_TP_ADD_TC(tp, traceme_raise4); 52861.33Skamil ATF_TP_ADD_TC(tp, traceme_raise5); 52871.85Skamil ATF_TP_ADD_TC(tp, traceme_raise6); 52881.85Skamil ATF_TP_ADD_TC(tp, traceme_raise7); 52891.85Skamil ATF_TP_ADD_TC(tp, traceme_raise8); 52901.85Skamil ATF_TP_ADD_TC(tp, traceme_raise9); 52911.85Skamil ATF_TP_ADD_TC(tp, traceme_raise10); 52921.33Skamil 52931.86Skamil ATF_TP_ADD_TC(tp, traceme_raisesignal_masked1); 52941.86Skamil ATF_TP_ADD_TC(tp, traceme_raisesignal_masked2); 52951.86Skamil ATF_TP_ADD_TC(tp, traceme_raisesignal_masked3); 52961.86Skamil ATF_TP_ADD_TC(tp, traceme_raisesignal_masked4); 52971.86Skamil ATF_TP_ADD_TC(tp, traceme_raisesignal_masked5); 52981.86Skamil ATF_TP_ADD_TC(tp, traceme_raisesignal_masked6); 52991.86Skamil ATF_TP_ADD_TC(tp, traceme_raisesignal_masked7); 53001.86Skamil ATF_TP_ADD_TC(tp, traceme_raisesignal_masked8); 53011.86Skamil 53021.59Skamil ATF_TP_ADD_TC(tp, traceme_crash_trap); 53031.59Skamil ATF_TP_ADD_TC(tp, traceme_crash_segv); 53041.71Skamil ATF_TP_ADD_TC(tp, traceme_crash_ill); 53051.59Skamil ATF_TP_ADD_TC(tp, traceme_crash_fpe); 53061.59Skamil ATF_TP_ADD_TC(tp, traceme_crash_bus); 53071.59Skamil 53081.50Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_handle1); 53091.50Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_handle2); 53101.50Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_handle3); 53111.85Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_handle4); 53121.85Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_handle5); 53131.85Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_handle6); 53141.85Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_handle7); 53151.85Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_handle8); 53161.50Skamil 53171.50Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_masked1); 53181.50Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_masked2); 53191.50Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_masked3); 53201.85Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_masked4); 53211.85Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_masked5); 53221.85Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_masked6); 53231.85Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_masked7); 53241.85Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_masked8); 53251.50Skamil 53261.50Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored1); 53271.50Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored2); 53281.50Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored3); 53291.85Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored4); 53301.85Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored5); 53311.85Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored6); 53321.85Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored7); 53331.85Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored8); 53341.50Skamil 53351.50Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_simple1); 53361.50Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_simple2); 53371.50Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_simple3); 53381.50Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_simple4); 53391.50Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_simple5); 53401.85Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_simple6); 53411.85Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_simple7); 53421.85Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_simple8); 53431.85Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_simple9); 53441.85Skamil ATF_TP_ADD_TC(tp, traceme_sendsignal_simple10); 53451.1Skamil 53461.37Skamil ATF_TP_ADD_TC(tp, traceme_pid1_parent); 53471.37Skamil 53481.40Skamil ATF_TP_ADD_TC(tp, traceme_vfork_raise1); 53491.46Skamil ATF_TP_ADD_TC(tp, traceme_vfork_raise2); 53501.40Skamil ATF_TP_ADD_TC(tp, traceme_vfork_raise3); 53511.40Skamil ATF_TP_ADD_TC(tp, traceme_vfork_raise4); 53521.40Skamil ATF_TP_ADD_TC(tp, traceme_vfork_raise5); 53531.47Skamil ATF_TP_ADD_TC(tp, traceme_vfork_raise6); 53541.47Skamil ATF_TP_ADD_TC(tp, traceme_vfork_raise7); 53551.47Skamil ATF_TP_ADD_TC(tp, traceme_vfork_raise8); 53561.85Skamil ATF_TP_ADD_TC(tp, traceme_vfork_raise9); 53571.85Skamil ATF_TP_ADD_TC(tp, traceme_vfork_raise10); 53581.85Skamil ATF_TP_ADD_TC(tp, traceme_vfork_raise11); 53591.85Skamil ATF_TP_ADD_TC(tp, traceme_vfork_raise12); 53601.85Skamil ATF_TP_ADD_TC(tp, traceme_vfork_raise13); 53611.40Skamil 53621.52Skamil ATF_TP_ADD_TC(tp, traceme_vfork_crash_trap); 53631.52Skamil ATF_TP_ADD_TC(tp, traceme_vfork_crash_segv); 53641.71Skamil ATF_TP_ADD_TC(tp, traceme_vfork_crash_ill); 53651.52Skamil ATF_TP_ADD_TC(tp, traceme_vfork_crash_fpe); 53661.52Skamil ATF_TP_ADD_TC(tp, traceme_vfork_crash_bus); 53671.41Skamil 53681.43Skamil ATF_TP_ADD_TC(tp, traceme_vfork_exec); 53691.43Skamil 53701.59Skamil ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_sees_crash_trap); 53711.59Skamil ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_sees_crash_segv); 53721.71Skamil ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_sees_crash_ill); 53731.59Skamil ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_sees_crash_fpe); 53741.59Skamil ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_sees_crash_bus); 53751.59Skamil 53761.51Skamil ATF_TP_ADD_TC_HAVE_PID(tp, tracer_sees_terminaton_before_the_parent); 53771.51Skamil ATF_TP_ADD_TC_HAVE_PID(tp, tracer_sysctl_lookup_without_duplicates); 53781.61Skre ATF_TP_ADD_TC_HAVE_PID(tp, 53791.61Skre unrelated_tracer_sees_terminaton_before_the_parent); 53801.67Skamil ATF_TP_ADD_TC_HAVE_PID(tp, tracer_attach_to_unrelated_stopped_process); 53811.51Skamil 53821.51Skamil ATF_TP_ADD_TC(tp, parent_attach_to_its_child); 53831.66Skamil ATF_TP_ADD_TC(tp, parent_attach_to_its_stopped_child); 53841.51Skamil 53851.51Skamil ATF_TP_ADD_TC(tp, child_attach_to_its_parent); 53861.65Skamil ATF_TP_ADD_TC(tp, child_attach_to_its_stopped_parent); 53871.51Skamil 53881.51Skamil ATF_TP_ADD_TC_HAVE_PID(tp, 53891.51Skamil tracee_sees_its_original_parent_getppid); 53901.51Skamil ATF_TP_ADD_TC_HAVE_PID(tp, 53911.51Skamil tracee_sees_its_original_parent_sysctl_kinfo_proc2); 53921.51Skamil ATF_TP_ADD_TC_HAVE_PID(tp, 53931.51Skamil tracee_sees_its_original_parent_procfs_status); 53941.1Skamil 53951.53Skamil ATF_TP_ADD_TC(tp, eventmask_preserved_empty); 53961.53Skamil ATF_TP_ADD_TC(tp, eventmask_preserved_fork); 53971.53Skamil ATF_TP_ADD_TC(tp, eventmask_preserved_vfork); 53981.53Skamil ATF_TP_ADD_TC(tp, eventmask_preserved_vfork_done); 53991.53Skamil ATF_TP_ADD_TC(tp, eventmask_preserved_lwp_create); 54001.53Skamil ATF_TP_ADD_TC(tp, eventmask_preserved_lwp_exit); 54011.1Skamil 54021.31Skamil ATF_TP_ADD_TC(tp, fork1); 54031.31Skamil ATF_TP_ADD_TC_HAVE_PID(tp, fork2); 54041.31Skamil ATF_TP_ADD_TC_HAVE_PID(tp, fork3); 54051.31Skamil ATF_TP_ADD_TC_HAVE_PID(tp, fork4); 54061.31Skamil ATF_TP_ADD_TC(tp, fork5); 54071.31Skamil ATF_TP_ADD_TC_HAVE_PID(tp, fork6); 54081.31Skamil ATF_TP_ADD_TC_HAVE_PID(tp, fork7); 54091.31Skamil ATF_TP_ADD_TC_HAVE_PID(tp, fork8); 54101.31Skamil 54111.31Skamil ATF_TP_ADD_TC(tp, vfork1); 54121.31Skamil ATF_TP_ADD_TC_HAVE_PID(tp, vfork2); 54131.31Skamil ATF_TP_ADD_TC_HAVE_PID(tp, vfork3); 54141.31Skamil ATF_TP_ADD_TC_HAVE_PID(tp, vfork4); 54151.31Skamil ATF_TP_ADD_TC(tp, vfork5); 54161.31Skamil ATF_TP_ADD_TC_HAVE_PID(tp, vfork6); 54171.64Smartin// thes tests hang on SMP machines, disable them for now 54181.64Smartin// ATF_TP_ADD_TC_HAVE_PID(tp, vfork7); 54191.64Smartin// ATF_TP_ADD_TC_HAVE_PID(tp, vfork8); 54201.1Skamil 54211.54Skamil ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_8); 54221.54Skamil ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_16); 54231.54Skamil ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_32); 54241.54Skamil ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_64); 54251.54Skamil 54261.54Skamil ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_8); 54271.54Skamil ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_16); 54281.54Skamil ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_32); 54291.54Skamil ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_64); 54301.54Skamil 54311.54Skamil ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_8); 54321.54Skamil ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_16); 54331.54Skamil ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_32); 54341.54Skamil ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_64); 54351.54Skamil 54361.54Skamil ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_8); 54371.54Skamil ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_16); 54381.54Skamil ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_32); 54391.54Skamil ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_64); 54401.54Skamil 54411.54Skamil ATF_TP_ADD_TC(tp, bytes_transfer_read_d); 54421.54Skamil ATF_TP_ADD_TC(tp, bytes_transfer_read_i); 54431.54Skamil ATF_TP_ADD_TC(tp, bytes_transfer_write_d); 54441.54Skamil ATF_TP_ADD_TC(tp, bytes_transfer_write_i); 54451.54Skamil 54461.54Skamil ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_8_text); 54471.54Skamil ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_16_text); 54481.54Skamil ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_32_text); 54491.54Skamil ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_64_text); 54501.54Skamil 54511.54Skamil ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_8_text); 54521.54Skamil ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_16_text); 54531.54Skamil ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_32_text); 54541.54Skamil ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_64_text); 54551.54Skamil 54561.54Skamil ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_8_text); 54571.54Skamil ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_16_text); 54581.54Skamil ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_32_text); 54591.54Skamil ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_64_text); 54601.54Skamil 54611.54Skamil ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_8_text); 54621.54Skamil ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_16_text); 54631.54Skamil ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_32_text); 54641.54Skamil ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_64_text); 54651.54Skamil 54661.54Skamil ATF_TP_ADD_TC(tp, bytes_transfer_read_d_text); 54671.54Skamil ATF_TP_ADD_TC(tp, bytes_transfer_read_i_text); 54681.54Skamil ATF_TP_ADD_TC(tp, bytes_transfer_write_d_text); 54691.54Skamil ATF_TP_ADD_TC(tp, bytes_transfer_write_i_text); 54701.1Skamil 54711.54Skamil ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_auxv); 54721.1Skamil 54731.72Skamil ATF_TP_ADD_TC_HAVE_GPREGS(tp, access_regs1); 54741.72Skamil ATF_TP_ADD_TC_HAVE_GPREGS(tp, access_regs2); 54751.72Skamil ATF_TP_ADD_TC_HAVE_GPREGS(tp, access_regs3); 54761.72Skamil ATF_TP_ADD_TC_HAVE_GPREGS(tp, access_regs4); 54771.72Skamil ATF_TP_ADD_TC_HAVE_GPREGS(tp, access_regs5); 54781.72Skamil ATF_TP_ADD_TC_HAVE_GPREGS(tp, access_regs6); 54791.1Skamil 54801.72Skamil ATF_TP_ADD_TC_HAVE_FPREGS(tp, access_fpregs1); 54811.72Skamil ATF_TP_ADD_TC_HAVE_FPREGS(tp, access_fpregs2); 54821.1Skamil 54831.1Skamil ATF_TP_ADD_TC_PT_STEP(tp, step1); 54841.1Skamil ATF_TP_ADD_TC_PT_STEP(tp, step2); 54851.1Skamil ATF_TP_ADD_TC_PT_STEP(tp, step3); 54861.1Skamil ATF_TP_ADD_TC_PT_STEP(tp, step4); 54871.1Skamil 54881.2Skamil ATF_TP_ADD_TC_PT_STEP(tp, setstep1); 54891.2Skamil ATF_TP_ADD_TC_PT_STEP(tp, setstep2); 54901.2Skamil ATF_TP_ADD_TC_PT_STEP(tp, setstep3); 54911.2Skamil ATF_TP_ADD_TC_PT_STEP(tp, setstep4); 54921.2Skamil 54931.1Skamil ATF_TP_ADD_TC(tp, kill1); 54941.1Skamil ATF_TP_ADD_TC(tp, kill2); 54951.75Skamil ATF_TP_ADD_TC(tp, kill3); 54961.1Skamil 54971.77Skamil ATF_TP_ADD_TC(tp, traceme_lwpinfo0); 54981.77Skamil ATF_TP_ADD_TC(tp, traceme_lwpinfo1); 54991.77Skamil ATF_TP_ADD_TC(tp, traceme_lwpinfo2); 55001.77Skamil ATF_TP_ADD_TC(tp, traceme_lwpinfo3); 55011.77Skamil 55021.77Skamil ATF_TP_ADD_TC_HAVE_PID(tp, attach_lwpinfo0); 55031.77Skamil ATF_TP_ADD_TC_HAVE_PID(tp, attach_lwpinfo1); 55041.77Skamil ATF_TP_ADD_TC_HAVE_PID(tp, attach_lwpinfo2); 55051.77Skamil ATF_TP_ADD_TC_HAVE_PID(tp, attach_lwpinfo3); 55061.1Skamil 55071.79Skamil ATF_TP_ADD_TC(tp, siginfo_set_unmodified); 55081.79Skamil ATF_TP_ADD_TC(tp, siginfo_set_faked); 55091.79Skamil 55101.82Skamil ATF_TP_ADD_TC(tp, traceme_exec); 55111.1Skamil 55121.83Skamil ATF_TP_ADD_TC(tp, trace_thread1); 55131.83Skamil ATF_TP_ADD_TC(tp, trace_thread2); 55141.83Skamil ATF_TP_ADD_TC(tp, trace_thread3); 55151.83Skamil ATF_TP_ADD_TC(tp, trace_thread4); 55161.1Skamil 55171.84Skamil ATF_TP_ADD_TC(tp, signal_mask_unrelated); 55181.84Skamil 55191.1Skamil ATF_TP_ADD_TC(tp, signal3); 55201.1Skamil ATF_TP_ADD_TC_PT_STEP(tp, signal4); 55211.1Skamil ATF_TP_ADD_TC(tp, signal5); 55221.1Skamil ATF_TP_ADD_TC_HAVE_PID(tp, signal6); 55231.1Skamil ATF_TP_ADD_TC_HAVE_PID(tp, signal7); 55241.1Skamil ATF_TP_ADD_TC(tp, signal8); 55251.1Skamil ATF_TP_ADD_TC(tp, signal9); 55261.1Skamil ATF_TP_ADD_TC(tp, signal10); 55271.1Skamil 55281.1Skamil ATF_TP_ADD_TC(tp, suspend1); 55291.1Skamil ATF_TP_ADD_TC(tp, suspend2); 55301.1Skamil 55311.1Skamil ATF_TP_ADD_TC(tp, resume1); 55321.1Skamil 55331.1Skamil ATF_TP_ADD_TC(tp, syscall1); 55341.1Skamil 55351.1Skamil ATF_TP_ADD_TC(tp, syscallemu1); 55361.1Skamil 55371.1Skamil ATF_TP_ADD_TCS_PTRACE_WAIT_AMD64(); 55381.1Skamil ATF_TP_ADD_TCS_PTRACE_WAIT_I386(); 55391.1Skamil ATF_TP_ADD_TCS_PTRACE_WAIT_X86(); 55401.1Skamil 55411.1Skamil return atf_no_error(); 55421.1Skamil} 5543