t_ptrace_wait.c revision 1.87
11.88Sjonathan/* $NetBSD: t_ptrace_wait.c,v 1.87 2019/02/15 04:11:39 kamil Exp $ */ 21.8Scgd 31.1Sderaadt/*- 41.1Sderaadt * Copyright (c) 2016, 2017, 2018, 2019 The NetBSD Foundation, Inc. 51.3Sglass * All rights reserved. 61.3Sglass * 71.1Sderaadt * Redistribution and use in source and binary forms, with or without 81.1Sderaadt * modification, are permitted provided that the following conditions 91.1Sderaadt * are met: 101.1Sderaadt * 1. Redistributions of source code must retain the above copyright 111.1Sderaadt * notice, this list of conditions and the following disclaimer. 121.1Sderaadt * 2. Redistributions in binary form must reproduce the above copyright 131.1Sderaadt * notice, this list of conditions and the following disclaimer in the 141.1Sderaadt * documentation and/or other materials provided with the distribution. 151.1Sderaadt * 161.1Sderaadt * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 171.1Sderaadt * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 181.1Sderaadt * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 191.1Sderaadt * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 201.1Sderaadt * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 211.1Sderaadt * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 221.1Sderaadt * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 231.1Sderaadt * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 241.1Sderaadt * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 251.1Sderaadt * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 261.1Sderaadt * POSSIBILITY OF SUCH DAMAGE. 271.1Sderaadt */ 281.1Sderaadt 291.1Sderaadt#include <sys/cdefs.h> 301.1Sderaadt__RCSID("$NetBSD: t_ptrace_wait.c,v 1.87 2019/02/15 04:11:39 kamil Exp $"); 311.1Sderaadt 321.1Sderaadt#include <sys/param.h> 331.1Sderaadt#include <sys/types.h> 341.1Sderaadt#include <sys/mman.h> 351.1Sderaadt#include <sys/ptrace.h> 361.1Sderaadt#include <sys/resource.h> 371.1Sderaadt#include <sys/stat.h> 381.1Sderaadt#include <sys/syscall.h> 391.1Sderaadt#include <sys/sysctl.h> 401.1Sderaadt#include <sys/wait.h> 411.3Sglass#include <machine/reg.h> 421.8Scgd#include <elf.h> 431.1Sderaadt#include <err.h> 441.1Sderaadt#include <errno.h> 451.78Sjonathan#include <lwp.h> 461.88Sjonathan#include <pthread.h> 471.82Sthorpej#include <sched.h> 481.85Sjonathan#include <signal.h> 491.86Sjonathan#include <stdint.h> 501.86Sjonathan#include <stdio.h> 511.87Sjonathan#include <stdlib.h> 521.87Sjonathan#include <strings.h> 531.88Sjonathan#include <time.h> 541.84Sthorpej#include <unistd.h> 551.82Sthorpej 561.85Sjonathan#include <atf-c.h> 571.78Sjonathan 581.43Sjonathan#include "h_macros.h" 591.57Smhitch 601.37Sjonathan#include "t_ptrace_wait.h" 611.37Sjonathan#include "msg.h" 621.1Sderaadt 631.1Sderaadt#define PARENT_TO_CHILD(info, fds, msg) \ 641.23Sjonathan SYSCALL_REQUIRE(msg_write_child(info " to child " # fds, &fds, &msg, \ 651.1Sderaadt sizeof(msg)) == 0) 661.1Sderaadt 671.1Sderaadt#define CHILD_FROM_PARENT(info, fds, msg) \ 681.1Sderaadt FORKEE_ASSERT(msg_read_parent(info " from parent " # fds, &fds, &msg, \ 691.1Sderaadt sizeof(msg)) == 0) 701.1Sderaadt 711.1Sderaadt#define CHILD_TO_PARENT(info, fds, msg) \ 721.1Sderaadt FORKEE_ASSERT(msg_write_parent(info " to parent " # fds, &fds, &msg, \ 731.1Sderaadt sizeof(msg)) == 0) 741.46Sjonathan 751.58Sjonathan#define PARENT_FROM_CHILD(info, fds, msg) \ 761.58Sjonathan SYSCALL_REQUIRE(msg_read_child(info " from parent " # fds, &fds, &msg, \ 771.58Sjonathan sizeof(msg)) == 0) 781.78Sjonathan 791.78Sjonathan#define SYSCALL_REQUIRE(expr) ATF_REQUIRE_MSG(expr, "%s: %s", # expr, \ 801.78Sjonathan strerror(errno)) 811.78Sjonathan#define SYSCALL_REQUIRE_ERRNO(res, exp) ATF_REQUIRE_MSG(res == exp, \ 821.82Sthorpej "%d(%s) != %d", res, strerror(res), exp) 831.82Sthorpej 841.82Sthorpejstatic int debug = 0; 851.82Sthorpej 861.70Sjonathan#define DPRINTF(a, ...) do \ 871.70Sjonathan if (debug) printf(a, ##__VA_ARGS__); \ 881.1Sderaadt while (/*CONSTCOND*/0) 891.70Sjonathan 901.70Sjonathan/// ---------------------------------------------------------------------------- 911.70Sjonathan 921.1Sderaadtstatic void 931.16Sjonathantraceme_raise(int sigval) 941.16Sjonathan{ 951.37Sjonathan const int exitval = 5; 961.37Sjonathan pid_t child, wpid; 971.69Sjonathan#if defined(TWAIT_HAVE_STATUS) 981.69Sjonathan int status; 991.77Smhitch#endif 1001.69Sjonathan 1011.69Sjonathan struct ptrace_siginfo info; 1021.37Sjonathan memset(&info, 0, sizeof(info)); 1031.37Sjonathan 1041.37Sjonathan DPRINTF("Before forking process PID=%d\n", getpid()); 1051.37Sjonathan SYSCALL_REQUIRE((child = fork()) != -1); 1061.51Sis if (child == 0) { 1071.37Sjonathan DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 1081.39Smhitch FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 1091.39Smhitch 1101.16Sjonathan DPRINTF("Before raising %s from child\n", strsignal(sigval)); 1111.53Sjonathan FORKEE_ASSERT(raise(sigval) == 0); 1121.53Sjonathan 1131.53Sjonathan switch (sigval) { 1141.53Sjonathan case SIGKILL: 1151.53Sjonathan /* NOTREACHED */ 1161.53Sjonathan FORKEE_ASSERTX(0 && "This shall not be reached"); 1171.71Sjonathan __unreachable(); 1181.33Sjonathan default: 1191.33Sjonathan DPRINTF("Before exiting of the child process\n"); 1201.33Sjonathan _exit(exitval); 1211.23Sjonathan } 1221.57Smhitch } 1231.57Smhitch DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 1241.57Smhitch 1251.1Sderaadt DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1261.85Sjonathan TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1271.85Sjonathan 1281.85Sjonathan switch (sigval) { 1291.85Sjonathan case SIGKILL: 1301.85Sjonathan validate_status_signaled(status, sigval, 0); 1311.85Sjonathan break; 1321.22Sjonathan default: 1331.57Smhitch validate_status_stopped(status, sigval); 1341.22Sjonathan 1351.72Sjonathan DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for " 1361.72Sjonathan "child\n"); 1371.50Sjonathan SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, 1381.57Smhitch sizeof(info)) != -1); 1391.57Smhitch 1401.50Sjonathan DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 1411.50Sjonathan DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 1421.47Sjonathan "si_errno=%#x\n", 1431.50Sjonathan info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 1441.47Sjonathan info.psi_siginfo.si_errno); 1451.72Sjonathan 1461.35Sjonathan ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 1471.57Smhitch ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 1481.50Sjonathan 1491.50Sjonathan DPRINTF("Before resuming the child process where it left off " 1501.57Smhitch "and without signal to be sent\n"); 1511.50Sjonathan SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 1521.50Sjonathan 1531.50Sjonathan DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1541.50Sjonathan TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), 1551.57Smhitch child); 1561.57Smhitch break; 1571.57Smhitch } 1581.48Sjonathan 1591.47Sjonathan DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1601.50Sjonathan TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 1611.47Sjonathan} 1621.57Smhitch 1631.47Sjonathan#define TRACEME_RAISE(test, sig) \ 1641.35SjonathanATF_TC(test); \ 1651.72SjonathanATF_TC_HEAD(test, tc) \ 1661.50Sjonathan{ \ 1671.35Sjonathan atf_tc_set_md_var(tc, "descr", \ 1681.35Sjonathan "Verify " #sig " followed by _exit(2) in a child"); \ 1691.35Sjonathan} \ 1701.50Sjonathan \ 1711.50SjonathanATF_TC_BODY(test, tc) \ 1721.50Sjonathan{ \ 1731.50Sjonathan \ 1741.50Sjonathan traceme_raise(sig); \ 1751.50Sjonathan} 1761.50Sjonathan 1771.50SjonathanTRACEME_RAISE(traceme_raise1, SIGKILL) /* non-maskable */ 1781.50SjonathanTRACEME_RAISE(traceme_raise2, SIGSTOP) /* non-maskable */ 1791.50SjonathanTRACEME_RAISE(traceme_raise3, SIGABRT) /* regular abort trap */ 1801.50SjonathanTRACEME_RAISE(traceme_raise4, SIGHUP) /* hangup */ 1811.50SjonathanTRACEME_RAISE(traceme_raise5, SIGCONT) /* continued? */ 1821.50SjonathanTRACEME_RAISE(traceme_raise6, SIGTRAP) /* crash signal */ 1831.50SjonathanTRACEME_RAISE(traceme_raise7, SIGBUS) /* crash signal */ 1841.50SjonathanTRACEME_RAISE(traceme_raise8, SIGILL) /* crash signal */ 1851.50SjonathanTRACEME_RAISE(traceme_raise9, SIGFPE) /* crash signal */ 1861.50SjonathanTRACEME_RAISE(traceme_raise10, SIGSEGV) /* crash signal */ 1871.50Sjonathan 1881.50Sjonathan/// ---------------------------------------------------------------------------- 1891.50Sjonathan 1901.50Sjonathanstatic void 1911.50Sjonathantraceme_raisesignal_ignored(int sigignored) 1921.50Sjonathan{ 1931.50Sjonathan const int exitval = 5; 1941.50Sjonathan const int sigval = SIGSTOP; 1951.50Sjonathan pid_t child, wpid; 1961.50Sjonathan struct sigaction sa; 1971.50Sjonathan#if defined(TWAIT_HAVE_STATUS) 1981.50Sjonathan int status; 1991.50Sjonathan#endif 2001.50Sjonathan struct ptrace_siginfo info; 2011.50Sjonathan 2021.35Sjonathan memset(&info, 0, sizeof(info)); 2031.35Sjonathan 2041.35Sjonathan DPRINTF("Before forking process PID=%d\n", getpid()); 2051.50Sjonathan SYSCALL_REQUIRE((child = fork()) != -1); 2061.50Sjonathan if (child == 0) { 2071.50Sjonathan DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 2081.50Sjonathan FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 2091.50Sjonathan 2101.50Sjonathan memset(&sa, 0, sizeof(sa)); 2111.50Sjonathan sa.sa_handler = SIG_IGN; 2121.50Sjonathan sigemptyset(&sa.sa_mask); 2131.57Smhitch FORKEE_ASSERT(sigaction(sigignored, &sa, NULL) != -1); 2141.50Sjonathan 2151.50Sjonathan DPRINTF("Before raising %s from child\n", strsignal(sigval)); 2161.50Sjonathan FORKEE_ASSERT(raise(sigval) == 0); 2171.50Sjonathan 2181.50Sjonathan DPRINTF("Before raising %s from child\n", 2191.50Sjonathan strsignal(sigignored)); 2201.50Sjonathan FORKEE_ASSERT(raise(sigignored) == 0); 2211.50Sjonathan 2221.50Sjonathan DPRINTF("Before exiting of the child process\n"); 2231.50Sjonathan _exit(exitval); 2241.50Sjonathan } 2251.50Sjonathan DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 2261.50Sjonathan 2271.50Sjonathan DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 2281.50Sjonathan TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 2291.50Sjonathan 2301.50Sjonathan validate_status_stopped(status, sigval); 2311.50Sjonathan 2321.50Sjonathan DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 2331.50Sjonathan SYSCALL_REQUIRE( 2341.50Sjonathan ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 2351.50Sjonathan 2361.50Sjonathan DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 2371.35Sjonathan DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 2381.72Sjonathan info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 2391.35Sjonathan info.psi_siginfo.si_errno); 2401.50Sjonathan 2411.50Sjonathan ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 2421.50Sjonathan ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 2431.1Sderaadt 2441.1Sderaadt DPRINTF("Before resuming the child process where it left off and " 2451.1Sderaadt "without signal to be sent\n"); 2461.50Sjonathan SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 2471.50Sjonathan 2481.57Smhitch DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 2491.57Smhitch TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 2501.50Sjonathan 2511.50Sjonathan validate_status_stopped(status, sigignored); 2521.50Sjonathan 2531.50Sjonathan DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 2541.50Sjonathan SYSCALL_REQUIRE( 2551.50Sjonathan ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 2561.50Sjonathan 2571.50Sjonathan DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 2581.50Sjonathan DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 2591.50Sjonathan info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 2601.57Smhitch info.psi_siginfo.si_errno); 2611.50Sjonathan 2621.50Sjonathan ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigignored); 2631.50Sjonathan ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 2641.50Sjonathan 2651.50Sjonathan DPRINTF("Before resuming the child process where it left off and " 2661.50Sjonathan "without signal to be sent\n"); 2671.50Sjonathan SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 2681.50Sjonathan 2691.50Sjonathan DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 2701.50Sjonathan TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 2711.50Sjonathan 2721.50Sjonathan validate_status_exited(status, exitval); 2731.50Sjonathan 2741.50Sjonathan DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 2751.50Sjonathan TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 2761.50Sjonathan} 2771.57Smhitch 2781.1Sderaadt#define TRACEME_RAISESIGNAL_IGNORED(test, sig) \ 2791.1SderaadtATF_TC(test); \ 2801.1SderaadtATF_TC_HEAD(test, tc) \ 2811.50Sjonathan{ \ 2821.50Sjonathan atf_tc_set_md_var(tc, "descr", \ 2831.50Sjonathan "Verify that ignoring (with SIG_IGN) " #sig " in tracee " \ 2841.50Sjonathan "does not stop tracer from catching this raised signal"); \ 2851.50Sjonathan} \ 2861.50Sjonathan \ 2871.50SjonathanATF_TC_BODY(test, tc) \ 2881.50Sjonathan{ \ 2891.57Smhitch \ 2901.50Sjonathan traceme_raisesignal_ignored(sig); \ 2911.50Sjonathan} 2921.50Sjonathan 2931.50Sjonathan// A signal handler for SIGKILL and SIGSTOP cannot be ignored. 2941.50SjonathanTRACEME_RAISESIGNAL_IGNORED(traceme_raisesignal_ignored1, SIGABRT) /* abort */ 2951.57SmhitchTRACEME_RAISESIGNAL_IGNORED(traceme_raisesignal_ignored2, SIGHUP) /* hangup */ 2961.50SjonathanTRACEME_RAISESIGNAL_IGNORED(traceme_raisesignal_ignored3, SIGCONT) /* cont. */ 2971.50SjonathanTRACEME_RAISESIGNAL_IGNORED(traceme_raisesignal_ignored4, SIGTRAP) /* crash */ 2981.50SjonathanTRACEME_RAISESIGNAL_IGNORED(traceme_raisesignal_ignored5, SIGBUS) /* crash */ 2991.50SjonathanTRACEME_RAISESIGNAL_IGNORED(traceme_raisesignal_ignored6, SIGILL) /* crash */ 3001.50SjonathanTRACEME_RAISESIGNAL_IGNORED(traceme_raisesignal_ignored7, SIGFPE) /* crash */ 3011.50SjonathanTRACEME_RAISESIGNAL_IGNORED(traceme_raisesignal_ignored8, SIGSEGV) /* crash */ 3021.50Sjonathan 3031.50Sjonathan/// ---------------------------------------------------------------------------- 3041.50Sjonathan 3051.50Sjonathanstatic void 3061.50Sjonathantraceme_raisesignal_masked(int sigmasked) 3071.50Sjonathan{ 3081.50Sjonathan const int exitval = 5; 3091.50Sjonathan const int sigval = SIGSTOP; 3101.50Sjonathan pid_t child, wpid; 3111.50Sjonathan#if defined(TWAIT_HAVE_STATUS) 3121.57Smhitch int status; 3131.1Sderaadt#endif 3141.50Sjonathan sigset_t intmask; 3151.50Sjonathan struct ptrace_siginfo info; 3161.1Sderaadt 3171.1Sderaadt memset(&info, 0, sizeof(info)); 3181.1Sderaadt 3191.1Sderaadt DPRINTF("Before forking process PID=%d\n", getpid()); 3201.1Sderaadt SYSCALL_REQUIRE((child = fork()) != -1); 3211.1Sderaadt if (child == 0) { 3221.1Sderaadt DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 3231.1Sderaadt FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 3241.1Sderaadt 3251.1Sderaadt sigemptyset(&intmask); 3261.1Sderaadt sigaddset(&intmask, sigmasked); 3271.1Sderaadt sigprocmask(SIG_BLOCK, &intmask, NULL); 3281.1Sderaadt 3291.1Sderaadt DPRINTF("Before raising %s from child\n", strsignal(sigval)); 3301.1Sderaadt FORKEE_ASSERT(raise(sigval) == 0); 3311.32Sjonathan 3321.32Sjonathan DPRINTF("Before raising %s breakpoint from child\n", 3331.32Sjonathan strsignal(sigmasked)); 3341.32Sjonathan FORKEE_ASSERT(raise(sigmasked) == 0); 3351.32Sjonathan 3361.32Sjonathan DPRINTF("Before exiting of the child process\n"); 3371.32Sjonathan _exit(exitval); 3381.32Sjonathan } 3391.32Sjonathan DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 3401.32Sjonathan 3411.46Sjonathan DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 3421.32Sjonathan TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 3431.32Sjonathan 3441.32Sjonathan validate_status_stopped(status, sigval); 3451.32Sjonathan 3461.32Sjonathan DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 3471.32Sjonathan SYSCALL_REQUIRE( 3481.32Sjonathan ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 3491.46Sjonathan 3501.1Sderaadt DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 3511.57Smhitch DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 3521.1Sderaadt info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 3531.1Sderaadt info.psi_siginfo.si_errno); 3541.1Sderaadt 3551.1Sderaadt ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 3561.1Sderaadt ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 3571.1Sderaadt 3581.1Sderaadt DPRINTF("Before resuming the child process where it left off and " 3591.1Sderaadt "without signal to be sent\n"); 3601.1Sderaadt SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 3611.32Sjonathan 3621.1Sderaadt DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 3631.1Sderaadt TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 3641.16Sjonathan 3651.22Sjonathan validate_status_exited(status, exitval); 3661.16Sjonathan 3671.16Sjonathan DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 3681.57Smhitch TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 3691.69Sjonathan} 3701.69Sjonathan 3711.66Smhitch#define TRACEME_RAISESIGNAL_MASKED(test, sig) \ 3721.66SmhitchATF_TC(test); \ 3731.33SjonathanATF_TC_HEAD(test, tc) \ 3741.33Sjonathan{ \ 3751.33Sjonathan atf_tc_set_md_var(tc, "descr", \ 3761.57Smhitch "Verify that masking (with SIG_BLOCK) " #sig " in tracee " \ 3771.33Sjonathan "stops tracer from catching this raised signal"); \ 3781.33Sjonathan} \ 3791.33Sjonathan \ 3801.16SjonathanATF_TC_BODY(test, tc) \ 3811.57Smhitch{ \ 3821.74Smhitch \ 3831.57Smhitch traceme_raisesignal_masked(sig); \ 3841.22Sjonathan} 3851.22Sjonathan 3861.22Sjonathan// A signal handler for SIGKILL and SIGSTOP cannot be masked. 3871.57SmhitchTRACEME_RAISESIGNAL_MASKED(traceme_raisesignal_masked1, SIGABRT) /* abort trap */ 3881.57SmhitchTRACEME_RAISESIGNAL_MASKED(traceme_raisesignal_masked2, SIGHUP) /* hangup */ 3891.22SjonathanTRACEME_RAISESIGNAL_MASKED(traceme_raisesignal_masked3, SIGCONT) /* continued? */ 3901.22SjonathanTRACEME_RAISESIGNAL_MASKED(traceme_raisesignal_masked4, SIGTRAP) /* crash sig. */ 3911.57SmhitchTRACEME_RAISESIGNAL_MASKED(traceme_raisesignal_masked5, SIGBUS) /* crash sig. */ 3921.57SmhitchTRACEME_RAISESIGNAL_MASKED(traceme_raisesignal_masked6, SIGILL) /* crash sig. */ 3931.57SmhitchTRACEME_RAISESIGNAL_MASKED(traceme_raisesignal_masked7, SIGFPE) /* crash sig. */ 3941.57SmhitchTRACEME_RAISESIGNAL_MASKED(traceme_raisesignal_masked8, SIGSEGV) /* crash sig. */ 3951.57Smhitch 3961.57Smhitch/// ---------------------------------------------------------------------------- 3971.57Smhitch 3981.57Smhitchstatic void 3991.57Smhitchtraceme_crash(int sig) 4001.22Sjonathan{ 4011.68Sjonathan pid_t child, wpid; 4021.68Sjonathan#if defined(TWAIT_HAVE_STATUS) 4031.68Sjonathan int status; 4041.73Sjonathan#endif 4051.56Sjonathan struct ptrace_siginfo info; 4061.56Sjonathan 4071.56Sjonathan#ifndef PTRACE_ILLEGAL_ASM 4081.16Sjonathan if (sig == SIGILL) 4091.16Sjonathan atf_tc_skip("PTRACE_ILLEGAL_ASM not defined"); 4101.22Sjonathan#endif 4111.22Sjonathan 4121.22Sjonathan memset(&info, 0, sizeof(info)); 4131.22Sjonathan 4141.23Sjonathan DPRINTF("Before forking process PID=%d\n", getpid()); 4151.36Sjonathan SYSCALL_REQUIRE((child = fork()) != -1); 4161.73Sjonathan if (child == 0) { 4171.16Sjonathan DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 4181.28Sjonathan FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 4191.28Sjonathan 4201.28Sjonathan DPRINTF("Before executing a trap\n"); 4211.28Sjonathan switch (sig) { 4221.28Sjonathan case SIGTRAP: 4231.57Smhitch trigger_trap(); 4241.57Smhitch break; 4251.57Smhitch case SIGSEGV: 4261.57Smhitch trigger_segv(); 4271.57Smhitch break; 4281.57Smhitch case SIGILL: 4291.57Smhitch trigger_ill(); 4301.57Smhitch break; 4311.57Smhitch case SIGFPE: 4321.57Smhitch trigger_fpe(); 4331.57Smhitch break; 4341.57Smhitch case SIGBUS: 4351.57Smhitch trigger_bus(); 4361.57Smhitch break; 4371.57Smhitch default: 4381.57Smhitch /* NOTREACHED */ 4391.57Smhitch FORKEE_ASSERTX(0 && "This shall not be reached"); 4401.28Sjonathan } 4411.28Sjonathan 4421.57Smhitch /* NOTREACHED */ 4431.57Smhitch FORKEE_ASSERTX(0 && "This shall not be reached"); 4441.57Smhitch } 4451.57Smhitch DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 4461.57Smhitch 4471.57Smhitch DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4481.57Smhitch TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4491.57Smhitch 4501.57Smhitch validate_status_stopped(status, sig); 4511.57Smhitch 4521.57Smhitch DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child"); 4531.57Smhitch SYSCALL_REQUIRE( 4541.57Smhitch ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 4551.57Smhitch 4561.57Smhitch DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 4571.57Smhitch DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 4581.57Smhitch info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 4591.57Smhitch info.psi_siginfo.si_errno); 4601.57Smhitch 4611.57Smhitch ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sig); 4621.57Smhitch switch (sig) { 4631.57Smhitch case SIGTRAP: 4641.57Smhitch ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_BRKPT); 4651.57Smhitch break; 4661.57Smhitch case SIGSEGV: 4671.57Smhitch ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SEGV_MAPERR); 4681.57Smhitch break; 4691.57Smhitch case SIGILL: 4701.57Smhitch ATF_REQUIRE_EQ(info.psi_siginfo.si_code, ILL_PRVOPC); 4711.57Smhitch break; 4721.57Smhitch case SIGFPE: 4731.57Smhitch ATF_REQUIRE_EQ(info.psi_siginfo.si_code, FPE_INTDIV); 4741.57Smhitch break; 4751.57Smhitch case SIGBUS: 4761.57Smhitch ATF_REQUIRE_EQ(info.psi_siginfo.si_code, BUS_ADRERR); 4771.57Smhitch break; 4781.57Smhitch } 4791.57Smhitch 4801.57Smhitch SYSCALL_REQUIRE(ptrace(PT_KILL, child, NULL, 0) != -1); 4811.57Smhitch 4821.1Sderaadt DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4831.63Smhitch TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4841.1Sderaadt 4851.57Smhitch validate_status_signaled(status, SIGKILL, 0); 4861.57Smhitch 4871.57Smhitch DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4881.57Smhitch TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 4891.57Smhitch} 4901.57Smhitch 4911.57Smhitch#define TRACEME_CRASH(test, sig) \ 4921.57SmhitchATF_TC(test); \ 4931.57SmhitchATF_TC_HEAD(test, tc) \ 4941.57Smhitch{ \ 4951.57Smhitch atf_tc_set_md_var(tc, "descr", \ 4961.1Sderaadt "Verify crash signal " #sig " in a child after PT_TRACE_ME"); \ 4971.57Smhitch} \ 4981.1Sderaadt \ 4991.57SmhitchATF_TC_BODY(test, tc) \ 5001.57Smhitch{ \ 5011.57Smhitch \ 5021.57Smhitch traceme_crash(sig); \ 5031.57Smhitch} 5041.57Smhitch 5051.57SmhitchTRACEME_CRASH(traceme_crash_trap, SIGTRAP) 5061.57SmhitchTRACEME_CRASH(traceme_crash_segv, SIGSEGV) 5071.57SmhitchTRACEME_CRASH(traceme_crash_ill, SIGILL) 5081.57SmhitchTRACEME_CRASH(traceme_crash_fpe, SIGFPE) 5091.57SmhitchTRACEME_CRASH(traceme_crash_bus, SIGBUS) 5101.57Smhitch 5111.57Smhitch/// ---------------------------------------------------------------------------- 5121.57Smhitch 5131.57Smhitchstatic void 5141.57Smhitchtraceme_sendsignal_handle(int sigsent, void (*sah)(int a), int *traceme_caught) 5151.82Sthorpej{ 5161.82Sthorpej const int exitval = 5; 5171.82Sthorpej const int sigval = SIGSTOP; 5181.57Smhitch pid_t child, wpid; 5191.82Sthorpej struct sigaction sa; 5201.76Sjonathan#if defined(TWAIT_HAVE_STATUS) 5211.76Sjonathan int status; 5221.76Sjonathan#endif 5231.57Smhitch struct ptrace_siginfo info; 5241.57Smhitch 5251.57Smhitch memset(&info, 0, sizeof(info)); 5261.57Smhitch 5271.57Smhitch DPRINTF("Before forking process PID=%d\n", getpid()); 5281.57Smhitch SYSCALL_REQUIRE((child = fork()) != -1); 5291.57Smhitch if (child == 0) { 5301.57Smhitch DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 5311.57Smhitch FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 5321.57Smhitch 5331.57Smhitch sa.sa_handler = sah; 5341.57Smhitch sa.sa_flags = SA_SIGINFO; 5351.57Smhitch sigemptyset(&sa.sa_mask); 5361.57Smhitch 5371.57Smhitch FORKEE_ASSERT(sigaction(sigsent, &sa, NULL) != -1); 5381.57Smhitch 5391.57Smhitch DPRINTF("Before raising %s from child\n", strsignal(sigval)); 5401.57Smhitch FORKEE_ASSERT(raise(sigval) == 0); 5411.57Smhitch 5421.57Smhitch FORKEE_ASSERT_EQ(*traceme_caught, 1); 5431.57Smhitch 5441.57Smhitch DPRINTF("Before exiting of the child process\n"); 5451.57Smhitch _exit(exitval); 5461.57Smhitch } 5471.57Smhitch DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 5481.57Smhitch 5491.57Smhitch DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 5501.57Smhitch TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5511.57Smhitch 5521.57Smhitch validate_status_stopped(status, sigval); 5531.57Smhitch 5541.57Smhitch DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 5551.57Smhitch SYSCALL_REQUIRE( 5561.57Smhitch ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 5571.57Smhitch 5581.57Smhitch DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 5591.57Smhitch DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 5601.57Smhitch info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 5611.57Smhitch info.psi_siginfo.si_errno); 5621.57Smhitch 5631.57Smhitch ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 5641.57Smhitch ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 5651.57Smhitch 5661.57Smhitch DPRINTF("Before resuming the child process where it left off and with " 5671.57Smhitch "signal %s to be sent\n", strsignal(sigsent)); 5681.57Smhitch SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigsent) != -1); 5691.57Smhitch 5701.57Smhitch DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 5711.57Smhitch TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5721.57Smhitch 5731.57Smhitch validate_status_exited(status, exitval); 5741.57Smhitch 5751.57Smhitch DPRINTF("Before calling %s() for the exited child\n", TWAIT_FNAME); 5761.57Smhitch TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 5771.57Smhitch} 5781.57Smhitch 5791.57Smhitch#define TRACEME_SENDSIGNAL_HANDLE(test, sig) \ 5801.57SmhitchATF_TC(test); \ 5811.57SmhitchATF_TC_HEAD(test, tc) \ 5821.57Smhitch{ \ 5831.57Smhitch atf_tc_set_md_var(tc, "descr", \ 5841.57Smhitch "Verify that a signal " #sig " emitted by a tracer to a child is " \ 5851.57Smhitch "handled correctly and caught by a signal handler"); \ 5861.57Smhitch} \ 5871.57Smhitch \ 5881.57Smhitchstatic int test##_caught = 0; \ 5891.57Smhitch \ 5901.57Smhitchstatic void \ 5911.57Smhitchtest##_sighandler(int arg) \ 5921.57Smhitch{ \ 5931.57Smhitch FORKEE_ASSERT_EQ(arg, sig); \ 5941.57Smhitch \ 5951.57Smhitch ++ test##_caught; \ 5961.57Smhitch} \ 5971.57Smhitch \ 5981.57SmhitchATF_TC_BODY(test, tc) \ 5991.57Smhitch{ \ 6001.57Smhitch \ 6011.57Smhitch traceme_sendsignal_handle(sig, test##_sighandler, & test##_caught); \ 6021.57Smhitch} 6031.57Smhitch 6041.57Smhitch// A signal handler for SIGKILL and SIGSTOP cannot be registered. 6051.57SmhitchTRACEME_SENDSIGNAL_HANDLE(traceme_sendsignal_handle1, SIGABRT) /* abort trap */ 6061.57SmhitchTRACEME_SENDSIGNAL_HANDLE(traceme_sendsignal_handle2, SIGHUP) /* hangup */ 6071.57SmhitchTRACEME_SENDSIGNAL_HANDLE(traceme_sendsignal_handle3, SIGCONT) /* continued? */ 6081.57SmhitchTRACEME_SENDSIGNAL_HANDLE(traceme_sendsignal_handle4, SIGTRAP) /* crash sig. */ 6091.57SmhitchTRACEME_SENDSIGNAL_HANDLE(traceme_sendsignal_handle5, SIGBUS) /* crash sig. */ 6101.57SmhitchTRACEME_SENDSIGNAL_HANDLE(traceme_sendsignal_handle6, SIGILL) /* crash sig. */ 6111.57SmhitchTRACEME_SENDSIGNAL_HANDLE(traceme_sendsignal_handle7, SIGFPE) /* crash sig. */ 6121.57SmhitchTRACEME_SENDSIGNAL_HANDLE(traceme_sendsignal_handle8, SIGSEGV) /* crash sig. */ 6131.57Smhitch 6141.57Smhitch/// ---------------------------------------------------------------------------- 6151.57Smhitch 6161.57Smhitchstatic void 6171.57Smhitchtraceme_sendsignal_masked(int sigsent) 6181.57Smhitch{ 6191.57Smhitch const int exitval = 5; 6201.57Smhitch const int sigval = SIGSTOP; 6211.57Smhitch pid_t child, wpid; 6221.57Smhitch sigset_t set; 6231.57Smhitch#if defined(TWAIT_HAVE_STATUS) 6241.57Smhitch int status; 6251.57Smhitch#endif 6261.57Smhitch struct ptrace_siginfo info; 6271.57Smhitch 6281.57Smhitch memset(&info, 0, sizeof(info)); 6291.57Smhitch 6301.57Smhitch DPRINTF("Before forking process PID=%d\n", getpid()); 6311.57Smhitch SYSCALL_REQUIRE((child = fork()) != -1); 6321.57Smhitch if (child == 0) { 6331.57Smhitch DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 6341.57Smhitch FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 6351.57Smhitch 6361.57Smhitch sigemptyset(&set); 6371.57Smhitch sigaddset(&set, sigsent); 6381.57Smhitch FORKEE_ASSERT(sigprocmask(SIG_BLOCK, &set, NULL) != -1); 6391.57Smhitch 6401.65Sjonathan DPRINTF("Before raising %s from child\n", strsignal(sigval)); 6411.57Smhitch FORKEE_ASSERT(raise(sigval) == 0); 6421.65Sjonathan 6431.57Smhitch _exit(exitval); 6441.57Smhitch } 6451.57Smhitch DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 6461.57Smhitch 6471.57Smhitch DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 6481.57Smhitch TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 6491.57Smhitch 6501.57Smhitch validate_status_stopped(status, sigval); 6511.57Smhitch 6521.57Smhitch DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 6531.57Smhitch SYSCALL_REQUIRE( 6541.57Smhitch ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 6551.57Smhitch 6561.57Smhitch DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 6571.57Smhitch DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 6581.57Smhitch info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 6591.57Smhitch info.psi_siginfo.si_errno); 6601.57Smhitch 6611.57Smhitch ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 6621.57Smhitch ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 6631.1Sderaadt 6641.57Smhitch DPRINTF("Before resuming the child process where it left off and with " 6651.1Sderaadt "signal %s to be sent\n", strsignal(sigsent)); 6661.1Sderaadt SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigsent) != -1); 6671.57Smhitch 6681.57Smhitch DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 6691.57Smhitch TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 6701.57Smhitch 6711.57Smhitch validate_status_exited(status, exitval); 6721.57Smhitch 6731.1Sderaadt DPRINTF("Before calling %s() for the exited child\n", TWAIT_FNAME); 6741.1Sderaadt TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 6751.1Sderaadt} 6761.1Sderaadt 6771.82Sthorpej#define TRACEME_SENDSIGNAL_MASKED(test, sig) \ 6781.82SthorpejATF_TC(test); \ 6791.82SthorpejATF_TC_HEAD(test, tc) \ 6801.1Sderaadt{ \ 6811.82Sthorpej atf_tc_set_md_var(tc, "descr", \ 6821.57Smhitch "Verify that a signal " #sig " emitted by a tracer to a child is " \ 6831.57Smhitch "handled correctly and the signal is masked by SIG_BLOCK"); \ 6841.1Sderaadt} \ 6851.1Sderaadt \ 6861.1SderaadtATF_TC_BODY(test, tc) \ 6871.1Sderaadt{ \ 6881.60Sjonathan \ 6891.65Sjonathan traceme_sendsignal_masked(sig); \ 6901.1Sderaadt} 6911.1Sderaadt 6921.57Smhitch// A signal handler for SIGKILL and SIGSTOP cannot be masked. 6931.57SmhitchTRACEME_SENDSIGNAL_MASKED(traceme_sendsignal_masked1, SIGABRT) /* abort trap */ 6941.57SmhitchTRACEME_SENDSIGNAL_MASKED(traceme_sendsignal_masked2, SIGHUP) /* hangup */ 6951.57SmhitchTRACEME_SENDSIGNAL_MASKED(traceme_sendsignal_masked3, SIGCONT) /* continued? */ 6961.57SmhitchTRACEME_SENDSIGNAL_MASKED(traceme_sendsignal_masked4, SIGTRAP) /* crash sig. */ 6971.57SmhitchTRACEME_SENDSIGNAL_MASKED(traceme_sendsignal_masked5, SIGBUS) /* crash sig. */ 6981.57SmhitchTRACEME_SENDSIGNAL_MASKED(traceme_sendsignal_masked6, SIGILL) /* crash sig. */ 6991.57SmhitchTRACEME_SENDSIGNAL_MASKED(traceme_sendsignal_masked7, SIGFPE) /* crash sig. */ 7001.57SmhitchTRACEME_SENDSIGNAL_MASKED(traceme_sendsignal_masked8, SIGSEGV) /* crash sig. */ 7011.57Smhitch 7021.57Smhitch/// ---------------------------------------------------------------------------- 7031.57Smhitch 7041.57Smhitchstatic void 7051.57Smhitchtraceme_sendsignal_ignored(int sigsent) 7061.57Smhitch{ 7071.57Smhitch const int exitval = 5; 7081.57Smhitch const int sigval = SIGSTOP; 7091.57Smhitch pid_t child, wpid; 7101.67Smhitch struct sigaction sa; 7111.57Smhitch#if defined(TWAIT_HAVE_STATUS) 7121.57Smhitch int status; 7131.1Sderaadt#endif 7141.57Smhitch struct ptrace_siginfo info; 7151.57Smhitch 7161.57Smhitch memset(&info, 0, sizeof(info)); 7171.57Smhitch 7181.1Sderaadt DPRINTF("Before forking process PID=%d\n", getpid()); 7191.57Smhitch SYSCALL_REQUIRE((child = fork()) != -1); 7201.1Sderaadt if (child == 0) { 7211.60Sjonathan DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 7221.57Smhitch 7231.57Smhitch FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 7241.60Sjonathan 7251.1Sderaadt memset(&sa, 0, sizeof(sa)); 7261.1Sderaadt sa.sa_handler = SIG_IGN; 7271.57Smhitch sigemptyset(&sa.sa_mask); 7281.1Sderaadt FORKEE_ASSERT(sigaction(sigsent, &sa, NULL) != -1); 7291.60Sjonathan 7301.1Sderaadt DPRINTF("Before raising %s from child\n", strsignal(sigval)); 7311.57Smhitch FORKEE_ASSERT(raise(sigval) == 0); 7321.57Smhitch 7331.57Smhitch _exit(exitval); 7341.1Sderaadt } 7351.3Sglass DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 7361.1Sderaadt 7371.1Sderaadt DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 7381.57Smhitch TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 7391.1Sderaadt 7401.1Sderaadt validate_status_stopped(status, sigval); 7411.57Smhitch 7421.1Sderaadt DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 7431.57Smhitch SYSCALL_REQUIRE( 7441.1Sderaadt ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 7451.1Sderaadt 7461.57Smhitch DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 7471.57Smhitch DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 7481.57Smhitch info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 7491.57Smhitch info.psi_siginfo.si_errno); 7501.57Smhitch 7511.57Smhitch ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 7521.57Smhitch ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 7531.57Smhitch 7541.57Smhitch DPRINTF("Before resuming the child process where it left off and with " 7551.3Sglass "signal %s to be sent\n", strsignal(sigsent)); 7561.60Sjonathan SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigsent) != -1); 7571.57Smhitch 7581.57Smhitch DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 7591.60Sjonathan TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 7601.3Sglass 7611.1Sderaadt validate_status_exited(status, exitval); 7621.57Smhitch 7631.1Sderaadt DPRINTF("Before calling %s() for the exited child\n", TWAIT_FNAME); 7641.60Sjonathan TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 7651.3Sglass} 7661.57Smhitch 7671.64Sjonathan#define TRACEME_SENDSIGNAL_IGNORED(test, sig) \ 7681.57SmhitchATF_TC(test); \ 7691.57SmhitchATF_TC_HEAD(test, tc) \ 7701.1Sderaadt{ \ 7711.3Sglass atf_tc_set_md_var(tc, "descr", \ 7721.1Sderaadt "Verify that a signal " #sig " emitted by a tracer to a child is " \ 7731.57Smhitch "handled correctly and the signal is masked by SIG_IGN"); \ 7741.57Smhitch} \ 7751.1Sderaadt \ 7761.1SderaadtATF_TC_BODY(test, tc) \ 7771.57Smhitch{ \ 7781.57Smhitch \ 7791.57Smhitch traceme_sendsignal_ignored(sig); \ 7801.1Sderaadt} 7811.1Sderaadt 7821.1Sderaadt// A signal handler for SIGKILL and SIGSTOP cannot be ignored. 7831.57SmhitchTRACEME_SENDSIGNAL_IGNORED(traceme_sendsignal_ignored1, SIGABRT) /* abort */ 7841.57SmhitchTRACEME_SENDSIGNAL_IGNORED(traceme_sendsignal_ignored2, SIGHUP) /* hangup */ 7851.57SmhitchTRACEME_SENDSIGNAL_IGNORED(traceme_sendsignal_ignored3, SIGCONT) /* continued */ 7861.1SderaadtTRACEME_SENDSIGNAL_IGNORED(traceme_sendsignal_ignored4, SIGTRAP) /* crash s. */ 7871.1SderaadtTRACEME_SENDSIGNAL_IGNORED(traceme_sendsignal_ignored5, SIGBUS) /* crash s. */ 7881.1SderaadtTRACEME_SENDSIGNAL_IGNORED(traceme_sendsignal_ignored6, SIGILL) /* crash s. */ 7891.1SderaadtTRACEME_SENDSIGNAL_IGNORED(traceme_sendsignal_ignored7, SIGFPE) /* crash s. */ 7901.74SmhitchTRACEME_SENDSIGNAL_IGNORED(traceme_sendsignal_ignored8, SIGSEGV) /* crash s. */ 7911.57Smhitch 7921.1Sderaadt/// ---------------------------------------------------------------------------- 7931.74Smhitch 7941.57Smhitchstatic void 7951.57Smhitchtraceme_sendsignal_simple(int sigsent) 7961.57Smhitch{ 7971.57Smhitch const int sigval = SIGSTOP; 7981.1Sderaadt int exitval = 0; 7991.1Sderaadt pid_t child, wpid; 8001.57Smhitch#if defined(TWAIT_HAVE_STATUS) 8011.1Sderaadt int status; 8021.1Sderaadt int expect_core; 8031.57Smhitch 8041.1Sderaadt switch (sigsent) { 8051.57Smhitch case SIGABRT: 8061.57Smhitch case SIGTRAP: 8071.57Smhitch case SIGBUS: 8081.1Sderaadt case SIGILL: 8091.1Sderaadt case SIGFPE: 8101.3Sglass case SIGSEGV: 8111.3Sglass expect_core = 1; 8121.57Smhitch break; 8131.82Sthorpej default: 8141.82Sthorpej expect_core = 0; 8151.82Sthorpej break; 8161.82Sthorpej } 8171.82Sthorpej#endif 8181.82Sthorpej struct ptrace_siginfo info; 8191.82Sthorpej 8201.82Sthorpej memset(&info, 0, sizeof(info)); 8211.1Sderaadt 8221.5Sglass DPRINTF("Before forking process PID=%d\n", getpid()); 8231.57Smhitch SYSCALL_REQUIRE((child = fork()) != -1); 8241.75Sjonathan if (child == 0) { 8251.75Sjonathan DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 8261.75Sjonathan FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 8271.5Sglass 8281.82Sthorpej DPRINTF("Before raising %s from child\n", strsignal(sigval)); 8291.1Sderaadt FORKEE_ASSERT(raise(sigval) == 0); 8301.1Sderaadt 8311.1Sderaadt switch (sigsent) { 8321.1Sderaadt case SIGCONT: 8331.1Sderaadt case SIGSTOP: 8341.1Sderaadt _exit(exitval); 8351.1Sderaadt default: 8361.1Sderaadt /* NOTREACHED */ 8371.1Sderaadt FORKEE_ASSERTX(0 && "This shall not be reached"); 8381.1Sderaadt } 8391.1Sderaadt } 8401.1Sderaadt DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 8411.1Sderaadt 8421.1Sderaadt DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 8431.57Smhitch TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 8441.57Smhitch 8451.1Sderaadt validate_status_stopped(status, sigval); 8461.1Sderaadt 8471.1Sderaadt DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 8481.57Smhitch SYSCALL_REQUIRE( 8491.57Smhitch ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 8501.57Smhitch 8511.57Smhitch DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 8521.57Smhitch DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 8531.57Smhitch info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 8541.57Smhitch info.psi_siginfo.si_errno); 8551.57Smhitch 8561.57Smhitch ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 8571.1Sderaadt ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 8581.57Smhitch 8591.57Smhitch DPRINTF("Before resuming the child process where it left off and with " 8601.57Smhitch "signal %s to be sent\n", strsignal(sigsent)); 8611.57Smhitch SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigsent) != -1); 8621.57Smhitch 8631.57Smhitch DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 8641.82Sthorpej TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 8651.82Sthorpej 8661.82Sthorpej switch (sigsent) { 8671.57Smhitch case SIGSTOP: 8681.82Sthorpej validate_status_stopped(status, sigsent); 8691.57Smhitch DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for " 8701.57Smhitch "child\n"); 8711.57Smhitch SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, 8721.1Sderaadt sizeof(info)) != -1); 8731.57Smhitch 8741.57Smhitch DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 8751.57Smhitch DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 8761.57Smhitch "si_errno=%#x\n", 8771.74Smhitch info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 8781.57Smhitch info.psi_siginfo.si_errno); 8791.74Smhitch 8801.57Smhitch ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 8811.1Sderaadt ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 8821.1Sderaadt 8831.1Sderaadt DPRINTF("Before resuming the child process where it left off " 8841.1Sderaadt "and with signal %s to be sent\n", strsignal(sigsent)); 8851.1Sderaadt SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 8861.57Smhitch 8871.57Smhitch DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 8881.57Smhitch TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), 8891.69Sjonathan child); 8901.69Sjonathan /* FALLTHROUGH */ 8911.69Sjonathan case SIGCONT: 8921.69Sjonathan validate_status_exited(status, exitval); 8931.69Sjonathan break; 8941.69Sjonathan default: 8951.69Sjonathan validate_status_signaled(status, sigsent, expect_core); 8961.69Sjonathan break; 8971.1Sderaadt } 8981.1Sderaadt 8991.57Smhitch DPRINTF("Before calling %s() for the exited child\n", TWAIT_FNAME); 9001.57Smhitch TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 9011.1Sderaadt} 9021.1Sderaadt 9031.57Smhitch#define TRACEME_SENDSIGNAL_SIMPLE(test, sig) \ 9041.1SderaadtATF_TC(test); \ 9051.1SderaadtATF_TC_HEAD(test, tc) \ 9061.1Sderaadt{ \ 9071.69Sjonathan atf_tc_set_md_var(tc, "descr", \ 9081.69Sjonathan "Verify that a signal " #sig " emitted by a tracer to a child is " \ 9091.69Sjonathan "handled correctly in a child without a signal handler"); \ 9101.57Smhitch} \ 9111.65Sjonathan \ 9121.57SmhitchATF_TC_BODY(test, tc) \ 9131.1Sderaadt{ \ 9141.1Sderaadt \ 9151.57Smhitch traceme_sendsignal_simple(sig); \ 9161.57Smhitch} 9171.57Smhitch 9181.57SmhitchTRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple1, SIGKILL) /* non-maskable*/ 9191.57SmhitchTRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple2, SIGSTOP) /* non-maskable*/ 9201.57SmhitchTRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple3, SIGABRT) /* abort trap */ 9211.1SderaadtTRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple4, SIGHUP) /* hangup */ 9221.1SderaadtTRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple5, SIGCONT) /* continued? */ 9231.57SmhitchTRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple6, SIGTRAP) /* crash sig. */ 9241.82SthorpejTRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple7, SIGBUS) /* crash sig. */ 9251.82SthorpejTRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple8, SIGILL) /* crash sig. */ 9261.82SthorpejTRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple9, SIGFPE) /* crash sig. */ 9271.82SthorpejTRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple10, SIGSEGV) /* crash sig. */ 9281.82Sthorpej 9291.82Sthorpej/// ---------------------------------------------------------------------------- 9301.82Sthorpej 9311.82SthorpejATF_TC(traceme_pid1_parent); 9321.82SthorpejATF_TC_HEAD(traceme_pid1_parent, tc) 9331.82Sthorpej{ 9341.57Smhitch atf_tc_set_md_var(tc, "descr", 9351.57Smhitch "Verify that PT_TRACE_ME is not allowed when our parent is PID1"); 9361.1Sderaadt} 9371.65Sjonathan 9381.57SmhitchATF_TC_BODY(traceme_pid1_parent, tc) 9391.57Smhitch{ 9401.57Smhitch struct msg_fds parent_child; 9411.1Sderaadt int exitval_child1 = 1, exitval_child2 = 2; 9421.82Sthorpej pid_t child1, child2, wpid; 9431.82Sthorpej uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */ 9441.57Smhitch#if defined(TWAIT_HAVE_STATUS) 9451.57Smhitch int status; 9461.57Smhitch#endif 9471.57Smhitch 9481.57Smhitch SYSCALL_REQUIRE(msg_open(&parent_child) == 0); 9491.57Smhitch 9501.57Smhitch DPRINTF("Before forking process PID=%d\n", getpid()); 9511.57Smhitch SYSCALL_REQUIRE((child1 = fork()) != -1); 9521.57Smhitch if (child1 == 0) { 9531.57Smhitch DPRINTF("Before forking process PID=%d\n", getpid()); 9541.57Smhitch SYSCALL_REQUIRE((child2 = fork()) != -1); 9551.57Smhitch if (child2 != 0) { 9561.57Smhitch DPRINTF("Parent process PID=%d, child2's PID=%d\n", 9571.1Sderaadt getpid(), child2); 9581.82Sthorpej _exit(exitval_child1); 9591.69Sjonathan } 9601.69Sjonathan CHILD_FROM_PARENT("exit child1", parent_child, msg); 9611.57Smhitch 9621.57Smhitch DPRINTF("Assert that our parent is PID1 (initproc)\n"); 9631.3Sglass FORKEE_ASSERT_EQ(getppid(), 1); 9641.1Sderaadt 9651.57Smhitch DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 9661.57Smhitch FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) == -1); 9671.57Smhitch SYSCALL_REQUIRE_ERRNO(errno, EPERM); 9681.1Sderaadt 9691.57Smhitch CHILD_TO_PARENT("child2 exiting", parent_child, msg); 9701.57Smhitch 9711.1Sderaadt _exit(exitval_child2); 9721.65Sjonathan } 9731.57Smhitch DPRINTF("Parent process PID=%d, child1's PID=%d\n", getpid(), child1); 9741.57Smhitch 9751.57Smhitch DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 9761.57Smhitch TWAIT_REQUIRE_SUCCESS( 9771.57Smhitch wpid = TWAIT_GENERIC(child1, &status, WEXITED), child1); 9781.87Sjonathan 9791.1Sderaadt validate_status_exited(status, exitval_child1); 9801.57Smhitch 9811.57Smhitch DPRINTF("Notify that child1 is dead\n"); 9821.32Sjonathan PARENT_TO_CHILD("exit child1", parent_child, msg); 9831.57Smhitch 9841.57Smhitch DPRINTF("Wait for exiting of child2\n"); 9851.57Smhitch PARENT_FROM_CHILD("child2 exiting", parent_child, msg); 9861.1Sderaadt} 9871.57Smhitch 9881.57Smhitch/// ---------------------------------------------------------------------------- 9891.1Sderaadt 9901.57Smhitchstatic void 9911.57Smhitchtraceme_vfork_raise(int sigval) 9921.57Smhitch{ 9931.57Smhitch const int exitval = 5, exitval_watcher = 10; 9941.57Smhitch pid_t child, parent, watcher, wpid; 9951.57Smhitch int rv; 9961.57Smhitch#if defined(TWAIT_HAVE_STATUS) 9971.57Smhitch int status; 9981.1Sderaadt 9991.57Smhitch /* volatile workarounds GCC -Werror=clobbered */ 10001.79Sveego volatile int expect_core; 10011.57Smhitch 10021.1Sderaadt switch (sigval) { 10031.80Swrstuden case SIGABRT: 10041.87Sjonathan case SIGTRAP: 10051.80Swrstuden case SIGBUS: 10061.87Sjonathan case SIGILL: 10071.80Swrstuden case SIGFPE: 10081.87Sjonathan case SIGSEGV: 10091.87Sjonathan expect_core = 1; 10101.87Sjonathan break; 10111.87Sjonathan default: 10121.87Sjonathan expect_core = 0; 10131.87Sjonathan break; 10141.87Sjonathan } 10151.87Sjonathan#endif 10161.87Sjonathan 10171.87Sjonathan /* 10181.87Sjonathan * Spawn a dedicated thread to watch for a stopped child and emit 10191.87Sjonathan * the SIGKILL signal to it. 10201.87Sjonathan * 10211.87Sjonathan * vfork(2) might clobber watcher, this means that it's safer and 10221.87Sjonathan * simpler to reparent this process to initproc and forget about it. 10231.80Swrstuden */ 10241.80Swrstuden if (sigval == SIGSTOP) { 10251.57Smhitch parent = getpid(); 10261.57Smhitch 10271.57Smhitch watcher = fork(); 10281.57Smhitch ATF_REQUIRE(watcher != 1); 10291.57Smhitch if (watcher == 0) { 10301.22Sjonathan /* Double fork(2) trick to reparent to initproc */ 10311.57Smhitch watcher = fork(); 10321.57Smhitch FORKEE_ASSERT_NEQ(watcher, -1); 10331.57Smhitch if (watcher != 0) 10341.1Sderaadt _exit(exitval_watcher); 10351.57Smhitch 10361.85Sjonathan child = await_stopped_child(parent); 10371.85Sjonathan 10381.85Sjonathan errno = 0; 10391.85Sjonathan rv = kill(child, SIGKILL); 10401.85Sjonathan FORKEE_ASSERT_EQ(rv, 0); 10411.85Sjonathan FORKEE_ASSERT_EQ(errno, 0); 10421.85Sjonathan 10431.85Sjonathan /* This exit value will be collected by initproc */ 10441.1Sderaadt _exit(0); 10451.1Sderaadt } 10461.57Smhitch DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 10471.57Smhitch TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(watcher, &status, 0), 10481.1Sderaadt watcher); 10491.1Sderaadt 10501.1Sderaadt validate_status_exited(status, exitval_watcher); 10511.33Sjonathan 10521.1Sderaadt DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 10531.1Sderaadt TWAIT_REQUIRE_FAILURE(ECHILD, 10541.1Sderaadt wpid = TWAIT_GENERIC(watcher, &status, 0)); 10551.1Sderaadt } 10561.1Sderaadt 10571.82Sthorpej DPRINTF("Before forking process PID=%d\n", getpid()); 10581.82Sthorpej SYSCALL_REQUIRE((child = vfork()) != -1); 10591.82Sthorpej if (child == 0) { 10601.1Sderaadt DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 10611.82Sthorpej FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 10621.57Smhitch 10631.33Sjonathan DPRINTF("Before raising %s from child\n", strsignal(sigval)); 10641.57Smhitch FORKEE_ASSERT(raise(sigval) == 0); 10651.83Sjonathan 10661.83Sjonathan switch (sigval) { 10671.83Sjonathan case SIGSTOP: 10681.28Sjonathan case SIGKILL: 10691.57Smhitch case SIGABRT: 10701.57Smhitch case SIGHUP: 10711.57Smhitch case SIGTRAP: 10721.45Schristos case SIGBUS: 10731.57Smhitch case SIGILL: 10741.57Smhitch case SIGFPE: 10751.1Sderaadt case SIGSEGV: 10761.83Sjonathan /* NOTREACHED */ 10771.14Sjonathan FORKEE_ASSERTX(0 && "This shall not be reached"); 10781.57Smhitch __unreachable(); 10791.65Sjonathan default: 10801.65Sjonathan DPRINTF("Before exiting of the child process\n"); 10811.57Smhitch _exit(exitval); 10821.57Smhitch } 10831.1Sderaadt } 10841.82Sthorpej DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 10851.82Sthorpej 10861.82Sthorpej DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 10871.1Sderaadt TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 10881.82Sthorpej 10891.28Sjonathan switch (sigval) { 10901.1Sderaadt case SIGKILL: 10911.79Sveego case SIGABRT: 10921.57Smhitch case SIGHUP: 10931.57Smhitch case SIGTRAP: 10941.57Smhitch case SIGBUS: 10951.80Swrstuden case SIGILL: 10961.80Swrstuden case SIGFPE: 10971.80Swrstuden case SIGSEGV: 10981.1Sderaadt validate_status_signaled(status, sigval, expect_core); 10991.1Sderaadt break; 11001.57Smhitch case SIGSTOP: 11011.1Sderaadt validate_status_signaled(status, SIGKILL, 0); 11021.1Sderaadt break; 11031.57Smhitch case SIGCONT: 11041.87Sjonathan case SIGTSTP: 11051.87Sjonathan case SIGTTIN: 11061.87Sjonathan case SIGTTOU: 11071.1Sderaadt validate_status_exited(status, exitval); 11081.20Spaulus break; 11091.57Smhitch default: 11101.20Spaulus /* NOTREACHED */ 11111.21Sjonathan ATF_REQUIRE(0 && "NOT IMPLEMENTED"); 11121.20Spaulus break; 11131.57Smhitch } 11141.65Sjonathan 11151.14Sjonathan DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 11161.82Sthorpej TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 11171.82Sthorpej} 11181.82Sthorpej 11191.57Smhitch#define TRACEME_VFORK_RAISE(test, sig) \ 11201.82SthorpejATF_TC(test); \ 11211.28SjonathanATF_TC_HEAD(test, tc) \ 11221.14Sjonathan{ \ 11231.43Sjonathan atf_tc_set_md_var(tc, "descr", \ 11241.1Sderaadt "Verify PT_TRACE_ME followed by raise of " #sig " in a " \ 11251.1Sderaadt "vfork(2)ed child"); \ 11261.1Sderaadt} \ 11271.57Smhitch \ 11281.57SmhitchATF_TC_BODY(test, tc) \ 11291.57Smhitch{ \ 11301.1Sderaadt \ 11311.22Sjonathan traceme_vfork_raise(sig); \ 11321.57Smhitch} 11331.1Sderaadt 11341.1SderaadtTRACEME_VFORK_RAISE(traceme_vfork_raise1, SIGKILL) /* non-maskable */ 11351.57SmhitchTRACEME_VFORK_RAISE(traceme_vfork_raise2, SIGSTOP) /* non-maskable */ 11361.1SderaadtTRACEME_VFORK_RAISE(traceme_vfork_raise3, SIGTSTP) /* ignored in vfork(2) */ 11371.82SthorpejTRACEME_VFORK_RAISE(traceme_vfork_raise4, SIGTTIN) /* ignored in vfork(2) */ 11381.82SthorpejTRACEME_VFORK_RAISE(traceme_vfork_raise5, SIGTTOU) /* ignored in vfork(2) */ 11391.82SthorpejTRACEME_VFORK_RAISE(traceme_vfork_raise6, SIGABRT) /* regular abort trap */ 11401.1SderaadtTRACEME_VFORK_RAISE(traceme_vfork_raise7, SIGHUP) /* hangup */ 11411.82SthorpejTRACEME_VFORK_RAISE(traceme_vfork_raise8, SIGCONT) /* continued? */ 11421.1SderaadtTRACEME_VFORK_RAISE(traceme_vfork_raise9, SIGTRAP) /* crash signal */ 11431.3SglassTRACEME_VFORK_RAISE(traceme_vfork_raise10, SIGBUS) /* crash signal */ 11441.3SglassTRACEME_VFORK_RAISE(traceme_vfork_raise11, SIGILL) /* crash signal */ 11451.1SderaadtTRACEME_VFORK_RAISE(traceme_vfork_raise12, SIGFPE) /* crash signal */ 11461.1SderaadtTRACEME_VFORK_RAISE(traceme_vfork_raise13, SIGSEGV) /* crash signal */ 11471.57Smhitch 11481.57Smhitch/// ---------------------------------------------------------------------------- 11491.1Sderaadt 11501.1Sderaadtstatic void 11511.1Sderaadttraceme_vfork_crash(int sig) 11521.22Sjonathan{ 11531.1Sderaadt pid_t child, wpid; 11541.1Sderaadt#if defined(TWAIT_HAVE_STATUS) 11551.1Sderaadt int status; 11561.1Sderaadt#endif 11571.1Sderaadt 11581.62Sjonathan#ifndef PTRACE_ILLEGAL_ASM 11591.1Sderaadt if (sig == SIGILL) 11601.1Sderaadt atf_tc_skip("PTRACE_ILLEGAL_ASM not defined"); 11611.45Schristos#endif 11621.1Sderaadt 11631.1Sderaadt DPRINTF("Before forking process PID=%d\n", getpid()); 11641.1Sderaadt SYSCALL_REQUIRE((child = vfork()) != -1); 11651.1Sderaadt if (child == 0) { 11661.1Sderaadt DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 11671.1Sderaadt FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 11681.1Sderaadt 11691.62Sjonathan DPRINTF("Before executing a trap\n"); 11701.63Smhitch switch (sig) { 11711.45Schristos case SIGTRAP: 11721.65Sjonathan trigger_trap(); 11731.1Sderaadt break; 11741.45Schristos case SIGSEGV: 11751.1Sderaadt trigger_segv(); 11761.69Sjonathan break; 11771.1Sderaadt case SIGILL: 11781.1Sderaadt trigger_ill(); 11791.69Sjonathan break; 11801.1Sderaadt case SIGFPE: 11811.1Sderaadt trigger_fpe(); 11821.1Sderaadt break; 11831.1Sderaadt case SIGBUS: 11841.46Sjonathan trigger_bus(); 11851.46Sjonathan break; 11861.46Sjonathan default: 11871.41Sjonathan /* NOTREACHED */ 11881.41Sjonathan FORKEE_ASSERTX(0 && "This shall not be reached"); 11891.46Sjonathan } 11901.1Sderaadt 11911.41Sjonathan /* NOTREACHED */ 11921.41Sjonathan FORKEE_ASSERTX(0 && "This shall not be reached"); 11931.22Sjonathan } 11941.41Sjonathan DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 11951.41Sjonathan 11961.41Sjonathan DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 11971.41Sjonathan TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 11981.41Sjonathan 11991.41Sjonathan validate_status_signaled(status, sig, 1); 12001.22Sjonathan 12011.43Sjonathan DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 12021.1Sderaadt TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 12031.1Sderaadt} 12041.1Sderaadt 12051.34Sjonathan#define TRACEME_VFORK_CRASH(test, sig) \ 12061.1SderaadtATF_TC(test); \ 12071.1SderaadtATF_TC_HEAD(test, tc) \ 12081.1Sderaadt{ \ 12091.1Sderaadt atf_tc_set_md_var(tc, "descr", \ 12101.1Sderaadt "Verify PT_TRACE_ME followed by a crash signal " #sig " in a " \ 12111.1Sderaadt "vfork(2)ed child"); \ 12121.1Sderaadt} \ 12131.1Sderaadt \ 12141.1SderaadtATF_TC_BODY(test, tc) \ 12151.24Sjonathan{ \ 12161.65Sjonathan \ 12171.24Sjonathan traceme_vfork_crash(sig); \ 12181.46Sjonathan} 12191.1Sderaadt 12201.45SchristosTRACEME_VFORK_CRASH(traceme_vfork_crash_trap, SIGTRAP) 12211.3SglassTRACEME_VFORK_CRASH(traceme_vfork_crash_segv, SIGSEGV) 12221.1SderaadtTRACEME_VFORK_CRASH(traceme_vfork_crash_ill, SIGILL) 12231.1SderaadtTRACEME_VFORK_CRASH(traceme_vfork_crash_fpe, SIGFPE) 12241.1SderaadtTRACEME_VFORK_CRASH(traceme_vfork_crash_bus, SIGBUS) 12251.1Sderaadt 12261.1Sderaadt/// ---------------------------------------------------------------------------- 12271.1Sderaadt 12281.1SderaadtATF_TC(traceme_vfork_exec); 12291.1SderaadtATF_TC_HEAD(traceme_vfork_exec, tc) 12301.1Sderaadt{ 12311.1Sderaadt atf_tc_set_md_var(tc, "descr", 12321.1Sderaadt "Verify PT_TRACE_ME followed by exec(3) in a vfork(2)ed child"); 12331.1Sderaadt} 12341.1Sderaadt 12351.1SderaadtATF_TC_BODY(traceme_vfork_exec, tc) 12361.1Sderaadt{ 12371.1Sderaadt const int sigval = SIGTRAP; 12381.1Sderaadt pid_t child, wpid; 12391.1Sderaadt#if defined(TWAIT_HAVE_STATUS) 12401.1Sderaadt int status; 12411.1Sderaadt#endif 12421.1Sderaadt struct ptrace_siginfo info; 12431.34Sjonathan 12441.34Sjonathan memset(&info, 0, sizeof(info)); 12451.34Sjonathan 12461.1Sderaadt DPRINTF("Before forking process PID=%d\n", getpid()); 12471.1Sderaadt SYSCALL_REQUIRE((child = vfork()) != -1); 12481.1Sderaadt if (child == 0) { 12491.1Sderaadt DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 12501.1Sderaadt FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 12511.1Sderaadt 12521.34Sjonathan DPRINTF("Before calling execve(2) from child\n"); 12531.1Sderaadt execlp("/bin/echo", "/bin/echo", NULL); 12541.34Sjonathan 12551.34Sjonathan /* NOTREACHED */ 12561.34Sjonathan FORKEE_ASSERTX(0 && "Not reached"); 12571.1Sderaadt } 12581.1Sderaadt DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 12591.1Sderaadt 12601.1Sderaadt DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 12611.1Sderaadt TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 12621.1Sderaadt 12631.1Sderaadt validate_status_stopped(status, sigval); 12641.1Sderaadt 12651.1Sderaadt DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 12661.1Sderaadt SYSCALL_REQUIRE( 12671.1Sderaadt ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 12681.1Sderaadt 12691.1Sderaadt DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 12701.1Sderaadt DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 12711.1Sderaadt info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 12721.1Sderaadt info.psi_siginfo.si_errno); 12731.1Sderaadt 12741.1Sderaadt ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 12751.34Sjonathan ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_EXEC); 12761.34Sjonathan 12771.1Sderaadt DPRINTF("Before resuming the child process where it left off and " 12781.1Sderaadt "without signal to be sent\n"); 12791.1Sderaadt SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 12801.1Sderaadt 12811.1Sderaadt DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 12821.1Sderaadt TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 12831.1Sderaadt 12841.34Sjonathan DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 12851.34Sjonathan TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 12861.1Sderaadt} 12871.1Sderaadt 12881.1Sderaadt/// ---------------------------------------------------------------------------- 12891.1Sderaadt 12901.1Sderaadt#if defined(TWAIT_HAVE_PID) 12911.1Sderaadtstatic void 12921.1Sderaadtunrelated_tracer_sees_crash(int sig) 12931.34Sjonathan{ 12941.34Sjonathan struct msg_fds parent_tracee, parent_tracer; 12951.1Sderaadt const int exitval = 10; 12961.1Sderaadt pid_t tracee, tracer, wpid; 12971.1Sderaadt uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */ 12981.1Sderaadt#if defined(TWAIT_HAVE_STATUS) 12991.1Sderaadt int status; 13001.1Sderaadt#endif 13011.1Sderaadt struct ptrace_siginfo info; 13021.34Sjonathan 13031.34Sjonathan#ifndef PTRACE_ILLEGAL_ASM 13041.1Sderaadt if (sig == SIGILL) 13051.1Sderaadt atf_tc_skip("PTRACE_ILLEGAL_ASM not defined"); 13061.1Sderaadt#endif 13071.1Sderaadt 13081.1Sderaadt memset(&info, 0, sizeof(info)); 13091.1Sderaadt 13101.1Sderaadt DPRINTF("Spawn tracee\n"); 13111.1Sderaadt SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0); 13121.1Sderaadt tracee = atf_utils_fork(); 13131.1Sderaadt if (tracee == 0) { 13141.1Sderaadt // Wait for parent to let us crash 13151.65Sjonathan CHILD_FROM_PARENT("exit tracee", parent_tracee, msg); 13161.1Sderaadt 13171.65Sjonathan DPRINTF("Before executing a trap\n"); 13181.1Sderaadt switch (sig) { 13191.1Sderaadt case SIGTRAP: 13201.1Sderaadt trigger_trap(); 13211.1Sderaadt break; 13221.1Sderaadt case SIGSEGV: 13231.1Sderaadt trigger_segv(); 13241.1Sderaadt break; 13251.1Sderaadt case SIGILL: 13261.1Sderaadt trigger_ill(); 13271.1Sderaadt break; 13281.1Sderaadt case SIGFPE: 13291.1Sderaadt trigger_fpe(); 13301.1Sderaadt break; 13311.1Sderaadt case SIGBUS: 13321.1Sderaadt trigger_bus(); 13331.1Sderaadt break; 13341.1Sderaadt default: 13351.1Sderaadt /* NOTREACHED */ 13361.1Sderaadt FORKEE_ASSERTX(0 && "This shall not be reached"); 13371.45Schristos } 13381.1Sderaadt 13391.1Sderaadt /* NOTREACHED */ 13401.1Sderaadt FORKEE_ASSERTX(0 && "This shall not be reached"); 13411.1Sderaadt } 13421.1Sderaadt 13431.1Sderaadt DPRINTF("Spawn debugger\n"); 13441.1Sderaadt SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0); 13451.1Sderaadt tracer = atf_utils_fork(); 13461.1Sderaadt if (tracer == 0) { 13471.1Sderaadt /* Fork again and drop parent to reattach to PID 1 */ 13481.22Sjonathan tracer = atf_utils_fork(); 13491.54Sjonathan if (tracer != 0) 13501.57Smhitch _exit(exitval); 13511.1Sderaadt 13521.57Smhitch DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid()); 13531.57Smhitch FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1); 13541.57Smhitch 13551.57Smhitch /* Wait for tracee and assert that it was stopped w/ SIGSTOP */ 13561.1Sderaadt FORKEE_REQUIRE_SUCCESS( 13571.57Smhitch wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 13581.45Schristos 13591.1Sderaadt forkee_status_stopped(status, SIGSTOP); 13601.57Smhitch 13611.1Sderaadt /* Resume tracee with PT_CONTINUE */ 13621.57Smhitch FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1); 13631.57Smhitch 13641.57Smhitch /* Inform parent that tracer has attached to tracee */ 13651.57Smhitch CHILD_TO_PARENT("tracer ready", parent_tracer, msg); 13661.57Smhitch 13671.1Sderaadt /* Wait for parent to tell use that tracee should have exited */ 13681.1Sderaadt CHILD_FROM_PARENT("wait for tracee exit", parent_tracer, msg); 13691.65Sjonathan 13701.57Smhitch /* Wait for tracee and assert that it exited */ 13711.1Sderaadt FORKEE_REQUIRE_SUCCESS( 13721.1Sderaadt wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 13731.57Smhitch 13741.82Sthorpej validate_status_stopped(status, sig); 13751.82Sthorpej 13761.82Sthorpej DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for the " 13771.1Sderaadt "traced process\n"); 13781.82Sthorpej SYSCALL_REQUIRE( 13791.82Sthorpej ptrace(PT_GET_SIGINFO, tracee, &info, sizeof(info)) != -1); 13801.82Sthorpej 13811.82Sthorpej DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 13821.82Sthorpej DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 13831.82Sthorpej "si_errno=%#x\n", info.psi_siginfo.si_signo, 13841.82Sthorpej info.psi_siginfo.si_code, info.psi_siginfo.si_errno); 13851.82Sthorpej 13861.82Sthorpej ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sig); 13871.82Sthorpej switch (sig) { 13881.82Sthorpej case SIGTRAP: 13891.1Sderaadt ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_BRKPT); 13901.82Sthorpej break; 13911.1Sderaadt case SIGSEGV: 13921.57Smhitch ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SEGV_MAPERR); 13931.57Smhitch break; 13941.57Smhitch case SIGILL: 13951.57Smhitch ATF_REQUIRE_EQ(info.psi_siginfo.si_code, ILL_PRVOPC); 13961.57Smhitch break; 13971.65Sjonathan case SIGFPE: 13981.32Sjonathan ATF_REQUIRE_EQ(info.psi_siginfo.si_code, FPE_INTDIV); 13991.32Sjonathan break; 14001.32Sjonathan case SIGBUS: 14011.57Smhitch ATF_REQUIRE_EQ(info.psi_siginfo.si_code, BUS_ADRERR); 14021.57Smhitch break; 14031.57Smhitch } 14041.57Smhitch 14051.57Smhitch FORKEE_ASSERT(ptrace(PT_KILL, tracee, NULL, 0) != -1); 14061.57Smhitch DPRINTF("Before calling %s() for the tracee\n", TWAIT_FNAME); 14071.57Smhitch TWAIT_REQUIRE_SUCCESS( 14081.57Smhitch wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 14091.57Smhitch 14101.57Smhitch validate_status_signaled(status, SIGKILL, 0); 14111.57Smhitch 14121.57Smhitch DPRINTF("Before calling %s() for tracee\n", TWAIT_FNAME); 14131.57Smhitch TWAIT_REQUIRE_FAILURE(ECHILD, 14141.57Smhitch wpid = TWAIT_GENERIC(tracee, &status, 0)); 14151.57Smhitch 14161.57Smhitch /* Inform parent that tracer is exiting normally */ 14171.57Smhitch CHILD_TO_PARENT("tracer done", parent_tracer, msg); 14181.57Smhitch 14191.57Smhitch DPRINTF("Before exiting of the tracer process\n"); 14201.57Smhitch _exit(0 /* collect by initproc */); 14211.57Smhitch } 14221.57Smhitch 14231.57Smhitch DPRINTF("Wait for the tracer process (direct child) to exit " 14241.57Smhitch "calling %s()\n", TWAIT_FNAME); 14251.57Smhitch TWAIT_REQUIRE_SUCCESS( 14261.57Smhitch wpid = TWAIT_GENERIC(tracer, &status, 0), tracer); 14271.32Sjonathan 14281.32Sjonathan validate_status_exited(status, exitval); 14291.57Smhitch 14301.57Smhitch DPRINTF("Wait for the non-exited tracee process with %s()\n", 14311.57Smhitch TWAIT_FNAME); 14321.57Smhitch TWAIT_REQUIRE_SUCCESS( 14331.57Smhitch wpid = TWAIT_GENERIC(tracee, NULL, WNOHANG), 0); 14341.57Smhitch 14351.32Sjonathan DPRINTF("Wait for the tracer to attach to the tracee\n"); 14361.45Schristos PARENT_FROM_CHILD("tracer ready", parent_tracer, msg); 14371.32Sjonathan 14381.32Sjonathan DPRINTF("Resume the tracee and let it crash\n"); 14391.32Sjonathan PARENT_TO_CHILD("exit tracee", parent_tracee, msg); 14401.32Sjonathan 14411.32Sjonathan DPRINTF("Resume the tracer and let it detect crashed tracee\n"); 14421.57Smhitch PARENT_TO_CHILD("Message 2", parent_tracer, msg); 14431.57Smhitch 14441.32Sjonathan DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n", 14451.57Smhitch TWAIT_FNAME); 14461.57Smhitch TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 14471.33Sjonathan 14481.57Smhitch validate_status_signaled(status, SIGKILL, 0); 14491.57Smhitch 14501.1Sderaadt DPRINTF("Await normal exit of tracer\n"); 14511.3Sglass PARENT_FROM_CHILD("tracer done", parent_tracer, msg); 14521.45Schristos 14531.57Smhitch msg_close(&parent_tracer); 14541.1Sderaadt msg_close(&parent_tracee); 14551.57Smhitch} 14561.3Sglass 14571.57Smhitch#define UNRELATED_TRACER_SEES_CRASH(test, sig) \ 14581.1SderaadtATF_TC(test); \ 14591.1SderaadtATF_TC_HEAD(test, tc) \ 14601.73Sjonathan{ \ 14611.22Sjonathan atf_tc_set_md_var(tc, "descr", \ 14621.1Sderaadt "Assert that an unrelated tracer sees crash signal from the " \ 14631.56Sjonathan "debuggee"); \ 14641.1Sderaadt} \ 14651.1Sderaadt \ 14661.56SjonathanATF_TC_BODY(test, tc) \ 14671.69Sjonathan{ \ 14681.69Sjonathan \ 14691.1Sderaadt unrelated_tracer_sees_crash(sig); \ 14701.1Sderaadt} 14711.1Sderaadt 14721.1SderaadtUNRELATED_TRACER_SEES_CRASH(unrelated_tracer_sees_crash_trap, SIGTRAP) 14731.1SderaadtUNRELATED_TRACER_SEES_CRASH(unrelated_tracer_sees_crash_segv, SIGSEGV) 14741.1SderaadtUNRELATED_TRACER_SEES_CRASH(unrelated_tracer_sees_crash_ill, SIGILL) 14751.1SderaadtUNRELATED_TRACER_SEES_CRASH(unrelated_tracer_sees_crash_fpe, SIGFPE) 14761.16SjonathanUNRELATED_TRACER_SEES_CRASH(unrelated_tracer_sees_crash_bus, SIGBUS) 14771.16Sjonathan#endif 14781.69Sjonathan 14791.69Sjonathan/// ---------------------------------------------------------------------------- 14801.69Sjonathan 14811.16Sjonathan#if defined(TWAIT_HAVE_PID) 14821.1Sderaadtstatic void 14831.56Sjonathantracer_sees_terminaton_before_the_parent_raw(bool notimeout, bool unrelated, 14841.56Sjonathan bool stopped) 14851.56Sjonathan{ 14861.1Sderaadt /* 14871.16Sjonathan * notimeout - disable timeout in await zombie function 14881.69Sjonathan * unrelated - attach from unrelated tracer reparented to initproc 14891.16Sjonathan * stopped - attach to a stopped process 14901.69Sjonathan */ 14911.16Sjonathan 14921.16Sjonathan struct msg_fds parent_tracee, parent_tracer; 14931.69Sjonathan const int exitval_tracee = 5; 14941.1Sderaadt const int exitval_tracer = 10; 14951.1Sderaadt pid_t tracee, tracer, wpid; 14961.1Sderaadt uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */ 14971.1Sderaadt#if defined(TWAIT_HAVE_STATUS) 14981.16Sjonathan int status; 14991.71Sjonathan#endif 15001.1Sderaadt 15011.16Sjonathan /* 15021.1Sderaadt * Only a subset of options are supported. 15031.16Sjonathan */ 15041.16Sjonathan ATF_REQUIRE((!notimeout && !unrelated && !stopped) || 15051.16Sjonathan (!notimeout && unrelated && !stopped) || 15061.16Sjonathan (notimeout && !unrelated && !stopped) || 15071.16Sjonathan (!notimeout && unrelated && stopped)); 15081.16Sjonathan 15091.17Sjonathan DPRINTF("Spawn tracee\n"); 15101.17Sjonathan SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0); 15111.16Sjonathan tracee = atf_utils_fork(); 15121.16Sjonathan if (tracee == 0) { 15131.16Sjonathan if (stopped) { 15141.16Sjonathan DPRINTF("Stop self PID %d\n", getpid()); 15151.16Sjonathan raise(SIGSTOP); 15161.16Sjonathan } 15171.16Sjonathan 15181.16Sjonathan // Wait for parent to let us exit 15191.16Sjonathan CHILD_FROM_PARENT("exit tracee", parent_tracee, msg); 15201.16Sjonathan _exit(exitval_tracee); 15211.35Sjonathan } 15221.35Sjonathan 15231.35Sjonathan DPRINTF("Spawn debugger\n"); 15241.35Sjonathan SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0); 15251.35Sjonathan tracer = atf_utils_fork(); 15261.35Sjonathan if (tracer == 0) { 15271.35Sjonathan if(unrelated) { 15281.35Sjonathan /* Fork again and drop parent to reattach to PID 1 */ 15291.35Sjonathan tracer = atf_utils_fork(); 15301.43Sjonathan if (tracer != 0) 15311.42Sjonathan _exit(exitval_tracer); 15321.50Sjonathan } 15331.1Sderaadt 15341.35Sjonathan if (stopped) { 15351.50Sjonathan DPRINTF("Await for a stopped parent PID %d\n", tracee); 15361.57Smhitch await_stopped(tracee); 15371.57Smhitch } 15381.57Smhitch 15391.57Smhitch DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid()); 15401.16Sjonathan FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1); 15411.16Sjonathan 15421.77Smhitch /* Wait for tracee and assert that it was stopped w/ SIGSTOP */ 15431.57Smhitch FORKEE_REQUIRE_SUCCESS( 15441.16Sjonathan wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 15451.1Sderaadt 15461.71Sjonathan forkee_status_stopped(status, SIGSTOP); 15471.71Sjonathan 15481.71Sjonathan /* Resume tracee with PT_CONTINUE */ 15491.71Sjonathan FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1); 15501.71Sjonathan 15511.71Sjonathan /* Inform parent that tracer has attached to tracee */ 15521.71Sjonathan CHILD_TO_PARENT("tracer ready", parent_tracer, msg); 15531.71Sjonathan 15541.71Sjonathan /* Wait for parent to tell use that tracee should have exited */ 15551.71Sjonathan CHILD_FROM_PARENT("wait for tracee exit", parent_tracer, msg); 15561.71Sjonathan 15571.77Smhitch /* Wait for tracee and assert that it exited */ 15581.71Sjonathan FORKEE_REQUIRE_SUCCESS( 15591.71Sjonathan wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 15601.71Sjonathan 15611.42Sjonathan forkee_status_exited(status, exitval_tracee); 15621.35Sjonathan DPRINTF("Tracee %d exited with %d\n", tracee, exitval_tracee); 15631.42Sjonathan 15641.50Sjonathan DPRINTF("Before exiting of the tracer process\n"); 15651.35Sjonathan _exit(unrelated ? 0 /* collect by initproc */ : exitval_tracer); 15661.71Sjonathan } 15671.50Sjonathan 15681.57Smhitch if (unrelated) { 15691.57Smhitch DPRINTF("Wait for the tracer process (direct child) to exit " 15701.57Smhitch "calling %s()\n", TWAIT_FNAME); 15711.57Smhitch TWAIT_REQUIRE_SUCCESS( 15721.35Sjonathan wpid = TWAIT_GENERIC(tracer, &status, 0), tracer); 15731.35Sjonathan 15741.77Smhitch validate_status_exited(status, exitval_tracer); 15751.57Smhitch 15761.35Sjonathan DPRINTF("Wait for the non-exited tracee process with %s()\n", 15771.35Sjonathan TWAIT_FNAME); 15781.71Sjonathan TWAIT_REQUIRE_SUCCESS( 15791.71Sjonathan wpid = TWAIT_GENERIC(tracee, NULL, WNOHANG), 0); 15801.71Sjonathan } 15811.71Sjonathan 15821.71Sjonathan DPRINTF("Wait for the tracer to attach to the tracee\n"); 15831.71Sjonathan PARENT_FROM_CHILD("tracer ready", parent_tracer, msg); 15841.71Sjonathan 15851.71Sjonathan DPRINTF("Resume the tracee and let it exit\n"); 15861.71Sjonathan PARENT_TO_CHILD("exit tracee", parent_tracee, msg); 15871.71Sjonathan 15881.71Sjonathan DPRINTF("Detect that tracee is zombie\n"); 15891.77Smhitch if (notimeout) 15901.71Sjonathan await_zombie_raw(tracee, 0); 15911.71Sjonathan else 15921.71Sjonathan await_zombie(tracee); 15931.42Sjonathan 15941.1Sderaadt DPRINTF("Assert that there is no status about tracee %d - " 15951.16Sjonathan "Tracer must detect zombie first - calling %s()\n", tracee, 15961.16Sjonathan TWAIT_FNAME); 15971.16Sjonathan TWAIT_REQUIRE_SUCCESS( 15981.16Sjonathan wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0); 15991.16Sjonathan 16001.16Sjonathan if (unrelated) { 16011.16Sjonathan DPRINTF("Resume the tracer and let it detect exited tracee\n"); 16021.35Sjonathan PARENT_TO_CHILD("Message 2", parent_tracer, msg); 16031.35Sjonathan } else { 16041.35Sjonathan DPRINTF("Tell the tracer child should have exited\n"); 16051.35Sjonathan PARENT_TO_CHILD("wait for tracee exit", parent_tracer, msg); 16061.43Sjonathan DPRINTF("Wait for tracer to finish its job and exit - calling " 16071.50Sjonathan "%s()\n", TWAIT_FNAME); 16081.50Sjonathan 16091.57Smhitch DPRINTF("Wait from tracer child to complete waiting for " 16101.57Smhitch "tracee\n"); 16111.57Smhitch TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0), 16121.50Sjonathan tracer); 16131.50Sjonathan 16141.50Sjonathan validate_status_exited(status, exitval_tracer); 16151.50Sjonathan } 16161.50Sjonathan 16171.50Sjonathan DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n", 16181.47Sjonathan TWAIT_FNAME); 16191.47Sjonathan TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 16201.47Sjonathan 16211.43Sjonathan validate_status_exited(status, exitval_tracee); 16221.43Sjonathan 16231.43Sjonathan msg_close(&parent_tracer); 16241.35Sjonathan msg_close(&parent_tracee); 16251.43Sjonathan} 16261.35Sjonathan 16271.50SjonathanATF_TC(tracer_sees_terminaton_before_the_parent); 16281.50SjonathanATF_TC_HEAD(tracer_sees_terminaton_before_the_parent, tc) 16291.57Smhitch{ 16301.50Sjonathan atf_tc_set_md_var(tc, "descr", 16311.57Smhitch "Assert that tracer sees process termination before the parent"); 16321.57Smhitch} 16331.50Sjonathan 16341.50SjonathanATF_TC_BODY(tracer_sees_terminaton_before_the_parent, tc) 16351.35Sjonathan{ 16361.57Smhitch 16371.50Sjonathan tracer_sees_terminaton_before_the_parent_raw(false, false, false); 16381.50Sjonathan} 16391.47Sjonathan 16401.47SjonathanATF_TC(tracer_sysctl_lookup_without_duplicates); 16411.47SjonathanATF_TC_HEAD(tracer_sysctl_lookup_without_duplicates, tc) 16421.42Sjonathan{ 16431.35Sjonathan atf_tc_set_md_var(tc, "descr", 16441.35Sjonathan "Assert that await_zombie() in attach1 always finds a single " 16451.57Smhitch "process and no other error is reported"); 16461.16Sjonathan} 16471.57Smhitch 16481.16SjonathanATF_TC_BODY(tracer_sysctl_lookup_without_duplicates, tc) 16491.16Sjonathan{ 16501.16Sjonathan time_t start, end; 16511.1Sderaadt double diff; 16521.16Sjonathan unsigned long N = 0; 16531.16Sjonathan 16541.71Sjonathan /* 16551.71Sjonathan * Reuse this test with tracer_sees_terminaton_before_the_parent_raw(). 16561.71Sjonathan * This test body isn't specific to this race, however it's just good 16571.71Sjonathan * enough for this purposes, no need to invent a dedicated code flow. 16581.1Sderaadt */ 16591.47Sjonathan 16601.47Sjonathan start = time(NULL); 16611.1Sderaadt while (true) { 16621.37Sjonathan DPRINTF("Step: %lu\n", N); 16631.37Sjonathan tracer_sees_terminaton_before_the_parent_raw(true, false, 16641.37Sjonathan false); 16651.37Sjonathan end = time(NULL); 16661.37Sjonathan diff = difftime(end, start); 16671.37Sjonathan if (diff >= 5.0) 16681.1Sderaadt break; 16691.1Sderaadt ++N; 16701.1Sderaadt } 16711.1Sderaadt DPRINTF("Iterations: %lu\n", N); 16721.1Sderaadt} 16731.1Sderaadt 16741.1SderaadtATF_TC(unrelated_tracer_sees_terminaton_before_the_parent); 16751.1SderaadtATF_TC_HEAD(unrelated_tracer_sees_terminaton_before_the_parent, tc) 16761.16Sjonathan{ 16771.16Sjonathan atf_tc_set_md_var(tc, "descr", 16781.16Sjonathan "Assert that tracer sees process termination before the parent"); 16791.1Sderaadt} 16801.16Sjonathan 16811.16SjonathanATF_TC_BODY(unrelated_tracer_sees_terminaton_before_the_parent, tc) 16821.16Sjonathan{ 16831.16Sjonathan 16841.16Sjonathan tracer_sees_terminaton_before_the_parent_raw(false, true, false); 16851.16Sjonathan} 16861.1Sderaadt 16871.16SjonathanATF_TC(tracer_attach_to_unrelated_stopped_process); 16881.16SjonathanATF_TC_HEAD(tracer_attach_to_unrelated_stopped_process, tc) 16891.16Sjonathan{ 16901.16Sjonathan atf_tc_set_md_var(tc, "descr", 16911.37Sjonathan "Assert that tracer can attach to an unrelated stopped process"); 16921.16Sjonathan} 16931.37Sjonathan 16941.1SderaadtATF_TC_BODY(tracer_attach_to_unrelated_stopped_process, tc) 16951.1Sderaadt{ 16961.1Sderaadt 16971.1Sderaadt tracer_sees_terminaton_before_the_parent_raw(false, true, true); 16981.71Sjonathan} 16991.16Sjonathan#endif 17001.16Sjonathan 17011.1Sderaadt/// ---------------------------------------------------------------------------- 17021.1Sderaadt 17031.1Sderaadtstatic void 17041.1Sderaadtparent_attach_to_its_child(bool stopped) 17051.1Sderaadt{ 17061.1Sderaadt struct msg_fds parent_tracee; 17071.1Sderaadt const int exitval_tracee = 5; 17081.1Sderaadt pid_t tracee, wpid; 17091.1Sderaadt uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */ 17101.1Sderaadt#if defined(TWAIT_HAVE_STATUS) 17111.1Sderaadt int status; 17121.1Sderaadt#endif 17131.1Sderaadt 17141.1Sderaadt DPRINTF("Spawn tracee\n"); 17151.1Sderaadt SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0); 17161.1Sderaadt tracee = atf_utils_fork(); 17171.1Sderaadt if (tracee == 0) { 17181.1Sderaadt CHILD_FROM_PARENT("Message 1", parent_tracee, msg); 17191.1Sderaadt DPRINTF("Parent should now attach to tracee\n"); 17201.1Sderaadt 17211.1Sderaadt if (stopped) { 17221.1Sderaadt DPRINTF("Stop self PID %d\n", getpid()); 17231.1Sderaadt SYSCALL_REQUIRE(raise(SIGSTOP) != -1); 17241.1Sderaadt } 17251.1Sderaadt 17261.1Sderaadt CHILD_FROM_PARENT("Message 2", parent_tracee, msg); 17271.1Sderaadt /* Wait for message from the parent */ 17281.1Sderaadt _exit(exitval_tracee); 17291.1Sderaadt } 17301.1Sderaadt PARENT_TO_CHILD("Message 1", parent_tracee, msg); 17311.1Sderaadt 17321.1Sderaadt if (stopped) { 17331.1Sderaadt DPRINTF("Await for a stopped tracee PID %d\n", tracee); 17341.1Sderaadt await_stopped(tracee); 17351.1Sderaadt } 17361.1Sderaadt 17371.1Sderaadt DPRINTF("Before calling PT_ATTACH for tracee %d\n", tracee); 17381.1Sderaadt SYSCALL_REQUIRE(ptrace(PT_ATTACH, tracee, NULL, 0) != -1); 17391.1Sderaadt 17401.1Sderaadt DPRINTF("Wait for the stopped tracee process with %s()\n", 17411.1Sderaadt TWAIT_FNAME); 17421.1Sderaadt TWAIT_REQUIRE_SUCCESS( 17431.1Sderaadt wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 17441.1Sderaadt 17451.1Sderaadt validate_status_stopped(status, SIGSTOP); 17461.1Sderaadt 17471.1Sderaadt DPRINTF("Resume tracee with PT_CONTINUE\n"); 17481.16Sjonathan SYSCALL_REQUIRE(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1); 17491.1Sderaadt 17501.1Sderaadt DPRINTF("Let the tracee exit now\n"); 17511.1Sderaadt PARENT_TO_CHILD("Message 2", parent_tracee, msg); 17521.1Sderaadt 17531.1Sderaadt DPRINTF("Wait for tracee to exit with %s()\n", TWAIT_FNAME); 17541.1Sderaadt TWAIT_REQUIRE_SUCCESS( 17551.1Sderaadt wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 17561.1Sderaadt 17571.1Sderaadt validate_status_exited(status, exitval_tracee); 17581.1Sderaadt 17591.1Sderaadt DPRINTF("Before calling %s() for tracee\n", TWAIT_FNAME); 17601.1Sderaadt TWAIT_REQUIRE_FAILURE(ECHILD, 17611.1Sderaadt wpid = TWAIT_GENERIC(tracee, &status, 0)); 17621.1Sderaadt 17631.1Sderaadt msg_close(&parent_tracee); 17641.1Sderaadt} 17651.1Sderaadt 17661.1SderaadtATF_TC(parent_attach_to_its_child); 17671.1SderaadtATF_TC_HEAD(parent_attach_to_its_child, tc) 17681.1Sderaadt{ 17691.1Sderaadt atf_tc_set_md_var(tc, "descr", 17701.1Sderaadt "Assert that tracer parent can PT_ATTACH to its child"); 17711.1Sderaadt} 17721.1Sderaadt 17731.1SderaadtATF_TC_BODY(parent_attach_to_its_child, tc) 17741.1Sderaadt{ 17751.1Sderaadt 17761.1Sderaadt parent_attach_to_its_child(false); 17771.1Sderaadt} 17781.1Sderaadt 17791.1SderaadtATF_TC(parent_attach_to_its_stopped_child); 17801.71SjonathanATF_TC_HEAD(parent_attach_to_its_stopped_child, tc) 17811.71Sjonathan{ 17821.71Sjonathan atf_tc_set_md_var(tc, "descr", 17831.71Sjonathan "Assert that tracer parent can PT_ATTACH to its stopped child"); 17841.71Sjonathan} 17851.1Sderaadt 17861.1SderaadtATF_TC_BODY(parent_attach_to_its_stopped_child, tc) 17871.1Sderaadt{ 17881.1Sderaadt 17891.16Sjonathan parent_attach_to_its_child(true); 17901.16Sjonathan} 17911.1Sderaadt 17921.1Sderaadt/// ---------------------------------------------------------------------------- 17931.1Sderaadt 17941.16Sjonathanstatic void 17951.1Sderaadtchild_attach_to_its_parent(bool stopped) 17961.1Sderaadt{ 17971.16Sjonathan struct msg_fds parent_tracee; 17981.16Sjonathan const int exitval_tracer = 5; 17991.1Sderaadt pid_t tracer, wpid; 18001.1Sderaadt uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */ 18011.16Sjonathan#if defined(TWAIT_HAVE_STATUS) 18021.17Sjonathan int status; 18031.16Sjonathan#endif 18041.16Sjonathan 18051.16Sjonathan DPRINTF("Spawn tracer\n"); 18061.16Sjonathan SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0); 18071.1Sderaadt tracer = atf_utils_fork(); 18081.1Sderaadt if (tracer == 0) { 18091.16Sjonathan /* Wait for message from the parent */ 18101.16Sjonathan CHILD_FROM_PARENT("Message 1", parent_tracee, msg); 18111.16Sjonathan 18121.16Sjonathan if (stopped) { 18131.16Sjonathan DPRINTF("Await for a stopped parent PID %d\n", 18141.16Sjonathan getppid()); 18151.16Sjonathan await_stopped(getppid()); 18161.16Sjonathan } 18171.16Sjonathan 18181.16Sjonathan DPRINTF("Attach to parent PID %d with PT_ATTACH from child\n", 18191.23Sjonathan getppid()); 18201.23Sjonathan FORKEE_ASSERT(ptrace(PT_ATTACH, getppid(), NULL, 0) != -1); 18211.23Sjonathan 18221.16Sjonathan DPRINTF("Wait for the stopped parent process with %s()\n", 18231.16Sjonathan TWAIT_FNAME); 18241.35Sjonathan FORKEE_REQUIRE_SUCCESS( 18251.36Sjonathan wpid = TWAIT_GENERIC(getppid(), &status, 0), getppid()); 18261.35Sjonathan 18271.42Sjonathan forkee_status_stopped(status, SIGSTOP); 18281.42Sjonathan 18291.50Sjonathan DPRINTF("Resume parent with PT_DETACH\n"); 18301.50Sjonathan FORKEE_ASSERT(ptrace(PT_DETACH, getppid(), (void *)1, 0) 18311.57Smhitch != -1); 18321.50Sjonathan 18331.50Sjonathan /* Tell parent we are ready */ 18341.42Sjonathan CHILD_TO_PARENT("Message 1", parent_tracee, msg); 18351.35Sjonathan 18361.42Sjonathan _exit(exitval_tracer); 18371.50Sjonathan } 18381.50Sjonathan 18391.57Smhitch DPRINTF("Wait for the tracer to become ready\n"); 18401.50Sjonathan PARENT_TO_CHILD("Message 1", parent_tracee, msg); 18411.50Sjonathan 18421.42Sjonathan if (stopped) { 18431.35Sjonathan DPRINTF("Stop self PID %d\n", getpid()); 18441.16Sjonathan SYSCALL_REQUIRE(raise(SIGSTOP) != -1); 18451.16Sjonathan } 18461.16Sjonathan 18471.16Sjonathan DPRINTF("Allow the tracer to exit now\n"); 18481.16Sjonathan PARENT_FROM_CHILD("Message 1", parent_tracee, msg); 18491.16Sjonathan 18501.16Sjonathan DPRINTF("Wait for tracer to exit with %s()\n", TWAIT_FNAME); 18511.16Sjonathan TWAIT_REQUIRE_SUCCESS( 18521.16Sjonathan wpid = TWAIT_GENERIC(tracer, &status, 0), tracer); 18531.16Sjonathan 18541.16Sjonathan validate_status_exited(status, exitval_tracer); 18551.16Sjonathan 18561.16Sjonathan DPRINTF("Before calling %s() for tracer\n", TWAIT_FNAME); 18571.16Sjonathan TWAIT_REQUIRE_FAILURE(ECHILD, 18581.77Smhitch wpid = TWAIT_GENERIC(tracer, &status, 0)); 18591.77Smhitch 18601.77Smhitch msg_close(&parent_tracee); 18611.77Smhitch} 18621.77Smhitch 18631.16SjonathanATF_TC(child_attach_to_its_parent); 18641.77SmhitchATF_TC_HEAD(child_attach_to_its_parent, tc) 18651.77Smhitch{ 18661.77Smhitch atf_tc_set_md_var(tc, "descr", 18671.77Smhitch "Assert that tracer child can PT_ATTACH to its parent"); 18681.77Smhitch} 18691.77Smhitch 18701.77SmhitchATF_TC_BODY(child_attach_to_its_parent, tc) 18711.77Smhitch{ 18721.16Sjonathan 18731.16Sjonathan child_attach_to_its_parent(false); 18741.16Sjonathan} 18751.45Schristos 18761.16SjonathanATF_TC(child_attach_to_its_stopped_parent); 18771.16SjonathanATF_TC_HEAD(child_attach_to_its_stopped_parent, tc) 18781.16Sjonathan{ 18791.1Sderaadt atf_tc_set_md_var(tc, "descr", 18801.57Smhitch "Assert that tracer child can PT_ATTACH to its stopped parent"); 18811.66Smhitch} 18821.66Smhitch 18831.68SjonathanATF_TC_BODY(child_attach_to_its_stopped_parent, tc) 18841.68Sjonathan{ 18851.66Smhitch /* 18861.66Smhitch * The ATF framework (atf-run) does not tolerate raise(SIGSTOP), as 18871.69Sjonathan * this causes a pipe (established from atf-run) to be broken. 18881.66Smhitch * atf-run uses this mechanism to monitor whether a test is alive. 18891.66Smhitch * 18901.69Sjonathan * As a workaround spawn this test as a subprocess. 18911.66Smhitch */ 18921.66Smhitch 18931.66Smhitch const int exitval = 15; 18941.66Smhitch pid_t child, wpid; 18951.66Smhitch#if defined(TWAIT_HAVE_STATUS) 18961.66Smhitch int status; 18971.66Smhitch#endif 18981.66Smhitch 18991.66Smhitch SYSCALL_REQUIRE((child = fork()) != -1); 19001.66Smhitch if (child == 0) { 19011.69Sjonathan child_attach_to_its_parent(true); 19021.66Smhitch _exit(exitval); 19031.66Smhitch } else { 19041.69Sjonathan DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 19051.66Smhitch TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 19061.69Sjonathan 19071.69Sjonathan validate_status_exited(status, exitval); 19081.69Sjonathan 19091.69Sjonathan DPRINTF("Before calling %s() for the exited child\n", TWAIT_FNAME); 19101.69Sjonathan TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 19111.69Sjonathan } 19121.69Sjonathan} 19131.69Sjonathan 19141.69Sjonathan/// ---------------------------------------------------------------------------- 19151.66Smhitch 19161.66Smhitch#if defined(TWAIT_HAVE_PID) 19171.66Smhitch 19181.66Smhitchenum tracee_sees_its_original_parent_type { 19191.66Smhitch TRACEE_SEES_ITS_ORIGINAL_PARENT_GETPPID, 19201.66Smhitch TRACEE_SEES_ITS_ORIGINAL_PARENT_SYSCTL_KINFO_PROC2, 19211.72Sjonathan TRACEE_SEES_ITS_ORIGINAL_PARENT_PROCFS_STATUS 19221.66Smhitch}; 19231.68Sjonathan 19241.68Sjonathanstatic void 19251.66Smhitchtracee_sees_its_original_parent(enum tracee_sees_its_original_parent_type type) 19261.66Smhitch{ 19271.69Sjonathan struct msg_fds parent_tracer, parent_tracee; 19281.66Smhitch const int exitval_tracee = 5; 19291.66Smhitch const int exitval_tracer = 10; 19301.69Sjonathan pid_t parent, tracee, tracer, wpid; 19311.66Smhitch uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */ 19321.66Smhitch#if defined(TWAIT_HAVE_STATUS) 19331.66Smhitch int status; 19341.66Smhitch#endif 19351.66Smhitch /* sysctl(3) - kinfo_proc2 */ 19361.66Smhitch int name[CTL_MAXNAME]; 19371.66Smhitch struct kinfo_proc2 kp; 19381.66Smhitch size_t len = sizeof(kp); 19391.66Smhitch unsigned int namelen; 19401.66Smhitch 19411.69Sjonathan /* procfs - status */ 19421.66Smhitch FILE *fp; 19431.66Smhitch struct stat st; 19441.69Sjonathan const char *fname = "/proc/curproc/status"; 19451.66Smhitch char s_executable[MAXPATHLEN]; 19461.69Sjonathan int s_pid, s_ppid; 19471.69Sjonathan int rv; 19481.69Sjonathan 19491.69Sjonathan if (type == TRACEE_SEES_ITS_ORIGINAL_PARENT_PROCFS_STATUS) { 19501.66Smhitch SYSCALL_REQUIRE( 19511.66Smhitch (rv = stat(fname, &st)) == 0 || (errno == ENOENT)); 19521.66Smhitch if (rv != 0) 19531.66Smhitch atf_tc_skip("/proc/curproc/status not found"); 19541.72Sjonathan } 19551.66Smhitch 19561.69Sjonathan DPRINTF("Spawn tracee\n"); 19571.69Sjonathan SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0); 19581.69Sjonathan SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0); 19591.66Smhitch tracee = atf_utils_fork(); 19601.66Smhitch if (tracee == 0) { 19611.66Smhitch parent = getppid(); 19621.66Smhitch 19631.66Smhitch /* Emit message to the parent */ 19641.66Smhitch CHILD_TO_PARENT("tracee ready", parent_tracee, msg); 19651.66Smhitch CHILD_FROM_PARENT("exit tracee", parent_tracee, msg); 19661.69Sjonathan 19671.66Smhitch switch (type) { 19681.66Smhitch case TRACEE_SEES_ITS_ORIGINAL_PARENT_GETPPID: 19691.66Smhitch FORKEE_ASSERT_EQ(parent, getppid()); 19701.69Sjonathan break; 19711.66Smhitch case TRACEE_SEES_ITS_ORIGINAL_PARENT_SYSCTL_KINFO_PROC2: 19721.66Smhitch namelen = 0; 19731.66Smhitch name[namelen++] = CTL_KERN; 1974 name[namelen++] = KERN_PROC2; 1975 name[namelen++] = KERN_PROC_PID; 1976 name[namelen++] = getpid(); 1977 name[namelen++] = len; 1978 name[namelen++] = 1; 1979 1980 FORKEE_ASSERT_EQ( 1981 sysctl(name, namelen, &kp, &len, NULL, 0), 0); 1982 FORKEE_ASSERT_EQ(parent, kp.p_ppid); 1983 break; 1984 case TRACEE_SEES_ITS_ORIGINAL_PARENT_PROCFS_STATUS: 1985 /* 1986 * Format: 1987 * EXECUTABLE PID PPID ... 1988 */ 1989 FORKEE_ASSERT((fp = fopen(fname, "r")) != NULL); 1990 fscanf(fp, "%s %d %d", s_executable, &s_pid, &s_ppid); 1991 FORKEE_ASSERT_EQ(fclose(fp), 0); 1992 FORKEE_ASSERT_EQ(parent, s_ppid); 1993 break; 1994 } 1995 1996 _exit(exitval_tracee); 1997 } 1998 DPRINTF("Wait for child to record its parent identifier (pid)\n"); 1999 PARENT_FROM_CHILD("tracee ready", parent_tracee, msg); 2000 2001 DPRINTF("Spawn debugger\n"); 2002 tracer = atf_utils_fork(); 2003 if (tracer == 0) { 2004 /* No IPC to communicate with the child */ 2005 DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid()); 2006 FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1); 2007 2008 /* Wait for tracee and assert that it was stopped w/ SIGSTOP */ 2009 FORKEE_REQUIRE_SUCCESS( 2010 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 2011 2012 forkee_status_stopped(status, SIGSTOP); 2013 2014 /* Resume tracee with PT_CONTINUE */ 2015 FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1); 2016 2017 /* Inform parent that tracer has attached to tracee */ 2018 CHILD_TO_PARENT("tracer ready", parent_tracer, msg); 2019 2020 /* Wait for parent to tell use that tracee should have exited */ 2021 CHILD_FROM_PARENT("wait for tracee exit", parent_tracer, msg); 2022 2023 /* Wait for tracee and assert that it exited */ 2024 FORKEE_REQUIRE_SUCCESS( 2025 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 2026 2027 forkee_status_exited(status, exitval_tracee); 2028 2029 DPRINTF("Before exiting of the tracer process\n"); 2030 _exit(exitval_tracer); 2031 } 2032 2033 DPRINTF("Wait for the tracer to attach to the tracee\n"); 2034 PARENT_FROM_CHILD("tracer ready", parent_tracer, msg); 2035 2036 DPRINTF("Resume the tracee and let it exit\n"); 2037 PARENT_TO_CHILD("exit tracee", parent_tracee, msg); 2038 2039 DPRINTF("Detect that tracee is zombie\n"); 2040 await_zombie(tracee); 2041 2042 DPRINTF("Assert that there is no status about tracee - " 2043 "Tracer must detect zombie first - calling %s()\n", TWAIT_FNAME); 2044 TWAIT_REQUIRE_SUCCESS( 2045 wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0); 2046 2047 DPRINTF("Tell the tracer child should have exited\n"); 2048 PARENT_TO_CHILD("wait for tracee exit", parent_tracer, msg); 2049 2050 DPRINTF("Wait from tracer child to complete waiting for tracee\n"); 2051 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0), 2052 tracer); 2053 2054 validate_status_exited(status, exitval_tracer); 2055 2056 DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n", 2057 TWAIT_FNAME); 2058 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 2059 tracee); 2060 2061 validate_status_exited(status, exitval_tracee); 2062 2063 msg_close(&parent_tracer); 2064 msg_close(&parent_tracee); 2065} 2066 2067#define TRACEE_SEES_ITS_ORIGINAL_PARENT(test, type, descr) \ 2068ATF_TC(test); \ 2069ATF_TC_HEAD(test, tc) \ 2070{ \ 2071 atf_tc_set_md_var(tc, "descr", \ 2072 "Assert that tracee sees its original parent when being traced " \ 2073 "(check " descr ")"); \ 2074} \ 2075 \ 2076ATF_TC_BODY(test, tc) \ 2077{ \ 2078 \ 2079 tracee_sees_its_original_parent(type); \ 2080} 2081 2082TRACEE_SEES_ITS_ORIGINAL_PARENT( 2083 tracee_sees_its_original_parent_getppid, 2084 TRACEE_SEES_ITS_ORIGINAL_PARENT_GETPPID, 2085 "getppid(2)"); 2086TRACEE_SEES_ITS_ORIGINAL_PARENT( 2087 tracee_sees_its_original_parent_sysctl_kinfo_proc2, 2088 TRACEE_SEES_ITS_ORIGINAL_PARENT_SYSCTL_KINFO_PROC2, 2089 "sysctl(3) and kinfo_proc2"); 2090TRACEE_SEES_ITS_ORIGINAL_PARENT( 2091 tracee_sees_its_original_parent_procfs_status, 2092 TRACEE_SEES_ITS_ORIGINAL_PARENT_PROCFS_STATUS, 2093 "the status file in procfs"); 2094#endif 2095 2096/// ---------------------------------------------------------------------------- 2097 2098static void 2099eventmask_preserved(int event) 2100{ 2101 const int exitval = 5; 2102 const int sigval = SIGSTOP; 2103 pid_t child, wpid; 2104#if defined(TWAIT_HAVE_STATUS) 2105 int status; 2106#endif 2107 ptrace_event_t set_event, get_event; 2108 const int len = sizeof(ptrace_event_t); 2109 2110 DPRINTF("Before forking process PID=%d\n", getpid()); 2111 SYSCALL_REQUIRE((child = fork()) != -1); 2112 if (child == 0) { 2113 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 2114 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 2115 2116 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 2117 FORKEE_ASSERT(raise(sigval) == 0); 2118 2119 DPRINTF("Before exiting of the child process\n"); 2120 _exit(exitval); 2121 } 2122 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 2123 2124 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 2125 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 2126 2127 validate_status_stopped(status, sigval); 2128 2129 set_event.pe_set_event = event; 2130 SYSCALL_REQUIRE( 2131 ptrace(PT_SET_EVENT_MASK, child, &set_event, len) != -1); 2132 SYSCALL_REQUIRE( 2133 ptrace(PT_GET_EVENT_MASK, child, &get_event, len) != -1); 2134 ATF_REQUIRE(memcmp(&set_event, &get_event, len) == 0); 2135 2136 DPRINTF("Before resuming the child process where it left off and " 2137 "without signal to be sent\n"); 2138 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 2139 2140 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 2141 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 2142 2143 validate_status_exited(status, exitval); 2144 2145 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 2146 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 2147} 2148 2149#define EVENTMASK_PRESERVED(test, event) \ 2150ATF_TC(test); \ 2151ATF_TC_HEAD(test, tc) \ 2152{ \ 2153 atf_tc_set_md_var(tc, "descr", \ 2154 "Verify that eventmask " #event " is preserved"); \ 2155} \ 2156 \ 2157ATF_TC_BODY(test, tc) \ 2158{ \ 2159 \ 2160 eventmask_preserved(event); \ 2161} 2162 2163EVENTMASK_PRESERVED(eventmask_preserved_empty, 0) 2164EVENTMASK_PRESERVED(eventmask_preserved_fork, PTRACE_FORK) 2165EVENTMASK_PRESERVED(eventmask_preserved_vfork, PTRACE_VFORK) 2166EVENTMASK_PRESERVED(eventmask_preserved_vfork_done, PTRACE_VFORK_DONE) 2167EVENTMASK_PRESERVED(eventmask_preserved_lwp_create, PTRACE_LWP_CREATE) 2168EVENTMASK_PRESERVED(eventmask_preserved_lwp_exit, PTRACE_LWP_EXIT) 2169 2170/// ---------------------------------------------------------------------------- 2171 2172static void 2173fork_body(pid_t (*fn)(void), bool trackfork, bool trackvfork, 2174 bool trackvforkdone, bool detachchild, bool detachparent) 2175{ 2176 const int exitval = 5; 2177 const int exitval2 = 15; 2178 const int sigval = SIGSTOP; 2179 pid_t child, child2 = 0, wpid; 2180#if defined(TWAIT_HAVE_STATUS) 2181 int status; 2182#endif 2183 ptrace_state_t state; 2184 const int slen = sizeof(state); 2185 ptrace_event_t event; 2186 const int elen = sizeof(event); 2187 2188 DPRINTF("Before forking process PID=%d\n", getpid()); 2189 SYSCALL_REQUIRE((child = fork()) != -1); 2190 if (child == 0) { 2191 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 2192 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 2193 2194 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 2195 FORKEE_ASSERT(raise(sigval) == 0); 2196 2197 FORKEE_ASSERT((child2 = (fn)()) != -1); 2198 2199 if (child2 == 0) 2200 _exit(exitval2); 2201 2202 FORKEE_REQUIRE_SUCCESS 2203 (wpid = TWAIT_GENERIC(child2, &status, 0), child2); 2204 2205 forkee_status_exited(status, exitval2); 2206 2207 DPRINTF("Before exiting of the child process\n"); 2208 _exit(exitval); 2209 } 2210 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 2211 2212 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 2213 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 2214 2215 validate_status_stopped(status, sigval); 2216 2217 DPRINTF("Set 0%s%s%s in EVENT_MASK for the child %d\n", 2218 trackfork ? "|PTRACE_FORK" : "", 2219 trackvfork ? "|PTRACE_VFORK" : "", 2220 trackvforkdone ? "|PTRACE_VFORK_DONE" : "", child); 2221 event.pe_set_event = 0; 2222 if (trackfork) 2223 event.pe_set_event |= PTRACE_FORK; 2224 if (trackvfork) 2225 event.pe_set_event |= PTRACE_VFORK; 2226 if (trackvforkdone) 2227 event.pe_set_event |= PTRACE_VFORK_DONE; 2228 SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); 2229 2230 DPRINTF("Before resuming the child process where it left off and " 2231 "without signal to be sent\n"); 2232 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 2233 2234#if defined(TWAIT_HAVE_PID) 2235 if ((trackfork && fn == fork) || (trackvfork && fn == vfork)) { 2236 DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME, 2237 child); 2238 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), 2239 child); 2240 2241 validate_status_stopped(status, SIGTRAP); 2242 2243 SYSCALL_REQUIRE( 2244 ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 2245 if (trackfork && fn == fork) { 2246 ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK, 2247 PTRACE_FORK); 2248 } 2249 if (trackvfork && fn == vfork) { 2250 ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK, 2251 PTRACE_VFORK); 2252 } 2253 2254 child2 = state.pe_other_pid; 2255 DPRINTF("Reported ptrace event with forkee %d\n", child2); 2256 2257 DPRINTF("Before calling %s() for the forkee %d of the child " 2258 "%d\n", TWAIT_FNAME, child2, child); 2259 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0), 2260 child2); 2261 2262 validate_status_stopped(status, SIGTRAP); 2263 2264 SYSCALL_REQUIRE( 2265 ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1); 2266 if (trackfork && fn == fork) { 2267 ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK, 2268 PTRACE_FORK); 2269 } 2270 if (trackvfork && fn == vfork) { 2271 ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK, 2272 PTRACE_VFORK); 2273 } 2274 2275 ATF_REQUIRE_EQ(state.pe_other_pid, child); 2276 2277 DPRINTF("Before resuming the forkee process where it left off " 2278 "and without signal to be sent\n"); 2279 SYSCALL_REQUIRE( 2280 ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1); 2281 2282 DPRINTF("Before resuming the child process where it left off " 2283 "and without signal to be sent\n"); 2284 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 2285 } 2286#endif 2287 2288 if (trackvforkdone && fn == vfork) { 2289 DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME, 2290 child); 2291 TWAIT_REQUIRE_SUCCESS( 2292 wpid = TWAIT_GENERIC(child, &status, 0), child); 2293 2294 validate_status_stopped(status, SIGTRAP); 2295 2296 SYSCALL_REQUIRE( 2297 ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 2298 ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK_DONE); 2299 2300 child2 = state.pe_other_pid; 2301 DPRINTF("Reported PTRACE_VFORK_DONE event with forkee %d\n", 2302 child2); 2303 2304 DPRINTF("Before resuming the child process where it left off " 2305 "and without signal to be sent\n"); 2306 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 2307 } 2308 2309#if defined(TWAIT_HAVE_PID) 2310 if ((trackfork && fn == fork) || (trackvfork && fn == vfork)) { 2311 DPRINTF("Before calling %s() for the forkee - expected exited" 2312 "\n", TWAIT_FNAME); 2313 TWAIT_REQUIRE_SUCCESS( 2314 wpid = TWAIT_GENERIC(child2, &status, 0), child2); 2315 2316 validate_status_exited(status, exitval2); 2317 2318 DPRINTF("Before calling %s() for the forkee - expected no " 2319 "process\n", TWAIT_FNAME); 2320 TWAIT_REQUIRE_FAILURE(ECHILD, 2321 wpid = TWAIT_GENERIC(child2, &status, 0)); 2322 } 2323#endif 2324 2325 DPRINTF("Before calling %s() for the child - expected stopped " 2326 "SIGCHLD\n", TWAIT_FNAME); 2327 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 2328 2329 validate_status_stopped(status, SIGCHLD); 2330 2331 DPRINTF("Before resuming the child process where it left off and " 2332 "without signal to be sent\n"); 2333 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 2334 2335 DPRINTF("Before calling %s() for the child - expected exited\n", 2336 TWAIT_FNAME); 2337 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 2338 2339 validate_status_exited(status, exitval); 2340 2341 DPRINTF("Before calling %s() for the child - expected no process\n", 2342 TWAIT_FNAME); 2343 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 2344} 2345 2346#define FORK_TEST(name,descr,fun,tfork,tvfork,tvforkdone,detchild,detparent) \ 2347ATF_TC(name); \ 2348ATF_TC_HEAD(name, tc) \ 2349{ \ 2350 atf_tc_set_md_var(tc, "descr", descr); \ 2351} \ 2352 \ 2353ATF_TC_BODY(name, tc) \ 2354{ \ 2355 \ 2356 fork_body(fun, tfork, tvfork, tvforkdone, detchild, detparent); \ 2357} 2358 2359#define F false 2360#define T true 2361 2362#define F_IF__0(x) 2363#define F_IF__1(x) x 2364#define F_IF__(x,y) F_IF__ ## x (y) 2365#define F_IF_(x,y) F_IF__(x,y) 2366#define F_IF(x,y) F_IF_(x,y) 2367 2368#define DSCR(function,forkbit,vforkbit,vforkdonebit,dchildbit,dparentbit) \ 2369 "Verify " #function "(2) called with 0" \ 2370 F_IF(forkbit,"|PTRACE_FORK") \ 2371 F_IF(vforkbit,"|PTRACE_VFORK") \ 2372 F_IF(vforkdonebit,"|PTRACE_VFORK_DONE") \ 2373 " in EVENT_MASK." \ 2374 F_IF(dchildbit," Detach child in this test.") \ 2375 F_IF(dparentbit," Detach parent in this test.") 2376 2377FORK_TEST(fork1, DSCR(fork,0,0,0,0,0), fork, F, F, F, F, F) 2378#if defined(TWAIT_HAVE_PID) 2379FORK_TEST(fork2, DSCR(fork,1,0,0,0,0), fork, T, F, F, F, F) 2380FORK_TEST(fork3, DSCR(fork,0,1,0,0,0), fork, F, T, F, F, F) 2381FORK_TEST(fork4, DSCR(fork,1,1,0,0,0), fork, T, T, F, F, F) 2382#endif 2383FORK_TEST(fork5, DSCR(fork,0,0,1,0,0), fork, F, F, T, F, F) 2384#if defined(TWAIT_HAVE_PID) 2385FORK_TEST(fork6, DSCR(fork,1,0,1,0,0), fork, T, F, T, F, F) 2386FORK_TEST(fork7, DSCR(fork,0,1,1,0,0), fork, F, T, T, F, F) 2387FORK_TEST(fork8, DSCR(fork,1,1,1,0,0), fork, T, T, T, F, F) 2388#endif 2389 2390FORK_TEST(vfork1, DSCR(vfork,0,0,0,0,0), vfork, F, F, F, F, F) 2391#if defined(TWAIT_HAVE_PID) 2392FORK_TEST(vfork2, DSCR(vfork,1,0,0,0,0), vfork, T, F, F, F, F) 2393FORK_TEST(vfork3, DSCR(vfork,0,1,0,0,0), vfork, F, T, F, F, F) 2394FORK_TEST(vfork4, DSCR(vfork,1,1,0,0,0), vfork, T, T, F, F, F) 2395#endif 2396FORK_TEST(vfork5, DSCR(vfork,0,0,1,0,0), vfork, F, F, T, F, F) 2397#if defined(TWAIT_HAVE_PID) 2398FORK_TEST(vfork6, DSCR(vfork,1,0,1,0,0), vfork, T, F, T, F, F) 2399FORK_TEST(vfork7, DSCR(vfork,0,1,1,0,0), vfork, F, T, T, F, F) 2400FORK_TEST(vfork8, DSCR(vfork,1,1,1,0,0), vfork, T, T, T, F, F) 2401#endif 2402 2403/// ---------------------------------------------------------------------------- 2404 2405enum bytes_transfer_type { 2406 BYTES_TRANSFER_DATA, 2407 BYTES_TRANSFER_DATAIO, 2408 BYTES_TRANSFER_TEXT, 2409 BYTES_TRANSFER_TEXTIO, 2410 BYTES_TRANSFER_AUXV 2411}; 2412 2413static int __used 2414bytes_transfer_dummy(int a, int b, int c, int d) 2415{ 2416 int e, f, g, h; 2417 2418 a *= 4; 2419 b += 3; 2420 c -= 2; 2421 d /= 1; 2422 2423 e = strtol("10", NULL, 10); 2424 f = strtol("20", NULL, 10); 2425 g = strtol("30", NULL, 10); 2426 h = strtol("40", NULL, 10); 2427 2428 return (a + b * c - d) + (e * f - g / h); 2429} 2430 2431static void 2432bytes_transfer(int operation, size_t size, enum bytes_transfer_type type) 2433{ 2434 const int exitval = 5; 2435 const int sigval = SIGSTOP; 2436 pid_t child, wpid; 2437 bool skip = false; 2438 2439 int lookup_me = 0; 2440 uint8_t lookup_me8 = 0; 2441 uint16_t lookup_me16 = 0; 2442 uint32_t lookup_me32 = 0; 2443 uint64_t lookup_me64 = 0; 2444 2445 int magic = 0x13579246; 2446 uint8_t magic8 = 0xab; 2447 uint16_t magic16 = 0x1234; 2448 uint32_t magic32 = 0x98765432; 2449 uint64_t magic64 = 0xabcdef0123456789; 2450 2451 struct ptrace_io_desc io; 2452#if defined(TWAIT_HAVE_STATUS) 2453 int status; 2454#endif 2455 /* 513 is just enough, for the purposes of ATF it's good enough */ 2456 AuxInfo ai[513], *aip; 2457 2458 ATF_REQUIRE(size < sizeof(ai)); 2459 2460 /* Prepare variables for .TEXT transfers */ 2461 switch (type) { 2462 case BYTES_TRANSFER_TEXT: 2463 memcpy(&magic, bytes_transfer_dummy, sizeof(magic)); 2464 break; 2465 case BYTES_TRANSFER_TEXTIO: 2466 switch (size) { 2467 case 8: 2468 memcpy(&magic8, bytes_transfer_dummy, sizeof(magic8)); 2469 break; 2470 case 16: 2471 memcpy(&magic16, bytes_transfer_dummy, sizeof(magic16)); 2472 break; 2473 case 32: 2474 memcpy(&magic32, bytes_transfer_dummy, sizeof(magic32)); 2475 break; 2476 case 64: 2477 memcpy(&magic64, bytes_transfer_dummy, sizeof(magic64)); 2478 break; 2479 } 2480 break; 2481 default: 2482 break; 2483 } 2484 2485 /* Prepare variables for PIOD and AUXV transfers */ 2486 switch (type) { 2487 case BYTES_TRANSFER_TEXTIO: 2488 case BYTES_TRANSFER_DATAIO: 2489 io.piod_op = operation; 2490 switch (size) { 2491 case 8: 2492 io.piod_offs = (type == BYTES_TRANSFER_TEXTIO) ? 2493 (void *)bytes_transfer_dummy : 2494 &lookup_me8; 2495 io.piod_addr = &lookup_me8; 2496 io.piod_len = sizeof(lookup_me8); 2497 break; 2498 case 16: 2499 io.piod_offs = (type == BYTES_TRANSFER_TEXTIO) ? 2500 (void *)bytes_transfer_dummy : 2501 &lookup_me16; 2502 io.piod_addr = &lookup_me16; 2503 io.piod_len = sizeof(lookup_me16); 2504 break; 2505 case 32: 2506 io.piod_offs = (type == BYTES_TRANSFER_TEXTIO) ? 2507 (void *)bytes_transfer_dummy : 2508 &lookup_me32; 2509 io.piod_addr = &lookup_me32; 2510 io.piod_len = sizeof(lookup_me32); 2511 break; 2512 case 64: 2513 io.piod_offs = (type == BYTES_TRANSFER_TEXTIO) ? 2514 (void *)bytes_transfer_dummy : 2515 &lookup_me64; 2516 io.piod_addr = &lookup_me64; 2517 io.piod_len = sizeof(lookup_me64); 2518 break; 2519 default: 2520 break; 2521 } 2522 break; 2523 case BYTES_TRANSFER_AUXV: 2524 io.piod_op = operation; 2525 io.piod_offs = 0; 2526 io.piod_addr = ai; 2527 io.piod_len = size; 2528 break; 2529 default: 2530 break; 2531 } 2532 2533 DPRINTF("Before forking process PID=%d\n", getpid()); 2534 SYSCALL_REQUIRE((child = fork()) != -1); 2535 if (child == 0) { 2536 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 2537 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 2538 2539 switch (type) { 2540 case BYTES_TRANSFER_DATA: 2541 switch (operation) { 2542 case PT_READ_D: 2543 case PT_READ_I: 2544 lookup_me = magic; 2545 break; 2546 default: 2547 break; 2548 } 2549 break; 2550 case BYTES_TRANSFER_DATAIO: 2551 switch (operation) { 2552 case PIOD_READ_D: 2553 case PIOD_READ_I: 2554 switch (size) { 2555 case 8: 2556 lookup_me8 = magic8; 2557 break; 2558 case 16: 2559 lookup_me16 = magic16; 2560 break; 2561 case 32: 2562 lookup_me32 = magic32; 2563 break; 2564 case 64: 2565 lookup_me64 = magic64; 2566 break; 2567 default: 2568 break; 2569 } 2570 break; 2571 default: 2572 break; 2573 } 2574 default: 2575 break; 2576 } 2577 2578 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 2579 FORKEE_ASSERT(raise(sigval) == 0); 2580 2581 /* Handle PIOD and PT separately as operation values overlap */ 2582 switch (type) { 2583 case BYTES_TRANSFER_DATA: 2584 switch (operation) { 2585 case PT_WRITE_D: 2586 case PT_WRITE_I: 2587 FORKEE_ASSERT_EQ(lookup_me, magic); 2588 break; 2589 default: 2590 break; 2591 } 2592 break; 2593 case BYTES_TRANSFER_DATAIO: 2594 switch (operation) { 2595 case PIOD_WRITE_D: 2596 case PIOD_WRITE_I: 2597 switch (size) { 2598 case 8: 2599 FORKEE_ASSERT_EQ(lookup_me8, magic8); 2600 break; 2601 case 16: 2602 FORKEE_ASSERT_EQ(lookup_me16, magic16); 2603 break; 2604 case 32: 2605 FORKEE_ASSERT_EQ(lookup_me32, magic32); 2606 break; 2607 case 64: 2608 FORKEE_ASSERT_EQ(lookup_me64, magic64); 2609 break; 2610 default: 2611 break; 2612 } 2613 break; 2614 default: 2615 break; 2616 } 2617 break; 2618 case BYTES_TRANSFER_TEXT: 2619 FORKEE_ASSERT(memcmp(&magic, bytes_transfer_dummy, 2620 sizeof(magic)) == 0); 2621 break; 2622 case BYTES_TRANSFER_TEXTIO: 2623 switch (size) { 2624 case 8: 2625 FORKEE_ASSERT(memcmp(&magic8, 2626 bytes_transfer_dummy, 2627 sizeof(magic8)) == 0); 2628 break; 2629 case 16: 2630 FORKEE_ASSERT(memcmp(&magic16, 2631 bytes_transfer_dummy, 2632 sizeof(magic16)) == 0); 2633 break; 2634 case 32: 2635 FORKEE_ASSERT(memcmp(&magic32, 2636 bytes_transfer_dummy, 2637 sizeof(magic32)) == 0); 2638 break; 2639 case 64: 2640 FORKEE_ASSERT(memcmp(&magic64, 2641 bytes_transfer_dummy, 2642 sizeof(magic64)) == 0); 2643 break; 2644 } 2645 break; 2646 default: 2647 break; 2648 } 2649 2650 DPRINTF("Before exiting of the child process\n"); 2651 _exit(exitval); 2652 } 2653 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 2654 2655 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 2656 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 2657 2658 validate_status_stopped(status, sigval); 2659 2660 /* Check PaX MPROTECT */ 2661 if (!can_we_write_to_text(child)) { 2662 switch (type) { 2663 case BYTES_TRANSFER_TEXTIO: 2664 switch (operation) { 2665 case PIOD_WRITE_D: 2666 case PIOD_WRITE_I: 2667 skip = true; 2668 break; 2669 default: 2670 break; 2671 } 2672 break; 2673 case BYTES_TRANSFER_TEXT: 2674 switch (operation) { 2675 case PT_WRITE_D: 2676 case PT_WRITE_I: 2677 skip = true; 2678 break; 2679 default: 2680 break; 2681 } 2682 break; 2683 default: 2684 break; 2685 } 2686 } 2687 2688 /* Bailout cleanly killing the child process */ 2689 if (skip) { 2690 SYSCALL_REQUIRE(ptrace(PT_KILL, child, (void *)1, 0) != -1); 2691 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 2692 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), 2693 child); 2694 2695 validate_status_signaled(status, SIGKILL, 0); 2696 2697 atf_tc_skip("PaX MPROTECT setup prevents writes to .text"); 2698 } 2699 2700 DPRINTF("Calling operation to transfer bytes between child=%d and " 2701 "parent=%d\n", child, getpid()); 2702 2703 switch (type) { 2704 case BYTES_TRANSFER_TEXTIO: 2705 case BYTES_TRANSFER_DATAIO: 2706 case BYTES_TRANSFER_AUXV: 2707 switch (operation) { 2708 case PIOD_WRITE_D: 2709 case PIOD_WRITE_I: 2710 switch (size) { 2711 case 8: 2712 lookup_me8 = magic8; 2713 break; 2714 case 16: 2715 lookup_me16 = magic16; 2716 break; 2717 case 32: 2718 lookup_me32 = magic32; 2719 break; 2720 case 64: 2721 lookup_me64 = magic64; 2722 break; 2723 default: 2724 break; 2725 } 2726 break; 2727 default: 2728 break; 2729 } 2730 SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1); 2731 switch (operation) { 2732 case PIOD_READ_D: 2733 case PIOD_READ_I: 2734 switch (size) { 2735 case 8: 2736 ATF_REQUIRE_EQ(lookup_me8, magic8); 2737 break; 2738 case 16: 2739 ATF_REQUIRE_EQ(lookup_me16, magic16); 2740 break; 2741 case 32: 2742 ATF_REQUIRE_EQ(lookup_me32, magic32); 2743 break; 2744 case 64: 2745 ATF_REQUIRE_EQ(lookup_me64, magic64); 2746 break; 2747 default: 2748 break; 2749 } 2750 break; 2751 case PIOD_READ_AUXV: 2752 DPRINTF("Asserting that AUXV length (%zu) is > 0\n", 2753 io.piod_len); 2754 ATF_REQUIRE(io.piod_len > 0); 2755 for (aip = ai; aip->a_type != AT_NULL; aip++) 2756 DPRINTF("a_type=%#llx a_v=%#llx\n", 2757 (long long int)aip->a_type, 2758 (long long int)aip->a_v); 2759 break; 2760 default: 2761 break; 2762 } 2763 break; 2764 case BYTES_TRANSFER_TEXT: 2765 switch (operation) { 2766 case PT_READ_D: 2767 case PT_READ_I: 2768 errno = 0; 2769 lookup_me = ptrace(operation, child, 2770 bytes_transfer_dummy, 0); 2771 ATF_REQUIRE_EQ(lookup_me, magic); 2772 SYSCALL_REQUIRE_ERRNO(errno, 0); 2773 break; 2774 case PT_WRITE_D: 2775 case PT_WRITE_I: 2776 SYSCALL_REQUIRE(ptrace(operation, child, 2777 bytes_transfer_dummy, magic) 2778 != -1); 2779 break; 2780 default: 2781 break; 2782 } 2783 break; 2784 case BYTES_TRANSFER_DATA: 2785 switch (operation) { 2786 case PT_READ_D: 2787 case PT_READ_I: 2788 errno = 0; 2789 lookup_me = ptrace(operation, child, &lookup_me, 0); 2790 ATF_REQUIRE_EQ(lookup_me, magic); 2791 SYSCALL_REQUIRE_ERRNO(errno, 0); 2792 break; 2793 case PT_WRITE_D: 2794 case PT_WRITE_I: 2795 lookup_me = magic; 2796 SYSCALL_REQUIRE(ptrace(operation, child, &lookup_me, 2797 magic) != -1); 2798 break; 2799 default: 2800 break; 2801 } 2802 break; 2803 default: 2804 break; 2805 } 2806 2807 DPRINTF("Before resuming the child process where it left off and " 2808 "without signal to be sent\n"); 2809 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 2810 2811 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 2812 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 2813 2814 validate_status_exited(status, exitval); 2815 2816 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 2817 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 2818} 2819 2820#define BYTES_TRANSFER(test, operation, size, type) \ 2821ATF_TC(test); \ 2822ATF_TC_HEAD(test, tc) \ 2823{ \ 2824 atf_tc_set_md_var(tc, "descr", \ 2825 "Verify bytes transfer operation" #operation " and size " #size \ 2826 " of type " #type); \ 2827} \ 2828 \ 2829ATF_TC_BODY(test, tc) \ 2830{ \ 2831 \ 2832 bytes_transfer(operation, size, BYTES_TRANSFER_##type); \ 2833} 2834 2835// DATA 2836 2837BYTES_TRANSFER(bytes_transfer_piod_read_d_8, PIOD_READ_D, 8, DATAIO) 2838BYTES_TRANSFER(bytes_transfer_piod_read_d_16, PIOD_READ_D, 16, DATAIO) 2839BYTES_TRANSFER(bytes_transfer_piod_read_d_32, PIOD_READ_D, 32, DATAIO) 2840BYTES_TRANSFER(bytes_transfer_piod_read_d_64, PIOD_READ_D, 64, DATAIO) 2841 2842BYTES_TRANSFER(bytes_transfer_piod_read_i_8, PIOD_READ_I, 8, DATAIO) 2843BYTES_TRANSFER(bytes_transfer_piod_read_i_16, PIOD_READ_I, 16, DATAIO) 2844BYTES_TRANSFER(bytes_transfer_piod_read_i_32, PIOD_READ_I, 32, DATAIO) 2845BYTES_TRANSFER(bytes_transfer_piod_read_i_64, PIOD_READ_I, 64, DATAIO) 2846 2847BYTES_TRANSFER(bytes_transfer_piod_write_d_8, PIOD_WRITE_D, 8, DATAIO) 2848BYTES_TRANSFER(bytes_transfer_piod_write_d_16, PIOD_WRITE_D, 16, DATAIO) 2849BYTES_TRANSFER(bytes_transfer_piod_write_d_32, PIOD_WRITE_D, 32, DATAIO) 2850BYTES_TRANSFER(bytes_transfer_piod_write_d_64, PIOD_WRITE_D, 64, DATAIO) 2851 2852BYTES_TRANSFER(bytes_transfer_piod_write_i_8, PIOD_WRITE_I, 8, DATAIO) 2853BYTES_TRANSFER(bytes_transfer_piod_write_i_16, PIOD_WRITE_I, 16, DATAIO) 2854BYTES_TRANSFER(bytes_transfer_piod_write_i_32, PIOD_WRITE_I, 32, DATAIO) 2855BYTES_TRANSFER(bytes_transfer_piod_write_i_64, PIOD_WRITE_I, 64, DATAIO) 2856 2857BYTES_TRANSFER(bytes_transfer_read_d, PT_READ_D, 32, DATA) 2858BYTES_TRANSFER(bytes_transfer_read_i, PT_READ_I, 32, DATA) 2859BYTES_TRANSFER(bytes_transfer_write_d, PT_WRITE_D, 32, DATA) 2860BYTES_TRANSFER(bytes_transfer_write_i, PT_WRITE_I, 32, DATA) 2861 2862// TEXT 2863 2864BYTES_TRANSFER(bytes_transfer_piod_read_d_8_text, PIOD_READ_D, 8, TEXTIO) 2865BYTES_TRANSFER(bytes_transfer_piod_read_d_16_text, PIOD_READ_D, 16, TEXTIO) 2866BYTES_TRANSFER(bytes_transfer_piod_read_d_32_text, PIOD_READ_D, 32, TEXTIO) 2867BYTES_TRANSFER(bytes_transfer_piod_read_d_64_text, PIOD_READ_D, 64, TEXTIO) 2868 2869BYTES_TRANSFER(bytes_transfer_piod_read_i_8_text, PIOD_READ_I, 8, TEXTIO) 2870BYTES_TRANSFER(bytes_transfer_piod_read_i_16_text, PIOD_READ_I, 16, TEXTIO) 2871BYTES_TRANSFER(bytes_transfer_piod_read_i_32_text, PIOD_READ_I, 32, TEXTIO) 2872BYTES_TRANSFER(bytes_transfer_piod_read_i_64_text, PIOD_READ_I, 64, TEXTIO) 2873 2874BYTES_TRANSFER(bytes_transfer_piod_write_d_8_text, PIOD_WRITE_D, 8, TEXTIO) 2875BYTES_TRANSFER(bytes_transfer_piod_write_d_16_text, PIOD_WRITE_D, 16, TEXTIO) 2876BYTES_TRANSFER(bytes_transfer_piod_write_d_32_text, PIOD_WRITE_D, 32, TEXTIO) 2877BYTES_TRANSFER(bytes_transfer_piod_write_d_64_text, PIOD_WRITE_D, 64, TEXTIO) 2878 2879BYTES_TRANSFER(bytes_transfer_piod_write_i_8_text, PIOD_WRITE_I, 8, TEXTIO) 2880BYTES_TRANSFER(bytes_transfer_piod_write_i_16_text, PIOD_WRITE_I, 16, TEXTIO) 2881BYTES_TRANSFER(bytes_transfer_piod_write_i_32_text, PIOD_WRITE_I, 32, TEXTIO) 2882BYTES_TRANSFER(bytes_transfer_piod_write_i_64_text, PIOD_WRITE_I, 64, TEXTIO) 2883 2884BYTES_TRANSFER(bytes_transfer_read_d_text, PT_READ_D, 32, TEXT) 2885BYTES_TRANSFER(bytes_transfer_read_i_text, PT_READ_I, 32, TEXT) 2886BYTES_TRANSFER(bytes_transfer_write_d_text, PT_WRITE_D, 32, TEXT) 2887BYTES_TRANSFER(bytes_transfer_write_i_text, PT_WRITE_I, 32, TEXT) 2888 2889// AUXV 2890 2891BYTES_TRANSFER(bytes_transfer_piod_read_auxv, PIOD_READ_AUXV, 4096, AUXV) 2892 2893/// ---------------------------------------------------------------------------- 2894 2895#if defined(HAVE_GPREGS) || defined(HAVE_FPREGS) 2896static void 2897access_regs(const char *regset, const char *aux) 2898{ 2899 const int exitval = 5; 2900 const int sigval = SIGSTOP; 2901 pid_t child, wpid; 2902#if defined(TWAIT_HAVE_STATUS) 2903 int status; 2904#endif 2905#if defined(HAVE_GPREGS) 2906 struct reg gpr; 2907 register_t rgstr; 2908#endif 2909#if defined(HAVE_FPREGS) 2910 struct fpreg fpr; 2911#endif 2912 2913#if !defined(HAVE_GPREGS) 2914 if (strcmp(regset, "regs") == 0) 2915 atf_tc_fail("Impossible test scenario!"); 2916#endif 2917 2918#if !defined(HAVE_FPREGS) 2919 if (strcmp(regset, "fpregs") == 0) 2920 atf_tc_fail("Impossible test scenario!"); 2921#endif 2922 2923 DPRINTF("Before forking process PID=%d\n", getpid()); 2924 SYSCALL_REQUIRE((child = fork()) != -1); 2925 if (child == 0) { 2926 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 2927 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 2928 2929 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 2930 FORKEE_ASSERT(raise(sigval) == 0); 2931 2932 DPRINTF("Before exiting of the child process\n"); 2933 _exit(exitval); 2934 } 2935 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 2936 2937 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 2938 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 2939 2940 validate_status_stopped(status, sigval); 2941 2942#if defined(HAVE_GPREGS) 2943 if (strcmp(regset, "regs") == 0) { 2944 DPRINTF("Call GETREGS for the child process\n"); 2945 SYSCALL_REQUIRE(ptrace(PT_GETREGS, child, &gpr, 0) != -1); 2946 2947 if (strcmp(aux, "none") == 0) { 2948 DPRINTF("Retrieved registers\n"); 2949 } else if (strcmp(aux, "pc") == 0) { 2950 rgstr = PTRACE_REG_PC(&gpr); 2951 DPRINTF("Retrieved %" PRIxREGISTER "\n", rgstr); 2952 } else if (strcmp(aux, "set_pc") == 0) { 2953 rgstr = PTRACE_REG_PC(&gpr); 2954 PTRACE_REG_SET_PC(&gpr, rgstr); 2955 } else if (strcmp(aux, "sp") == 0) { 2956 rgstr = PTRACE_REG_SP(&gpr); 2957 DPRINTF("Retrieved %" PRIxREGISTER "\n", rgstr); 2958 } else if (strcmp(aux, "intrv") == 0) { 2959 rgstr = PTRACE_REG_INTRV(&gpr); 2960 DPRINTF("Retrieved %" PRIxREGISTER "\n", rgstr); 2961 } else if (strcmp(aux, "setregs") == 0) { 2962 DPRINTF("Call SETREGS for the child process\n"); 2963 SYSCALL_REQUIRE( 2964 ptrace(PT_GETREGS, child, &gpr, 0) != -1); 2965 } 2966 } 2967#endif 2968 2969#if defined(HAVE_FPREGS) 2970 if (strcmp(regset, "fpregs") == 0) { 2971 DPRINTF("Call GETFPREGS for the child process\n"); 2972 SYSCALL_REQUIRE(ptrace(PT_GETFPREGS, child, &fpr, 0) != -1); 2973 2974 if (strcmp(aux, "getfpregs") == 0) { 2975 DPRINTF("Retrieved FP registers\n"); 2976 } else if (strcmp(aux, "setfpregs") == 0) { 2977 DPRINTF("Call SETFPREGS for the child\n"); 2978 SYSCALL_REQUIRE( 2979 ptrace(PT_SETFPREGS, child, &fpr, 0) != -1); 2980 } 2981 } 2982#endif 2983 2984 DPRINTF("Before resuming the child process where it left off and " 2985 "without signal to be sent\n"); 2986 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 2987 2988 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 2989 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 2990 2991 validate_status_exited(status, exitval); 2992 2993 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 2994 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 2995} 2996 2997#define ACCESS_REGS(test, regset, aux) \ 2998ATF_TC(test); \ 2999ATF_TC_HEAD(test, tc) \ 3000{ \ 3001 atf_tc_set_md_var(tc, "descr", \ 3002 "Verify " regset " with auxiliary operation: " aux); \ 3003} \ 3004 \ 3005ATF_TC_BODY(test, tc) \ 3006{ \ 3007 \ 3008 access_regs(regset, aux); \ 3009} 3010#endif 3011 3012#if defined(HAVE_GPREGS) 3013ACCESS_REGS(access_regs1, "regs", "none") 3014ACCESS_REGS(access_regs2, "regs", "pc") 3015ACCESS_REGS(access_regs3, "regs", "set_pc") 3016ACCESS_REGS(access_regs4, "regs", "sp") 3017ACCESS_REGS(access_regs5, "regs", "intrv") 3018ACCESS_REGS(access_regs6, "regs", "setregs") 3019#endif 3020#if defined(HAVE_FPREGS) 3021ACCESS_REGS(access_fpregs1, "fpregs", "getfpregs") 3022ACCESS_REGS(access_fpregs2, "fpregs", "setfpregs") 3023#endif 3024 3025/// ---------------------------------------------------------------------------- 3026 3027#if defined(PT_STEP) 3028static void 3029ptrace_step(int N, int setstep) 3030{ 3031 const int exitval = 5; 3032 const int sigval = SIGSTOP; 3033 pid_t child, wpid; 3034#if defined(TWAIT_HAVE_STATUS) 3035 int status; 3036#endif 3037 int happy; 3038 struct ptrace_siginfo info; 3039 3040#if defined(__arm__) 3041 /* PT_STEP not supported on arm 32-bit */ 3042 atf_tc_expect_fail("PR kern/52119"); 3043#endif 3044 3045 DPRINTF("Before forking process PID=%d\n", getpid()); 3046 SYSCALL_REQUIRE((child = fork()) != -1); 3047 if (child == 0) { 3048 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 3049 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 3050 3051 happy = check_happy(999); 3052 3053 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 3054 FORKEE_ASSERT(raise(sigval) == 0); 3055 3056 FORKEE_ASSERT_EQ(happy, check_happy(999)); 3057 3058 DPRINTF("Before exiting of the child process\n"); 3059 _exit(exitval); 3060 } 3061 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 3062 3063 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 3064 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 3065 3066 validate_status_stopped(status, sigval); 3067 3068 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 3069 SYSCALL_REQUIRE( 3070 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 3071 3072 DPRINTF("Before checking siginfo_t\n"); 3073 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 3074 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 3075 3076 while (N --> 0) { 3077 if (setstep) { 3078 DPRINTF("Before resuming the child process where it " 3079 "left off and without signal to be sent (use " 3080 "PT_SETSTEP and PT_CONTINUE)\n"); 3081 SYSCALL_REQUIRE(ptrace(PT_SETSTEP, child, 0, 0) != -1); 3082 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) 3083 != -1); 3084 } else { 3085 DPRINTF("Before resuming the child process where it " 3086 "left off and without signal to be sent (use " 3087 "PT_STEP)\n"); 3088 SYSCALL_REQUIRE(ptrace(PT_STEP, child, (void *)1, 0) 3089 != -1); 3090 } 3091 3092 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 3093 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), 3094 child); 3095 3096 validate_status_stopped(status, SIGTRAP); 3097 3098 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 3099 SYSCALL_REQUIRE( 3100 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 3101 3102 DPRINTF("Before checking siginfo_t\n"); 3103 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); 3104 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_TRACE); 3105 3106 if (setstep) { 3107 SYSCALL_REQUIRE(ptrace(PT_CLEARSTEP, child, 0, 0) != -1); 3108 } 3109 } 3110 3111 DPRINTF("Before resuming the child process where it left off and " 3112 "without signal to be sent\n"); 3113 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 3114 3115 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 3116 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 3117 3118 validate_status_exited(status, exitval); 3119 3120 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 3121 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 3122} 3123 3124#define PTRACE_STEP(test, N, setstep) \ 3125ATF_TC(test); \ 3126ATF_TC_HEAD(test, tc) \ 3127{ \ 3128 atf_tc_set_md_var(tc, "descr", \ 3129 "Verify " #N " (PT_SETSTEP set to: " #setstep ")"); \ 3130} \ 3131 \ 3132ATF_TC_BODY(test, tc) \ 3133{ \ 3134 \ 3135 ptrace_step(N, setstep); \ 3136} 3137 3138PTRACE_STEP(step1, 1, 0) 3139PTRACE_STEP(step2, 2, 0) 3140PTRACE_STEP(step3, 3, 0) 3141PTRACE_STEP(step4, 4, 0) 3142PTRACE_STEP(setstep1, 1, 1) 3143PTRACE_STEP(setstep2, 2, 1) 3144PTRACE_STEP(setstep3, 3, 1) 3145PTRACE_STEP(setstep4, 4, 1) 3146#endif 3147 3148/// ---------------------------------------------------------------------------- 3149 3150static void 3151ptrace_kill(const char *type) 3152{ 3153 const int sigval = SIGSTOP; 3154 pid_t child, wpid; 3155#if defined(TWAIT_HAVE_STATUS) 3156 int status; 3157#endif 3158 3159 DPRINTF("Before forking process PID=%d\n", getpid()); 3160 SYSCALL_REQUIRE((child = fork()) != -1); 3161 if (child == 0) { 3162 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 3163 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 3164 3165 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 3166 FORKEE_ASSERT(raise(sigval) == 0); 3167 3168 /* NOTREACHED */ 3169 FORKEE_ASSERTX(0 && 3170 "Child should be terminated by a signal from its parent"); 3171 } 3172 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 3173 3174 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 3175 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 3176 3177 validate_status_stopped(status, sigval); 3178 3179 DPRINTF("Before killing the child process with %s\n", type); 3180 if (strcmp(type, "ptrace(PT_KILL)") == 0) { 3181 SYSCALL_REQUIRE(ptrace(PT_KILL, child, (void*)1, 0) != -1); 3182 } else if (strcmp(type, "kill(SIGKILL)") == 0) { 3183 kill(child, SIGKILL); 3184 } else if (strcmp(type, "killpg(SIGKILL)") == 0) { 3185 setpgid(child, 0); 3186 killpg(getpgid(child), SIGKILL); 3187 } 3188 3189 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 3190 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 3191 3192 validate_status_signaled(status, SIGKILL, 0); 3193 3194 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 3195 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 3196} 3197 3198#define PTRACE_KILL(test, type) \ 3199ATF_TC(test); \ 3200ATF_TC_HEAD(test, tc) \ 3201{ \ 3202 atf_tc_set_md_var(tc, "descr", \ 3203 "Verify killing the child with " type); \ 3204} \ 3205 \ 3206ATF_TC_BODY(test, tc) \ 3207{ \ 3208 \ 3209 ptrace_kill(type); \ 3210} 3211 3212// PT_CONTINUE with SIGKILL is covered by traceme_sendsignal_simple1 3213PTRACE_KILL(kill1, "ptrace(PT_KILL)") 3214PTRACE_KILL(kill2, "kill(SIGKILL)") 3215PTRACE_KILL(kill3, "killpg(SIGKILL)") 3216 3217/// ---------------------------------------------------------------------------- 3218 3219static void 3220traceme_lwpinfo(const int threads) 3221{ 3222 const int sigval = SIGSTOP; 3223 const int sigval2 = SIGINT; 3224 pid_t child, wpid; 3225#if defined(TWAIT_HAVE_STATUS) 3226 int status; 3227#endif 3228 struct ptrace_lwpinfo lwp = {0, 0}; 3229 struct ptrace_siginfo info; 3230 3231 /* Maximum number of supported threads in this test */ 3232 pthread_t t[3]; 3233 int n, rv; 3234 3235 ATF_REQUIRE((int)__arraycount(t) >= threads); 3236 3237 DPRINTF("Before forking process PID=%d\n", getpid()); 3238 SYSCALL_REQUIRE((child = fork()) != -1); 3239 if (child == 0) { 3240 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 3241 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 3242 3243 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 3244 FORKEE_ASSERT(raise(sigval) == 0); 3245 3246 for (n = 0; n < threads; n++) { 3247 rv = pthread_create(&t[n], NULL, infinite_thread, NULL); 3248 FORKEE_ASSERT(rv == 0); 3249 } 3250 3251 DPRINTF("Before raising %s from child\n", strsignal(sigval2)); 3252 FORKEE_ASSERT(raise(sigval2) == 0); 3253 3254 /* NOTREACHED */ 3255 FORKEE_ASSERTX(0 && "Not reached"); 3256 } 3257 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 3258 3259 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 3260 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 3261 3262 validate_status_stopped(status, sigval); 3263 3264 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child"); 3265 SYSCALL_REQUIRE( 3266 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 3267 3268 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 3269 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 3270 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 3271 info.psi_siginfo.si_errno); 3272 3273 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 3274 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 3275 3276 DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n"); 3277 SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &lwp, sizeof(lwp)) != -1); 3278 3279 DPRINTF("Assert that there exists a single thread only\n"); 3280 ATF_REQUIRE(lwp.pl_lwpid > 0); 3281 3282 DPRINTF("Assert that lwp thread %d received event PL_EVENT_SIGNAL\n", 3283 lwp.pl_lwpid); 3284 FORKEE_ASSERT_EQ(lwp.pl_event, PL_EVENT_SIGNAL); 3285 3286 DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n"); 3287 SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &lwp, sizeof(lwp)) != -1); 3288 3289 DPRINTF("Assert that there exists a single thread only\n"); 3290 ATF_REQUIRE_EQ(lwp.pl_lwpid, 0); 3291 3292 DPRINTF("Before resuming the child process where it left off and " 3293 "without signal to be sent\n"); 3294 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 3295 3296 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 3297 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 3298 3299 validate_status_stopped(status, sigval2); 3300 3301 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child"); 3302 SYSCALL_REQUIRE( 3303 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 3304 3305 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 3306 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 3307 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 3308 info.psi_siginfo.si_errno); 3309 3310 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval2); 3311 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 3312 3313 memset(&lwp, 0, sizeof(lwp)); 3314 3315 for (n = 0; n <= threads; n++) { 3316 DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n"); 3317 SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &lwp, sizeof(lwp)) != -1); 3318 DPRINTF("LWP=%d\n", lwp.pl_lwpid); 3319 3320 DPRINTF("Assert that the thread exists\n"); 3321 ATF_REQUIRE(lwp.pl_lwpid > 0); 3322 3323 DPRINTF("Assert that lwp thread %d received expected event\n", 3324 lwp.pl_lwpid); 3325 FORKEE_ASSERT_EQ(lwp.pl_event, info.psi_lwpid == lwp.pl_lwpid ? 3326 PL_EVENT_SIGNAL : PL_EVENT_NONE); 3327 } 3328 DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n"); 3329 SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &lwp, sizeof(lwp)) != -1); 3330 DPRINTF("LWP=%d\n", lwp.pl_lwpid); 3331 3332 DPRINTF("Assert that there are no more threads\n"); 3333 ATF_REQUIRE_EQ(lwp.pl_lwpid, 0); 3334 3335 DPRINTF("Before resuming the child process where it left off and " 3336 "without signal to be sent\n"); 3337 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, SIGKILL) != -1); 3338 3339 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 3340 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 3341 3342 validate_status_signaled(status, SIGKILL, 0); 3343 3344 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 3345 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 3346} 3347 3348#define TRACEME_LWPINFO(test, threads) \ 3349ATF_TC(test); \ 3350ATF_TC_HEAD(test, tc) \ 3351{ \ 3352 atf_tc_set_md_var(tc, "descr", \ 3353 "Verify LWPINFO with the child with " #threads \ 3354 " spawned extra threads"); \ 3355} \ 3356 \ 3357ATF_TC_BODY(test, tc) \ 3358{ \ 3359 \ 3360 traceme_lwpinfo(threads); \ 3361} 3362 3363TRACEME_LWPINFO(traceme_lwpinfo0, 0) 3364TRACEME_LWPINFO(traceme_lwpinfo1, 1) 3365TRACEME_LWPINFO(traceme_lwpinfo2, 2) 3366TRACEME_LWPINFO(traceme_lwpinfo3, 3) 3367 3368/// ---------------------------------------------------------------------------- 3369 3370#if defined(TWAIT_HAVE_PID) 3371static void 3372attach_lwpinfo(const int threads) 3373{ 3374 const int sigval = SIGINT; 3375 struct msg_fds parent_tracee, parent_tracer; 3376 const int exitval_tracer = 10; 3377 pid_t tracee, tracer, wpid; 3378 uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */ 3379#if defined(TWAIT_HAVE_STATUS) 3380 int status; 3381#endif 3382 struct ptrace_lwpinfo lwp = {0, 0}; 3383 struct ptrace_siginfo info; 3384 3385 /* Maximum number of supported threads in this test */ 3386 pthread_t t[3]; 3387 int n, rv; 3388 3389 DPRINTF("Spawn tracee\n"); 3390 SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0); 3391 SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0); 3392 tracee = atf_utils_fork(); 3393 if (tracee == 0) { 3394 /* Wait for message from the parent */ 3395 CHILD_TO_PARENT("tracee ready", parent_tracee, msg); 3396 3397 CHILD_FROM_PARENT("spawn threads", parent_tracee, msg); 3398 3399 for (n = 0; n < threads; n++) { 3400 rv = pthread_create(&t[n], NULL, infinite_thread, NULL); 3401 FORKEE_ASSERT(rv == 0); 3402 } 3403 3404 CHILD_TO_PARENT("tracee exit", parent_tracee, msg); 3405 3406 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 3407 FORKEE_ASSERT(raise(sigval) == 0); 3408 3409 /* NOTREACHED */ 3410 FORKEE_ASSERTX(0 && "Not reached"); 3411 } 3412 PARENT_FROM_CHILD("tracee ready", parent_tracee, msg); 3413 3414 DPRINTF("Spawn debugger\n"); 3415 tracer = atf_utils_fork(); 3416 if (tracer == 0) { 3417 /* No IPC to communicate with the child */ 3418 DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid()); 3419 FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1); 3420 3421 /* Wait for tracee and assert that it was stopped w/ SIGSTOP */ 3422 FORKEE_REQUIRE_SUCCESS( 3423 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 3424 3425 forkee_status_stopped(status, SIGSTOP); 3426 3427 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for " 3428 "tracee"); 3429 FORKEE_ASSERT( 3430 ptrace(PT_GET_SIGINFO, tracee, &info, sizeof(info)) != -1); 3431 3432 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 3433 DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 3434 "si_errno=%#x\n", 3435 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 3436 info.psi_siginfo.si_errno); 3437 3438 FORKEE_ASSERT_EQ(info.psi_siginfo.si_signo, SIGSTOP); 3439 FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, SI_USER); 3440 3441 DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n"); 3442 FORKEE_ASSERT(ptrace(PT_LWPINFO, tracee, &lwp, sizeof(lwp)) 3443 != -1); 3444 3445 DPRINTF("Assert that there exists a thread\n"); 3446 FORKEE_ASSERTX(lwp.pl_lwpid > 0); 3447 3448 DPRINTF("Assert that lwp thread %d received event " 3449 "PL_EVENT_SIGNAL\n", lwp.pl_lwpid); 3450 FORKEE_ASSERT_EQ(lwp.pl_event, PL_EVENT_SIGNAL); 3451 3452 DPRINTF("Before calling ptrace(2) with PT_LWPINFO for " 3453 "tracee\n"); 3454 FORKEE_ASSERT(ptrace(PT_LWPINFO, tracee, &lwp, sizeof(lwp)) 3455 != -1); 3456 3457 DPRINTF("Assert that there are no more lwp threads in " 3458 "tracee\n"); 3459 FORKEE_ASSERT_EQ(lwp.pl_lwpid, 0); 3460 3461 /* Resume tracee with PT_CONTINUE */ 3462 FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1); 3463 3464 /* Inform parent that tracer has attached to tracee */ 3465 CHILD_TO_PARENT("tracer ready", parent_tracer, msg); 3466 3467 /* Wait for parent */ 3468 CHILD_FROM_PARENT("tracer wait", parent_tracer, msg); 3469 3470 /* Wait for tracee and assert that it raised a signal */ 3471 FORKEE_REQUIRE_SUCCESS( 3472 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 3473 3474 forkee_status_stopped(status, SIGINT); 3475 3476 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for " 3477 "child"); 3478 FORKEE_ASSERT( 3479 ptrace(PT_GET_SIGINFO, tracee, &info, sizeof(info)) != -1); 3480 3481 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 3482 DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 3483 "si_errno=%#x\n", 3484 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 3485 info.psi_siginfo.si_errno); 3486 3487 FORKEE_ASSERT_EQ(info.psi_siginfo.si_signo, sigval); 3488 FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, SI_LWP); 3489 3490 memset(&lwp, 0, sizeof(lwp)); 3491 3492 for (n = 0; n <= threads; n++) { 3493 DPRINTF("Before calling ptrace(2) with PT_LWPINFO for " 3494 "child\n"); 3495 FORKEE_ASSERT(ptrace(PT_LWPINFO, tracee, &lwp, 3496 sizeof(lwp)) != -1); 3497 DPRINTF("LWP=%d\n", lwp.pl_lwpid); 3498 3499 DPRINTF("Assert that the thread exists\n"); 3500 FORKEE_ASSERT(lwp.pl_lwpid > 0); 3501 3502 DPRINTF("Assert that lwp thread %d received expected " 3503 "event\n", lwp.pl_lwpid); 3504 FORKEE_ASSERT_EQ(lwp.pl_event, 3505 info.psi_lwpid == lwp.pl_lwpid ? 3506 PL_EVENT_SIGNAL : PL_EVENT_NONE); 3507 } 3508 DPRINTF("Before calling ptrace(2) with PT_LWPINFO for " 3509 "tracee\n"); 3510 FORKEE_ASSERT(ptrace(PT_LWPINFO, tracee, &lwp, sizeof(lwp)) 3511 != -1); 3512 DPRINTF("LWP=%d\n", lwp.pl_lwpid); 3513 3514 DPRINTF("Assert that there are no more threads\n"); 3515 FORKEE_ASSERT_EQ(lwp.pl_lwpid, 0); 3516 3517 DPRINTF("Before resuming the child process where it left off " 3518 "and without signal to be sent\n"); 3519 FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, SIGKILL) 3520 != -1); 3521 3522 /* Wait for tracee and assert that it exited */ 3523 FORKEE_REQUIRE_SUCCESS( 3524 wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); 3525 3526 forkee_status_signaled(status, SIGKILL, 0); 3527 3528 DPRINTF("Before exiting of the tracer process\n"); 3529 _exit(exitval_tracer); 3530 } 3531 3532 DPRINTF("Wait for the tracer to attach to the tracee\n"); 3533 PARENT_FROM_CHILD("tracer ready", parent_tracer, msg); 3534 3535 DPRINTF("Resume the tracee and spawn threads\n"); 3536 PARENT_TO_CHILD("spawn threads", parent_tracee, msg); 3537 3538 DPRINTF("Resume the tracee and let it exit\n"); 3539 PARENT_FROM_CHILD("tracee exit", parent_tracee, msg); 3540 3541 DPRINTF("Resume the tracer and let it detect multiple threads\n"); 3542 PARENT_TO_CHILD("tracer wait", parent_tracer, msg); 3543 3544 DPRINTF("Wait for tracer to finish its job and exit - calling %s()\n", 3545 TWAIT_FNAME); 3546 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0), 3547 tracer); 3548 3549 validate_status_exited(status, exitval_tracer); 3550 3551 DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n", 3552 TWAIT_FNAME); 3553 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 3554 tracee); 3555 3556 validate_status_signaled(status, SIGKILL, 0); 3557 3558 msg_close(&parent_tracer); 3559 msg_close(&parent_tracee); 3560} 3561 3562#define ATTACH_LWPINFO(test, threads) \ 3563ATF_TC(test); \ 3564ATF_TC_HEAD(test, tc) \ 3565{ \ 3566 atf_tc_set_md_var(tc, "descr", \ 3567 "Verify LWPINFO with the child with " #threads \ 3568 " spawned extra threads (tracer is not the original " \ 3569 "parent)"); \ 3570} \ 3571 \ 3572ATF_TC_BODY(test, tc) \ 3573{ \ 3574 \ 3575 attach_lwpinfo(threads); \ 3576} 3577 3578ATTACH_LWPINFO(attach_lwpinfo0, 0) 3579ATTACH_LWPINFO(attach_lwpinfo1, 1) 3580ATTACH_LWPINFO(attach_lwpinfo2, 2) 3581ATTACH_LWPINFO(attach_lwpinfo3, 3) 3582#endif 3583 3584/// ---------------------------------------------------------------------------- 3585 3586static void 3587ptrace_siginfo(bool faked, void (*sah)(int a, siginfo_t *b, void *c), int *signal_caught) 3588{ 3589 const int exitval = 5; 3590 const int sigval = SIGINT; 3591 const int sigfaked = SIGTRAP; 3592 const int sicodefaked = TRAP_BRKPT; 3593 pid_t child, wpid; 3594 struct sigaction sa; 3595#if defined(TWAIT_HAVE_STATUS) 3596 int status; 3597#endif 3598 struct ptrace_siginfo info; 3599 memset(&info, 0, sizeof(info)); 3600 3601 DPRINTF("Before forking process PID=%d\n", getpid()); 3602 SYSCALL_REQUIRE((child = fork()) != -1); 3603 if (child == 0) { 3604 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 3605 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 3606 3607 sa.sa_sigaction = sah; 3608 sa.sa_flags = SA_SIGINFO; 3609 sigemptyset(&sa.sa_mask); 3610 3611 FORKEE_ASSERT(sigaction(faked ? sigfaked : sigval, &sa, NULL) 3612 != -1); 3613 3614 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 3615 FORKEE_ASSERT(raise(sigval) == 0); 3616 3617 FORKEE_ASSERT_EQ(*signal_caught, 1); 3618 3619 DPRINTF("Before exiting of the child process\n"); 3620 _exit(exitval); 3621 } 3622 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 3623 3624 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 3625 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 3626 3627 validate_status_stopped(status, sigval); 3628 3629 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 3630 SYSCALL_REQUIRE( 3631 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 3632 3633 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 3634 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 3635 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 3636 info.psi_siginfo.si_errno); 3637 3638 if (faked) { 3639 DPRINTF("Before setting new faked signal to signo=%d " 3640 "si_code=%d\n", sigfaked, sicodefaked); 3641 info.psi_siginfo.si_signo = sigfaked; 3642 info.psi_siginfo.si_code = sicodefaked; 3643 } 3644 3645 DPRINTF("Before calling ptrace(2) with PT_SET_SIGINFO for child\n"); 3646 SYSCALL_REQUIRE( 3647 ptrace(PT_SET_SIGINFO, child, &info, sizeof(info)) != -1); 3648 3649 if (faked) { 3650 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for " 3651 "child\n"); 3652 SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, 3653 sizeof(info)) != -1); 3654 3655 DPRINTF("Before checking siginfo_t\n"); 3656 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigfaked); 3657 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, sicodefaked); 3658 } 3659 3660 DPRINTF("Before resuming the child process where it left off and " 3661 "without signal to be sent\n"); 3662 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 3663 faked ? sigfaked : sigval) != -1); 3664 3665 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 3666 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 3667 3668 validate_status_exited(status, exitval); 3669 3670 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 3671 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 3672} 3673 3674#define PTRACE_SIGINFO(test, faked) \ 3675ATF_TC(test); \ 3676ATF_TC_HEAD(test, tc) \ 3677{ \ 3678 atf_tc_set_md_var(tc, "descr", \ 3679 "Verify basic PT_GET_SIGINFO and PT_SET_SIGINFO calls" \ 3680 "with%s setting signal to new value", faked ? "" : "out"); \ 3681} \ 3682 \ 3683static int test##_caught = 0; \ 3684 \ 3685static void \ 3686test##_sighandler(int sig, siginfo_t *info, void *ctx) \ 3687{ \ 3688 if (faked) { \ 3689 FORKEE_ASSERT_EQ(sig, SIGTRAP); \ 3690 FORKEE_ASSERT_EQ(info->si_signo, SIGTRAP); \ 3691 FORKEE_ASSERT_EQ(info->si_code, TRAP_BRKPT); \ 3692 } else { \ 3693 FORKEE_ASSERT_EQ(sig, SIGINT); \ 3694 FORKEE_ASSERT_EQ(info->si_signo, SIGINT); \ 3695 FORKEE_ASSERT_EQ(info->si_code, SI_LWP); \ 3696 } \ 3697 \ 3698 ++ test##_caught; \ 3699} \ 3700 \ 3701ATF_TC_BODY(test, tc) \ 3702{ \ 3703 \ 3704 ptrace_siginfo(faked, test##_sighandler, & test##_caught); \ 3705} 3706 3707PTRACE_SIGINFO(siginfo_set_unmodified, false) 3708PTRACE_SIGINFO(siginfo_set_faked, true) 3709 3710/// ---------------------------------------------------------------------------- 3711 3712ATF_TC(traceme_exec); 3713ATF_TC_HEAD(traceme_exec, tc) 3714{ 3715 atf_tc_set_md_var(tc, "descr", 3716 "Detect SIGTRAP TRAP_EXEC from tracee"); 3717} 3718 3719ATF_TC_BODY(traceme_exec, tc) 3720{ 3721 const int sigval = SIGTRAP; 3722 pid_t child, wpid; 3723#if defined(TWAIT_HAVE_STATUS) 3724 int status; 3725#endif 3726 3727 struct ptrace_siginfo info; 3728 memset(&info, 0, sizeof(info)); 3729 3730 DPRINTF("Before forking process PID=%d\n", getpid()); 3731 SYSCALL_REQUIRE((child = fork()) != -1); 3732 if (child == 0) { 3733 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 3734 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 3735 3736 DPRINTF("Before calling execve(2) from child\n"); 3737 execlp("/bin/echo", "/bin/echo", NULL); 3738 3739 FORKEE_ASSERT(0 && "Not reached"); 3740 } 3741 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 3742 3743 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 3744 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 3745 3746 validate_status_stopped(status, sigval); 3747 3748 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 3749 SYSCALL_REQUIRE( 3750 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 3751 3752 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 3753 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 3754 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 3755 info.psi_siginfo.si_errno); 3756 3757 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 3758 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_EXEC); 3759 3760 DPRINTF("Before resuming the child process where it left off and " 3761 "without signal to be sent\n"); 3762 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 3763 3764 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 3765 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 3766 3767 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 3768 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 3769} 3770 3771/// ---------------------------------------------------------------------------- 3772 3773static volatile int done; 3774 3775static void * 3776trace_threads_cb(void *arg __unused) 3777{ 3778 3779 done++; 3780 3781 while (done < 3) 3782 continue; 3783 3784 return NULL; 3785} 3786 3787static void 3788trace_threads(bool trace_create, bool trace_exit) 3789{ 3790 const int sigval = SIGSTOP; 3791 pid_t child, wpid; 3792#if defined(TWAIT_HAVE_STATUS) 3793 int status; 3794#endif 3795 ptrace_state_t state; 3796 const int slen = sizeof(state); 3797 ptrace_event_t event; 3798 const int elen = sizeof(event); 3799 struct ptrace_siginfo info; 3800 3801 pthread_t t[3]; 3802 int rv; 3803 size_t n; 3804 lwpid_t lid; 3805 3806 /* Track created and exited threads */ 3807 bool traced_lwps[__arraycount(t)]; 3808 3809 atf_tc_skip("PR kern/51995"); 3810 3811 DPRINTF("Before forking process PID=%d\n", getpid()); 3812 SYSCALL_REQUIRE((child = fork()) != -1); 3813 if (child == 0) { 3814 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 3815 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 3816 3817 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 3818 FORKEE_ASSERT(raise(sigval) == 0); 3819 3820 for (n = 0; n < __arraycount(t); n++) { 3821 rv = pthread_create(&t[n], NULL, trace_threads_cb, 3822 NULL); 3823 FORKEE_ASSERT(rv == 0); 3824 } 3825 3826 for (n = 0; n < __arraycount(t); n++) { 3827 rv = pthread_join(t[n], NULL); 3828 FORKEE_ASSERT(rv == 0); 3829 } 3830 3831 /* 3832 * There is race between _exit() and pthread_join() detaching 3833 * a thread. For simplicity kill the process after detecting 3834 * LWP events. 3835 */ 3836 while (true) 3837 continue; 3838 3839 FORKEE_ASSERT(0 && "Not reached"); 3840 } 3841 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 3842 3843 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 3844 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 3845 3846 validate_status_stopped(status, sigval); 3847 3848 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 3849 SYSCALL_REQUIRE( 3850 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 3851 3852 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 3853 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 3854 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 3855 info.psi_siginfo.si_errno); 3856 3857 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 3858 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 3859 3860 DPRINTF("Set LWP event mask for the child %d\n", child); 3861 memset(&event, 0, sizeof(event)); 3862 if (trace_create) 3863 event.pe_set_event |= PTRACE_LWP_CREATE; 3864 if (trace_exit) 3865 event.pe_set_event |= PTRACE_LWP_EXIT; 3866 SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); 3867 3868 DPRINTF("Before resuming the child process where it left off and " 3869 "without signal to be sent\n"); 3870 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 3871 3872 memset(traced_lwps, 0, sizeof(traced_lwps)); 3873 3874 for (n = 0; n < (trace_create ? __arraycount(t) : 0); n++) { 3875 DPRINTF("Before calling %s() for the child - expected stopped " 3876 "SIGTRAP\n", TWAIT_FNAME); 3877 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), 3878 child); 3879 3880 validate_status_stopped(status, SIGTRAP); 3881 3882 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for " 3883 "child\n"); 3884 SYSCALL_REQUIRE( 3885 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 3886 3887 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 3888 DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 3889 "si_errno=%#x\n", 3890 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 3891 info.psi_siginfo.si_errno); 3892 3893 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); 3894 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_LWP); 3895 3896 SYSCALL_REQUIRE( 3897 ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 3898 3899 ATF_REQUIRE_EQ_MSG(state.pe_report_event, PTRACE_LWP_CREATE, 3900 "%d != %d", state.pe_report_event, PTRACE_LWP_CREATE); 3901 3902 lid = state.pe_lwp; 3903 DPRINTF("Reported PTRACE_LWP_CREATE event with lid %d\n", lid); 3904 3905 traced_lwps[lid - 1] = true; 3906 3907 DPRINTF("Before resuming the child process where it left off " 3908 "and without signal to be sent\n"); 3909 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 3910 } 3911 3912 for (n = 0; n < (trace_exit ? __arraycount(t) : 0); n++) { 3913 DPRINTF("Before calling %s() for the child - expected stopped " 3914 "SIGTRAP\n", TWAIT_FNAME); 3915 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), 3916 child); 3917 3918 validate_status_stopped(status, SIGTRAP); 3919 3920 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for " 3921 "child\n"); 3922 SYSCALL_REQUIRE( 3923 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 3924 3925 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 3926 DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 3927 "si_errno=%#x\n", 3928 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 3929 info.psi_siginfo.si_errno); 3930 3931 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); 3932 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_LWP); 3933 3934 SYSCALL_REQUIRE( 3935 ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 3936 3937 ATF_REQUIRE_EQ_MSG(state.pe_report_event, PTRACE_LWP_EXIT, 3938 "%d != %d", state.pe_report_event, PTRACE_LWP_EXIT); 3939 3940 lid = state.pe_lwp; 3941 DPRINTF("Reported PTRACE_LWP_EXIT event with lid %d\n", lid); 3942 3943 if (trace_create) { 3944 ATF_REQUIRE(traced_lwps[lid - 1] == true); 3945 traced_lwps[lid - 1] = false; 3946 } 3947 3948 DPRINTF("Before resuming the child process where it left off " 3949 "and without signal to be sent\n"); 3950 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 3951 } 3952 3953 kill(child, SIGKILL); 3954 3955 DPRINTF("Before calling %s() for the child - expected exited\n", 3956 TWAIT_FNAME); 3957 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 3958 3959 validate_status_signaled(status, SIGKILL, 0); 3960 3961 DPRINTF("Before calling %s() for the child - expected no process\n", 3962 TWAIT_FNAME); 3963 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 3964} 3965 3966#define TRACE_THREADS(test, trace_create, trace_exit) \ 3967ATF_TC(test); \ 3968ATF_TC_HEAD(test, tc) \ 3969{ \ 3970 atf_tc_set_md_var(tc, "descr", \ 3971 "Verify spawning threads with%s tracing LWP create and" \ 3972 "with%s tracing LWP exit", trace_create ? "" : "out", \ 3973 trace_exit ? "" : "out"); \ 3974} \ 3975 \ 3976ATF_TC_BODY(test, tc) \ 3977{ \ 3978 \ 3979 trace_threads(trace_create, trace_exit); \ 3980} 3981 3982TRACE_THREADS(trace_thread1, false, false) 3983TRACE_THREADS(trace_thread2, false, true) 3984TRACE_THREADS(trace_thread3, true, false) 3985TRACE_THREADS(trace_thread4, true, true) 3986 3987/// ---------------------------------------------------------------------------- 3988 3989ATF_TC(signal_mask_unrelated); 3990ATF_TC_HEAD(signal_mask_unrelated, tc) 3991{ 3992 atf_tc_set_md_var(tc, "descr", 3993 "Verify that masking single unrelated signal does not stop tracer " 3994 "from catching other signals"); 3995} 3996 3997ATF_TC_BODY(signal_mask_unrelated, tc) 3998{ 3999 const int exitval = 5; 4000 const int sigval = SIGSTOP; 4001 const int sigmasked = SIGTRAP; 4002 const int signotmasked = SIGINT; 4003 pid_t child, wpid; 4004#if defined(TWAIT_HAVE_STATUS) 4005 int status; 4006#endif 4007 sigset_t intmask; 4008 4009 DPRINTF("Before forking process PID=%d\n", getpid()); 4010 SYSCALL_REQUIRE((child = fork()) != -1); 4011 if (child == 0) { 4012 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 4013 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 4014 4015 sigemptyset(&intmask); 4016 sigaddset(&intmask, sigmasked); 4017 sigprocmask(SIG_BLOCK, &intmask, NULL); 4018 4019 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 4020 FORKEE_ASSERT(raise(sigval) == 0); 4021 4022 DPRINTF("Before raising %s from child\n", 4023 strsignal(signotmasked)); 4024 FORKEE_ASSERT(raise(signotmasked) == 0); 4025 4026 DPRINTF("Before exiting of the child process\n"); 4027 _exit(exitval); 4028 } 4029 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 4030 4031 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4032 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4033 4034 validate_status_stopped(status, sigval); 4035 4036 DPRINTF("Before resuming the child process where it left off and " 4037 "without signal to be sent\n"); 4038 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 4039 4040 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4041 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4042 4043 validate_status_stopped(status, signotmasked); 4044 4045 DPRINTF("Before resuming the child process where it left off and " 4046 "without signal to be sent\n"); 4047 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 4048 4049 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4050 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4051 4052 validate_status_exited(status, exitval); 4053 4054 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4055 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 4056} 4057 4058/// ---------------------------------------------------------------------------- 4059 4060ATF_TC(signal3); 4061ATF_TC_HEAD(signal3, tc) 4062{ 4063 atf_tc_set_md_var(tc, "timeout", "5"); 4064 atf_tc_set_md_var(tc, "descr", 4065 "Verify that masking SIGTRAP in tracee does not stop tracer from " 4066 "catching software breakpoints"); 4067} 4068 4069ATF_TC_BODY(signal3, tc) 4070{ 4071 const int exitval = 5; 4072 const int sigval = SIGSTOP; 4073 const int sigmasked = SIGTRAP; 4074 pid_t child, wpid; 4075#if defined(TWAIT_HAVE_STATUS) 4076 int status; 4077#endif 4078 sigset_t intmask; 4079 4080 DPRINTF("Before forking process PID=%d\n", getpid()); 4081 SYSCALL_REQUIRE((child = fork()) != -1); 4082 if (child == 0) { 4083 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 4084 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 4085 4086 sigemptyset(&intmask); 4087 sigaddset(&intmask, sigmasked); 4088 sigprocmask(SIG_BLOCK, &intmask, NULL); 4089 4090 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 4091 FORKEE_ASSERT(raise(sigval) == 0); 4092 4093 DPRINTF("Before raising software breakpoint from child\n"); 4094 trigger_trap(); 4095 4096 DPRINTF("Before exiting of the child process\n"); 4097 _exit(exitval); 4098 } 4099 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 4100 4101 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4102 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4103 4104 validate_status_stopped(status, sigval); 4105 4106 DPRINTF("Before resuming the child process where it left off and " 4107 "without signal to be sent\n"); 4108 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 4109 4110 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4111 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4112 4113 validate_status_stopped(status, sigmasked); 4114 4115 DPRINTF("Before resuming the child process where it left off and " 4116 "without signal to be sent\n"); 4117 SYSCALL_REQUIRE(ptrace(PT_KILL, child, NULL, 0) != -1); 4118 4119 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4120 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4121 4122 validate_status_signaled(status, SIGKILL, 0); 4123 4124 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4125 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 4126} 4127 4128#if defined(PT_STEP) 4129ATF_TC(signal4); 4130ATF_TC_HEAD(signal4, tc) 4131{ 4132 atf_tc_set_md_var(tc, "descr", 4133 "Verify that masking SIGTRAP in tracee does not stop tracer from " 4134 "catching single step trap"); 4135} 4136 4137ATF_TC_BODY(signal4, tc) 4138{ 4139 const int exitval = 5; 4140 const int sigval = SIGSTOP; 4141 const int sigmasked = SIGTRAP; 4142 pid_t child, wpid; 4143#if defined(TWAIT_HAVE_STATUS) 4144 int status; 4145#endif 4146 sigset_t intmask; 4147 int happy; 4148 4149#if defined(__arm__) 4150 /* PT_STEP not supported on arm 32-bit */ 4151 atf_tc_expect_fail("PR kern/51918 PR kern/52119"); 4152#endif 4153 4154 DPRINTF("Before forking process PID=%d\n", getpid()); 4155 SYSCALL_REQUIRE((child = fork()) != -1); 4156 if (child == 0) { 4157 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 4158 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 4159 4160 happy = check_happy(100); 4161 4162 sigemptyset(&intmask); 4163 sigaddset(&intmask, sigmasked); 4164 sigprocmask(SIG_BLOCK, &intmask, NULL); 4165 4166 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 4167 FORKEE_ASSERT(raise(sigval) == 0); 4168 4169 FORKEE_ASSERT_EQ(happy, check_happy(100)); 4170 4171 DPRINTF("Before exiting of the child process\n"); 4172 _exit(exitval); 4173 } 4174 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 4175 4176 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4177 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4178 4179 validate_status_stopped(status, sigval); 4180 4181 DPRINTF("Before resuming the child process where it left off and " 4182 "without signal to be sent\n"); 4183 SYSCALL_REQUIRE(ptrace(PT_STEP, child, (void *)1, 0) != -1); 4184 4185 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4186 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4187 4188 validate_status_stopped(status, sigmasked); 4189 4190 DPRINTF("Before resuming the child process where it left off and " 4191 "without signal to be sent\n"); 4192 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 4193 4194 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4195 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4196 4197 validate_status_exited(status, exitval); 4198 4199 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4200 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 4201} 4202#endif 4203 4204ATF_TC(signal5); 4205ATF_TC_HEAD(signal5, tc) 4206{ 4207 atf_tc_set_md_var(tc, "descr", 4208 "Verify that masking SIGTRAP in tracee does not stop tracer from " 4209 "catching exec() breakpoint"); 4210} 4211 4212ATF_TC_BODY(signal5, tc) 4213{ 4214 const int sigval = SIGSTOP; 4215 const int sigmasked = SIGTRAP; 4216 pid_t child, wpid; 4217#if defined(TWAIT_HAVE_STATUS) 4218 int status; 4219#endif 4220 struct ptrace_siginfo info; 4221 sigset_t intmask; 4222 4223 memset(&info, 0, sizeof(info)); 4224 4225 DPRINTF("Before forking process PID=%d\n", getpid()); 4226 SYSCALL_REQUIRE((child = fork()) != -1); 4227 if (child == 0) { 4228 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 4229 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 4230 4231 sigemptyset(&intmask); 4232 sigaddset(&intmask, sigmasked); 4233 sigprocmask(SIG_BLOCK, &intmask, NULL); 4234 4235 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 4236 FORKEE_ASSERT(raise(sigval) == 0); 4237 4238 DPRINTF("Before calling execve(2) from child\n"); 4239 execlp("/bin/echo", "/bin/echo", NULL); 4240 4241 /* NOTREACHED */ 4242 FORKEE_ASSERTX(0 && "Not reached"); 4243 } 4244 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 4245 4246 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4247 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4248 4249 validate_status_stopped(status, sigval); 4250 4251 DPRINTF("Before resuming the child process where it left off and " 4252 "without signal to be sent\n"); 4253 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 4254 4255 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4256 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4257 4258 validate_status_stopped(status, sigmasked); 4259 4260 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 4261 SYSCALL_REQUIRE( 4262 ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 4263 4264 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 4265 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 4266 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 4267 info.psi_siginfo.si_errno); 4268 4269 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigmasked); 4270 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_EXEC); 4271 4272 DPRINTF("Before resuming the child process where it left off and " 4273 "without signal to be sent\n"); 4274 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 4275 4276 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4277 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4278 4279 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4280 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 4281} 4282 4283#if defined(TWAIT_HAVE_PID) 4284ATF_TC(signal6); 4285ATF_TC_HEAD(signal6, tc) 4286{ 4287 atf_tc_set_md_var(tc, "timeout", "5"); 4288 atf_tc_set_md_var(tc, "descr", 4289 "Verify that masking SIGTRAP in tracee does not stop tracer from " 4290 "catching PTRACE_FORK breakpoint"); 4291} 4292 4293ATF_TC_BODY(signal6, tc) 4294{ 4295 const int exitval = 5; 4296 const int exitval2 = 15; 4297 const int sigval = SIGSTOP; 4298 const int sigmasked = SIGTRAP; 4299 pid_t child, child2, wpid; 4300#if defined(TWAIT_HAVE_STATUS) 4301 int status; 4302#endif 4303 sigset_t intmask; 4304 ptrace_state_t state; 4305 const int slen = sizeof(state); 4306 ptrace_event_t event; 4307 const int elen = sizeof(event); 4308 4309 atf_tc_expect_fail("PR kern/51918"); 4310 4311 DPRINTF("Before forking process PID=%d\n", getpid()); 4312 SYSCALL_REQUIRE((child = fork()) != -1); 4313 if (child == 0) { 4314 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 4315 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 4316 4317 sigemptyset(&intmask); 4318 sigaddset(&intmask, sigmasked); 4319 sigprocmask(SIG_BLOCK, &intmask, NULL); 4320 4321 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 4322 FORKEE_ASSERT(raise(sigval) == 0); 4323 4324 FORKEE_ASSERT((child2 = fork()) != -1); 4325 4326 if (child2 == 0) 4327 _exit(exitval2); 4328 4329 FORKEE_REQUIRE_SUCCESS 4330 (wpid = TWAIT_GENERIC(child2, &status, 0), child2); 4331 4332 forkee_status_exited(status, exitval2); 4333 4334 DPRINTF("Before exiting of the child process\n"); 4335 _exit(exitval); 4336 } 4337 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 4338 4339 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4340 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4341 4342 validate_status_stopped(status, sigval); 4343 4344 DPRINTF("Enable PTRACE_FORK in EVENT_MASK for the child %d\n", child); 4345 event.pe_set_event = PTRACE_FORK; 4346 SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); 4347 4348 DPRINTF("Before resuming the child process where it left off and " 4349 "without signal to be sent\n"); 4350 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 4351 4352 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4353 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4354 4355 validate_status_stopped(status, sigmasked); 4356 4357 SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 4358 ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_FORK); 4359 4360 child2 = state.pe_other_pid; 4361 DPRINTF("Reported PTRACE_FORK event with forkee %d\n", child2); 4362 4363 DPRINTF("Before calling %s() for the child2\n", TWAIT_FNAME); 4364 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0), 4365 child2); 4366 4367 validate_status_stopped(status, SIGTRAP); 4368 4369 SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1); 4370 ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_FORK); 4371 ATF_REQUIRE_EQ(state.pe_other_pid, child); 4372 4373 DPRINTF("Before resuming the forkee process where it left off and " 4374 "without signal to be sent\n"); 4375 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1); 4376 4377 DPRINTF("Before resuming the child process where it left off and " 4378 "without signal to be sent\n"); 4379 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 4380 4381 DPRINTF("Before calling %s() for the forkee - expected exited\n", 4382 TWAIT_FNAME); 4383 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0), 4384 child2); 4385 4386 validate_status_exited(status, exitval2); 4387 4388 DPRINTF("Before calling %s() for the forkee - expected no process\n", 4389 TWAIT_FNAME); 4390 TWAIT_REQUIRE_FAILURE(ECHILD, 4391 wpid = TWAIT_GENERIC(child2, &status, 0)); 4392 4393 DPRINTF("Before calling %s() for the child - expected stopped " 4394 "SIGCHLD\n", TWAIT_FNAME); 4395 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4396 4397 validate_status_stopped(status, SIGCHLD); 4398 4399 DPRINTF("Before resuming the child process where it left off and " 4400 "without signal to be sent\n"); 4401 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 4402 4403 DPRINTF("Before calling %s() for the child - expected exited\n", 4404 TWAIT_FNAME); 4405 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4406 4407 validate_status_exited(status, exitval); 4408 4409 DPRINTF("Before calling %s() for the child - expected no process\n", 4410 TWAIT_FNAME); 4411 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 4412} 4413#endif 4414 4415#if defined(TWAIT_HAVE_PID) 4416ATF_TC(signal7); 4417ATF_TC_HEAD(signal7, tc) 4418{ 4419 atf_tc_set_md_var(tc, "descr", 4420 "Verify that masking SIGTRAP in tracee does not stop tracer from " 4421 "catching PTRACE_VFORK breakpoint"); 4422} 4423 4424ATF_TC_BODY(signal7, tc) 4425{ 4426 const int exitval = 5; 4427 const int exitval2 = 15; 4428 const int sigval = SIGSTOP; 4429 const int sigmasked = SIGTRAP; 4430 pid_t child, child2, wpid; 4431#if defined(TWAIT_HAVE_STATUS) 4432 int status; 4433#endif 4434 sigset_t intmask; 4435 ptrace_state_t state; 4436 const int slen = sizeof(state); 4437 ptrace_event_t event; 4438 const int elen = sizeof(event); 4439 4440 atf_tc_expect_fail("PR kern/51918"); 4441 4442 DPRINTF("Before forking process PID=%d\n", getpid()); 4443 SYSCALL_REQUIRE((child = fork()) != -1); 4444 if (child == 0) { 4445 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 4446 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 4447 4448 sigemptyset(&intmask); 4449 sigaddset(&intmask, sigmasked); 4450 sigprocmask(SIG_BLOCK, &intmask, NULL); 4451 4452 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 4453 FORKEE_ASSERT(raise(sigval) == 0); 4454 4455 FORKEE_ASSERT((child2 = fork()) != -1); 4456 4457 if (child2 == 0) 4458 _exit(exitval2); 4459 4460 FORKEE_REQUIRE_SUCCESS 4461 (wpid = TWAIT_GENERIC(child2, &status, 0), child2); 4462 4463 forkee_status_exited(status, exitval2); 4464 4465 DPRINTF("Before exiting of the child process\n"); 4466 _exit(exitval); 4467 } 4468 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 4469 4470 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4471 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4472 4473 validate_status_stopped(status, sigval); 4474 4475 DPRINTF("Enable PTRACE_VFORK in EVENT_MASK for the child %d\n", child); 4476 event.pe_set_event = PTRACE_VFORK; 4477 SYSCALL_REQUIRE( 4478 ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1 || 4479 errno == ENOTSUP); 4480 4481 DPRINTF("Before resuming the child process where it left off and " 4482 "without signal to be sent\n"); 4483 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 4484 4485 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4486 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4487 4488 validate_status_stopped(status, sigmasked); 4489 4490 SYSCALL_REQUIRE( 4491 ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 4492 ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK); 4493 4494 child2 = state.pe_other_pid; 4495 DPRINTF("Reported PTRACE_VFORK event with forkee %d\n", child2); 4496 4497 DPRINTF("Before calling %s() for the child2\n", TWAIT_FNAME); 4498 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0), 4499 child2); 4500 4501 validate_status_stopped(status, SIGTRAP); 4502 4503 SYSCALL_REQUIRE( 4504 ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1); 4505 ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK); 4506 ATF_REQUIRE_EQ(state.pe_other_pid, child); 4507 4508 DPRINTF("Before resuming the forkee process where it left off and " 4509 "without signal to be sent\n"); 4510 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1); 4511 4512 DPRINTF("Before resuming the child process where it left off and " 4513 "without signal to be sent\n"); 4514 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 4515 4516 DPRINTF("Before calling %s() for the forkee - expected exited\n", 4517 TWAIT_FNAME); 4518 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0), 4519 child2); 4520 4521 validate_status_exited(status, exitval2); 4522 4523 DPRINTF("Before calling %s() for the forkee - expected no process\n", 4524 TWAIT_FNAME); 4525 TWAIT_REQUIRE_FAILURE(ECHILD, 4526 wpid = TWAIT_GENERIC(child2, &status, 0)); 4527 4528 DPRINTF("Before calling %s() for the child - expected stopped " 4529 "SIGCHLD\n", TWAIT_FNAME); 4530 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4531 4532 validate_status_stopped(status, SIGCHLD); 4533 4534 DPRINTF("Before resuming the child process where it left off and " 4535 "without signal to be sent\n"); 4536 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 4537 4538 DPRINTF("Before calling %s() for the child - expected exited\n", 4539 TWAIT_FNAME); 4540 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4541 4542 validate_status_exited(status, exitval); 4543 4544 DPRINTF("Before calling %s() for the child - expected no process\n", 4545 TWAIT_FNAME); 4546 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 4547} 4548#endif 4549 4550ATF_TC(signal8); 4551ATF_TC_HEAD(signal8, tc) 4552{ 4553 atf_tc_set_md_var(tc, "descr", 4554 "Verify that masking SIGTRAP in tracee does not stop tracer from " 4555 "catching PTRACE_VFORK_DONE breakpoint"); 4556} 4557 4558ATF_TC_BODY(signal8, tc) 4559{ 4560 const int exitval = 5; 4561 const int exitval2 = 15; 4562 const int sigval = SIGSTOP; 4563 const int sigmasked = SIGTRAP; 4564 pid_t child, child2, wpid; 4565#if defined(TWAIT_HAVE_STATUS) 4566 int status; 4567#endif 4568 sigset_t intmask; 4569 ptrace_state_t state; 4570 const int slen = sizeof(state); 4571 ptrace_event_t event; 4572 const int elen = sizeof(event); 4573 4574 atf_tc_expect_fail("PR kern/51918"); 4575 4576 DPRINTF("Before forking process PID=%d\n", getpid()); 4577 SYSCALL_REQUIRE((child = fork()) != -1); 4578 if (child == 0) { 4579 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 4580 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 4581 4582 sigemptyset(&intmask); 4583 sigaddset(&intmask, sigmasked); 4584 sigprocmask(SIG_BLOCK, &intmask, NULL); 4585 4586 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 4587 FORKEE_ASSERT(raise(sigval) == 0); 4588 4589 FORKEE_ASSERT((child2 = vfork()) != -1); 4590 4591 if (child2 == 0) 4592 _exit(exitval2); 4593 4594 FORKEE_REQUIRE_SUCCESS 4595 (wpid = TWAIT_GENERIC(child2, &status, 0), child2); 4596 4597 forkee_status_exited(status, exitval2); 4598 4599 DPRINTF("Before exiting of the child process\n"); 4600 _exit(exitval); 4601 } 4602 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 4603 4604 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4605 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4606 4607 validate_status_stopped(status, sigval); 4608 4609 DPRINTF("Enable PTRACE_VFORK_DONE in EVENT_MASK for the child %d\n", 4610 child); 4611 event.pe_set_event = PTRACE_VFORK_DONE; 4612 SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); 4613 4614 DPRINTF("Before resuming the child process where it left off and " 4615 "without signal to be sent\n"); 4616 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 4617 4618 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4619 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4620 4621 validate_status_stopped(status, sigmasked); 4622 4623 SYSCALL_REQUIRE( 4624 ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 4625 ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK_DONE); 4626 4627 child2 = state.pe_other_pid; 4628 DPRINTF("Reported PTRACE_VFORK_DONE event with forkee %d\n", child2); 4629 4630 DPRINTF("Before resuming the child process where it left off and " 4631 "without signal to be sent\n"); 4632 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 4633 4634 DPRINTF("Before calling %s() for the child - expected stopped " 4635 "SIGCHLD\n", TWAIT_FNAME); 4636 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4637 4638 validate_status_stopped(status, SIGCHLD); 4639 4640 DPRINTF("Before resuming the child process where it left off and " 4641 "without signal to be sent\n"); 4642 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 4643 4644 DPRINTF("Before calling %s() for the child - expected exited\n", 4645 TWAIT_FNAME); 4646 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4647 4648 validate_status_exited(status, exitval); 4649 4650 DPRINTF("Before calling %s() for the child - expected no process\n", 4651 TWAIT_FNAME); 4652 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 4653} 4654 4655volatile lwpid_t the_lwp_id = 0; 4656 4657static void 4658lwp_main_func(void *arg) 4659{ 4660 the_lwp_id = _lwp_self(); 4661 _lwp_exit(); 4662} 4663 4664ATF_TC(signal9); 4665ATF_TC_HEAD(signal9, tc) 4666{ 4667 atf_tc_set_md_var(tc, "descr", 4668 "Verify that masking SIGTRAP in tracee does not stop tracer from " 4669 "catching PTRACE_LWP_CREATE breakpoint"); 4670} 4671 4672ATF_TC_BODY(signal9, tc) 4673{ 4674 const int exitval = 5; 4675 const int sigval = SIGSTOP; 4676 const int sigmasked = SIGTRAP; 4677 pid_t child, wpid; 4678#if defined(TWAIT_HAVE_STATUS) 4679 int status; 4680#endif 4681 sigset_t intmask; 4682 ptrace_state_t state; 4683 const int slen = sizeof(state); 4684 ptrace_event_t event; 4685 const int elen = sizeof(event); 4686 ucontext_t uc; 4687 lwpid_t lid; 4688 static const size_t ssize = 16*1024; 4689 void *stack; 4690 4691 atf_tc_expect_fail("PR kern/51918"); 4692 4693 DPRINTF("Before forking process PID=%d\n", getpid()); 4694 SYSCALL_REQUIRE((child = fork()) != -1); 4695 if (child == 0) { 4696 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 4697 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 4698 4699 sigemptyset(&intmask); 4700 sigaddset(&intmask, sigmasked); 4701 sigprocmask(SIG_BLOCK, &intmask, NULL); 4702 4703 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 4704 FORKEE_ASSERT(raise(sigval) == 0); 4705 4706 DPRINTF("Before allocating memory for stack in child\n"); 4707 FORKEE_ASSERT((stack = malloc(ssize)) != NULL); 4708 4709 DPRINTF("Before making context for new lwp in child\n"); 4710 _lwp_makecontext(&uc, lwp_main_func, NULL, NULL, stack, ssize); 4711 4712 DPRINTF("Before creating new in child\n"); 4713 FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0); 4714 4715 DPRINTF("Before waiting for lwp %d to exit\n", lid); 4716 FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0); 4717 4718 DPRINTF("Before verifying that reported %d and running lid %d " 4719 "are the same\n", lid, the_lwp_id); 4720 FORKEE_ASSERT_EQ(lid, the_lwp_id); 4721 4722 DPRINTF("Before exiting of the child process\n"); 4723 _exit(exitval); 4724 } 4725 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 4726 4727 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4728 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4729 4730 validate_status_stopped(status, sigval); 4731 4732 DPRINTF("Set empty EVENT_MASK for the child %d\n", child); 4733 event.pe_set_event = PTRACE_LWP_CREATE; 4734 SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); 4735 4736 DPRINTF("Before resuming the child process where it left off and " 4737 "without signal to be sent\n"); 4738 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 4739 4740 DPRINTF("Before calling %s() for the child - expected stopped " 4741 "SIGTRAP\n", TWAIT_FNAME); 4742 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4743 4744 validate_status_stopped(status, sigmasked); 4745 4746 SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 4747 4748 ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_LWP_CREATE); 4749 4750 lid = state.pe_lwp; 4751 DPRINTF("Reported PTRACE_LWP_CREATE event with lid %d\n", lid); 4752 4753 DPRINTF("Before resuming the child process where it left off and " 4754 "without signal to be sent\n"); 4755 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 4756 4757 DPRINTF("Before calling %s() for the child - expected exited\n", 4758 TWAIT_FNAME); 4759 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4760 4761 validate_status_exited(status, exitval); 4762 4763 DPRINTF("Before calling %s() for the child - expected no process\n", 4764 TWAIT_FNAME); 4765 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 4766} 4767 4768ATF_TC(signal10); 4769ATF_TC_HEAD(signal10, tc) 4770{ 4771 atf_tc_set_md_var(tc, "descr", 4772 "Verify that masking SIGTRAP in tracee does not stop tracer from " 4773 "catching PTRACE_LWP_EXIT breakpoint"); 4774} 4775 4776ATF_TC_BODY(signal10, tc) 4777{ 4778 const int exitval = 5; 4779 const int sigval = SIGSTOP; 4780 const int sigmasked = SIGTRAP; 4781 pid_t child, wpid; 4782#if defined(TWAIT_HAVE_STATUS) 4783 int status; 4784#endif 4785 sigset_t intmask; 4786 ptrace_state_t state; 4787 const int slen = sizeof(state); 4788 ptrace_event_t event; 4789 const int elen = sizeof(event); 4790 ucontext_t uc; 4791 lwpid_t lid; 4792 static const size_t ssize = 16*1024; 4793 void *stack; 4794 4795 atf_tc_expect_fail("PR kern/51918"); 4796 4797 DPRINTF("Before forking process PID=%d\n", getpid()); 4798 SYSCALL_REQUIRE((child = fork()) != -1); 4799 if (child == 0) { 4800 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 4801 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 4802 4803 sigemptyset(&intmask); 4804 sigaddset(&intmask, sigmasked); 4805 sigprocmask(SIG_BLOCK, &intmask, NULL); 4806 4807 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 4808 FORKEE_ASSERT(raise(sigval) == 0); 4809 4810 DPRINTF("Before allocating memory for stack in child\n"); 4811 FORKEE_ASSERT((stack = malloc(ssize)) != NULL); 4812 4813 DPRINTF("Before making context for new lwp in child\n"); 4814 _lwp_makecontext(&uc, lwp_main_func, NULL, NULL, stack, ssize); 4815 4816 DPRINTF("Before creating new in child\n"); 4817 FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0); 4818 4819 DPRINTF("Before waiting for lwp %d to exit\n", lid); 4820 FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0); 4821 4822 DPRINTF("Before verifying that reported %d and running lid %d " 4823 "are the same\n", lid, the_lwp_id); 4824 FORKEE_ASSERT_EQ(lid, the_lwp_id); 4825 4826 DPRINTF("Before exiting of the child process\n"); 4827 _exit(exitval); 4828 } 4829 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 4830 4831 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4832 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4833 4834 validate_status_stopped(status, sigval); 4835 4836 DPRINTF("Set empty EVENT_MASK for the child %d\n", child); 4837 event.pe_set_event = PTRACE_LWP_EXIT; 4838 SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); 4839 4840 DPRINTF("Before resuming the child process where it left off and " 4841 "without signal to be sent\n"); 4842 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 4843 4844 DPRINTF("Before calling %s() for the child - expected stopped " 4845 "SIGTRAP\n", TWAIT_FNAME); 4846 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4847 4848 validate_status_stopped(status, sigmasked); 4849 4850 SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 4851 4852 ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_LWP_EXIT); 4853 4854 lid = state.pe_lwp; 4855 DPRINTF("Reported PTRACE_LWP_EXIT event with lid %d\n", lid); 4856 4857 DPRINTF("Before resuming the child process where it left off and " 4858 "without signal to be sent\n"); 4859 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 4860 4861 DPRINTF("Before calling %s() for the child - expected exited\n", 4862 TWAIT_FNAME); 4863 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4864 4865 validate_status_exited(status, exitval); 4866 4867 DPRINTF("Before calling %s() for the child - expected no process\n", 4868 TWAIT_FNAME); 4869 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 4870} 4871 4872static void 4873lwp_main_stop(void *arg) 4874{ 4875 the_lwp_id = _lwp_self(); 4876 4877 raise(SIGTRAP); 4878 4879 _lwp_exit(); 4880} 4881 4882ATF_TC(suspend1); 4883ATF_TC_HEAD(suspend1, tc) 4884{ 4885 atf_tc_set_md_var(tc, "descr", 4886 "Verify that a thread can be suspended by a debugger and later " 4887 "resumed by a tracee"); 4888} 4889 4890ATF_TC_BODY(suspend1, tc) 4891{ 4892 const int exitval = 5; 4893 const int sigval = SIGSTOP; 4894 pid_t child, wpid; 4895#if defined(TWAIT_HAVE_STATUS) 4896 int status; 4897#endif 4898 ucontext_t uc; 4899 lwpid_t lid; 4900 static const size_t ssize = 16*1024; 4901 void *stack; 4902 struct ptrace_lwpinfo pl; 4903 struct ptrace_siginfo psi; 4904 volatile int go = 0; 4905 4906 // Feature pending for refactoring 4907 atf_tc_expect_fail("PR kern/51995"); 4908 4909 // Hangs with qemu 4910 ATF_REQUIRE(0 && "In order to get reliable failure, abort"); 4911 4912 DPRINTF("Before forking process PID=%d\n", getpid()); 4913 SYSCALL_REQUIRE((child = fork()) != -1); 4914 if (child == 0) { 4915 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 4916 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 4917 4918 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 4919 FORKEE_ASSERT(raise(sigval) == 0); 4920 4921 DPRINTF("Before allocating memory for stack in child\n"); 4922 FORKEE_ASSERT((stack = malloc(ssize)) != NULL); 4923 4924 DPRINTF("Before making context for new lwp in child\n"); 4925 _lwp_makecontext(&uc, lwp_main_stop, NULL, NULL, stack, ssize); 4926 4927 DPRINTF("Before creating new in child\n"); 4928 FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0); 4929 4930 while (go == 0) 4931 continue; 4932 4933 raise(SIGINT); 4934 4935 FORKEE_ASSERT(_lwp_continue(lid) == 0); 4936 4937 DPRINTF("Before waiting for lwp %d to exit\n", lid); 4938 FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0); 4939 4940 DPRINTF("Before verifying that reported %d and running lid %d " 4941 "are the same\n", lid, the_lwp_id); 4942 FORKEE_ASSERT_EQ(lid, the_lwp_id); 4943 4944 DPRINTF("Before exiting of the child process\n"); 4945 _exit(exitval); 4946 } 4947 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 4948 4949 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4950 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4951 4952 validate_status_stopped(status, sigval); 4953 4954 DPRINTF("Before resuming the child process where it left off and " 4955 "without signal to be sent\n"); 4956 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 4957 4958 DPRINTF("Before calling %s() for the child - expected stopped " 4959 "SIGTRAP\n", TWAIT_FNAME); 4960 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4961 4962 validate_status_stopped(status, SIGTRAP); 4963 4964 DPRINTF("Before reading siginfo and lwpid_t\n"); 4965 SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &psi, sizeof(psi)) != -1); 4966 4967 DPRINTF("Before suspending LWP %d\n", psi.psi_lwpid); 4968 SYSCALL_REQUIRE(ptrace(PT_SUSPEND, child, NULL, psi.psi_lwpid) != -1); 4969 4970 DPRINTF("Write new go to tracee (PID=%d) from tracer (PID=%d)\n", 4971 child, getpid()); 4972 SYSCALL_REQUIRE(ptrace(PT_WRITE_D, child, __UNVOLATILE(&go), 1) != -1); 4973 4974 DPRINTF("Before resuming the child process where it left off and " 4975 "without signal to be sent\n"); 4976 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 4977 4978 DPRINTF("Before calling %s() for the child - expected stopped " 4979 "SIGINT\n", TWAIT_FNAME); 4980 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4981 4982 validate_status_stopped(status, SIGINT); 4983 4984 pl.pl_lwpid = 0; 4985 4986 SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &pl, sizeof(pl)) != -1); 4987 while (pl.pl_lwpid != 0) { 4988 4989 SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &pl, sizeof(pl)) != -1); 4990 switch (pl.pl_lwpid) { 4991 case 1: 4992 ATF_REQUIRE_EQ(pl.pl_event, PL_EVENT_SIGNAL); 4993 break; 4994 case 2: 4995 ATF_REQUIRE_EQ(pl.pl_event, PL_EVENT_SUSPENDED); 4996 break; 4997 } 4998 } 4999 5000 DPRINTF("Before resuming the child process where it left off and " 5001 "without signal to be sent\n"); 5002 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 5003 5004 DPRINTF("Before calling %s() for the child - expected exited\n", 5005 TWAIT_FNAME); 5006 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5007 5008 validate_status_exited(status, exitval); 5009 5010 DPRINTF("Before calling %s() for the child - expected no process\n", 5011 TWAIT_FNAME); 5012 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 5013} 5014 5015ATF_TC(suspend2); 5016ATF_TC_HEAD(suspend2, tc) 5017{ 5018 atf_tc_set_md_var(tc, "descr", 5019 "Verify that the while the only thread within a process is " 5020 "suspended, the whole process cannot be unstopped"); 5021} 5022 5023ATF_TC_BODY(suspend2, tc) 5024{ 5025 const int exitval = 5; 5026 const int sigval = SIGSTOP; 5027 pid_t child, wpid; 5028#if defined(TWAIT_HAVE_STATUS) 5029 int status; 5030#endif 5031 struct ptrace_siginfo psi; 5032 5033 // Feature pending for refactoring 5034 atf_tc_expect_fail("PR kern/51995"); 5035 5036 // Hangs with qemu 5037 ATF_REQUIRE(0 && "In order to get reliable failure, abort"); 5038 5039 DPRINTF("Before forking process PID=%d\n", getpid()); 5040 SYSCALL_REQUIRE((child = fork()) != -1); 5041 if (child == 0) { 5042 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 5043 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 5044 5045 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 5046 FORKEE_ASSERT(raise(sigval) == 0); 5047 5048 DPRINTF("Before exiting of the child process\n"); 5049 _exit(exitval); 5050 } 5051 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 5052 5053 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 5054 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5055 5056 validate_status_stopped(status, sigval); 5057 5058 DPRINTF("Before reading siginfo and lwpid_t\n"); 5059 SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &psi, sizeof(psi)) != -1); 5060 5061 DPRINTF("Before suspending LWP %d\n", psi.psi_lwpid); 5062 SYSCALL_REQUIRE(ptrace(PT_SUSPEND, child, NULL, psi.psi_lwpid) != -1); 5063 5064 DPRINTF("Before resuming the child process where it left off and " 5065 "without signal to be sent\n"); 5066 ATF_REQUIRE_ERRNO(EDEADLK, 5067 ptrace(PT_CONTINUE, child, (void *)1, 0) == -1); 5068 5069 DPRINTF("Before resuming LWP %d\n", psi.psi_lwpid); 5070 SYSCALL_REQUIRE(ptrace(PT_RESUME, child, NULL, psi.psi_lwpid) != -1); 5071 5072 DPRINTF("Before resuming the child process where it left off and " 5073 "without signal to be sent\n"); 5074 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 5075 5076 DPRINTF("Before calling %s() for the child - expected exited\n", 5077 TWAIT_FNAME); 5078 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5079 5080 validate_status_exited(status, exitval); 5081 5082 DPRINTF("Before calling %s() for the child - expected no process\n", 5083 TWAIT_FNAME); 5084 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 5085} 5086 5087ATF_TC(resume1); 5088ATF_TC_HEAD(resume1, tc) 5089{ 5090 atf_tc_set_md_var(tc, "timeout", "5"); 5091 atf_tc_set_md_var(tc, "descr", 5092 "Verify that a thread can be suspended by a debugger and later " 5093 "resumed by the debugger"); 5094} 5095 5096ATF_TC_BODY(resume1, tc) 5097{ 5098 struct msg_fds fds; 5099 const int exitval = 5; 5100 const int sigval = SIGSTOP; 5101 pid_t child, wpid; 5102 uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */ 5103#if defined(TWAIT_HAVE_STATUS) 5104 int status; 5105#endif 5106 ucontext_t uc; 5107 lwpid_t lid; 5108 static const size_t ssize = 16*1024; 5109 void *stack; 5110 struct ptrace_lwpinfo pl; 5111 struct ptrace_siginfo psi; 5112 5113 // Feature pending for refactoring 5114 atf_tc_expect_fail("PR kern/51995"); 5115 5116 // Hangs with qemu 5117 ATF_REQUIRE(0 && "In order to get reliable failure, abort"); 5118 5119 SYSCALL_REQUIRE(msg_open(&fds) == 0); 5120 5121 DPRINTF("Before forking process PID=%d\n", getpid()); 5122 SYSCALL_REQUIRE((child = fork()) != -1); 5123 if (child == 0) { 5124 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 5125 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 5126 5127 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 5128 FORKEE_ASSERT(raise(sigval) == 0); 5129 5130 DPRINTF("Before allocating memory for stack in child\n"); 5131 FORKEE_ASSERT((stack = malloc(ssize)) != NULL); 5132 5133 DPRINTF("Before making context for new lwp in child\n"); 5134 _lwp_makecontext(&uc, lwp_main_stop, NULL, NULL, stack, ssize); 5135 5136 DPRINTF("Before creating new in child\n"); 5137 FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0); 5138 5139 CHILD_TO_PARENT("Message", fds, msg); 5140 5141 raise(SIGINT); 5142 5143 DPRINTF("Before waiting for lwp %d to exit\n", lid); 5144 FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0); 5145 5146 DPRINTF("Before verifying that reported %d and running lid %d " 5147 "are the same\n", lid, the_lwp_id); 5148 FORKEE_ASSERT_EQ(lid, the_lwp_id); 5149 5150 DPRINTF("Before exiting of the child process\n"); 5151 _exit(exitval); 5152 } 5153 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 5154 5155 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 5156 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5157 5158 validate_status_stopped(status, sigval); 5159 5160 DPRINTF("Before resuming the child process where it left off and " 5161 "without signal to be sent\n"); 5162 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 5163 5164 DPRINTF("Before calling %s() for the child - expected stopped " 5165 "SIGTRAP\n", TWAIT_FNAME); 5166 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5167 5168 validate_status_stopped(status, SIGTRAP); 5169 5170 DPRINTF("Before reading siginfo and lwpid_t\n"); 5171 SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &psi, sizeof(psi)) != -1); 5172 5173 DPRINTF("Before suspending LWP %d\n", psi.psi_lwpid); 5174 SYSCALL_REQUIRE(ptrace(PT_SUSPEND, child, NULL, psi.psi_lwpid) != -1); 5175 5176 PARENT_FROM_CHILD("Message", fds, msg); 5177 5178 DPRINTF("Before resuming the child process where it left off and " 5179 "without signal to be sent\n"); 5180 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 5181 5182 DPRINTF("Before calling %s() for the child - expected stopped " 5183 "SIGINT\n", TWAIT_FNAME); 5184 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5185 5186 validate_status_stopped(status, SIGINT); 5187 5188 pl.pl_lwpid = 0; 5189 5190 SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &pl, sizeof(pl)) != -1); 5191 while (pl.pl_lwpid != 0) { 5192 SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &pl, sizeof(pl)) != -1); 5193 switch (pl.pl_lwpid) { 5194 case 1: 5195 ATF_REQUIRE_EQ(pl.pl_event, PL_EVENT_SIGNAL); 5196 break; 5197 case 2: 5198 ATF_REQUIRE_EQ(pl.pl_event, PL_EVENT_SUSPENDED); 5199 break; 5200 } 5201 } 5202 5203 DPRINTF("Before resuming LWP %d\n", psi.psi_lwpid); 5204 SYSCALL_REQUIRE(ptrace(PT_RESUME, child, NULL, psi.psi_lwpid) != -1); 5205 5206 DPRINTF("Before resuming the child process where it left off and " 5207 "without signal to be sent\n"); 5208 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 5209 5210 DPRINTF("Before calling %s() for the child - expected exited\n", 5211 TWAIT_FNAME); 5212 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5213 5214 validate_status_exited(status, exitval); 5215 5216 DPRINTF("Before calling %s() for the child - expected no process\n", 5217 TWAIT_FNAME); 5218 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 5219 5220 msg_close(&fds); 5221 5222 DPRINTF("XXX: Test worked this time but for consistency timeout it\n"); 5223 sleep(10); 5224} 5225 5226ATF_TC(syscall1); 5227ATF_TC_HEAD(syscall1, tc) 5228{ 5229 atf_tc_set_md_var(tc, "descr", 5230 "Verify that getpid(2) can be traced with PT_SYSCALL"); 5231} 5232 5233ATF_TC_BODY(syscall1, tc) 5234{ 5235 const int exitval = 5; 5236 const int sigval = SIGSTOP; 5237 pid_t child, wpid; 5238#if defined(TWAIT_HAVE_STATUS) 5239 int status; 5240#endif 5241 struct ptrace_siginfo info; 5242 memset(&info, 0, sizeof(info)); 5243 5244 DPRINTF("Before forking process PID=%d\n", getpid()); 5245 SYSCALL_REQUIRE((child = fork()) != -1); 5246 if (child == 0) { 5247 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 5248 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 5249 5250 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 5251 FORKEE_ASSERT(raise(sigval) == 0); 5252 5253 syscall(SYS_getpid); 5254 5255 DPRINTF("Before exiting of the child process\n"); 5256 _exit(exitval); 5257 } 5258 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 5259 5260 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 5261 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5262 5263 validate_status_stopped(status, sigval); 5264 5265 DPRINTF("Before resuming the child process where it left off and " 5266 "without signal to be sent\n"); 5267 SYSCALL_REQUIRE(ptrace(PT_SYSCALL, child, (void *)1, 0) != -1); 5268 5269 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 5270 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5271 5272 validate_status_stopped(status, SIGTRAP); 5273 5274 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 5275 SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 5276 5277 DPRINTF("Before checking siginfo_t and lwpid\n"); 5278 ATF_REQUIRE_EQ(info.psi_lwpid, 1); 5279 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); 5280 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_SCE); 5281 5282 DPRINTF("Before resuming the child process where it left off and " 5283 "without signal to be sent\n"); 5284 SYSCALL_REQUIRE(ptrace(PT_SYSCALL, child, (void *)1, 0) != -1); 5285 5286 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 5287 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5288 5289 validate_status_stopped(status, SIGTRAP); 5290 5291 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 5292 SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 5293 5294 DPRINTF("Before checking siginfo_t and lwpid\n"); 5295 ATF_REQUIRE_EQ(info.psi_lwpid, 1); 5296 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); 5297 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_SCX); 5298 5299 DPRINTF("Before resuming the child process where it left off and " 5300 "without signal to be sent\n"); 5301 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 5302 5303 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 5304 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5305 5306 validate_status_exited(status, exitval); 5307 5308 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 5309 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 5310} 5311 5312ATF_TC(syscallemu1); 5313ATF_TC_HEAD(syscallemu1, tc) 5314{ 5315 atf_tc_set_md_var(tc, "descr", 5316 "Verify that exit(2) can be intercepted with PT_SYSCALLEMU"); 5317} 5318 5319ATF_TC_BODY(syscallemu1, tc) 5320{ 5321 const int exitval = 5; 5322 const int sigval = SIGSTOP; 5323 pid_t child, wpid; 5324#if defined(TWAIT_HAVE_STATUS) 5325 int status; 5326#endif 5327 5328#if defined(__sparc__) && !defined(__sparc64__) 5329 /* syscallemu does not work on sparc (32-bit) */ 5330 atf_tc_expect_fail("PR kern/52166"); 5331#endif 5332 5333 DPRINTF("Before forking process PID=%d\n", getpid()); 5334 SYSCALL_REQUIRE((child = fork()) != -1); 5335 if (child == 0) { 5336 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 5337 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 5338 5339 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 5340 FORKEE_ASSERT(raise(sigval) == 0); 5341 5342 syscall(SYS_exit, 100); 5343 5344 DPRINTF("Before exiting of the child process\n"); 5345 _exit(exitval); 5346 } 5347 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 5348 5349 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 5350 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5351 5352 validate_status_stopped(status, sigval); 5353 5354 DPRINTF("Before resuming the child process where it left off and " 5355 "without signal to be sent\n"); 5356 SYSCALL_REQUIRE(ptrace(PT_SYSCALL, child, (void *)1, 0) != -1); 5357 5358 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 5359 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5360 5361 validate_status_stopped(status, SIGTRAP); 5362 5363 DPRINTF("Set SYSCALLEMU for intercepted syscall\n"); 5364 SYSCALL_REQUIRE(ptrace(PT_SYSCALLEMU, child, (void *)1, 0) != -1); 5365 5366 DPRINTF("Before resuming the child process where it left off and " 5367 "without signal to be sent\n"); 5368 SYSCALL_REQUIRE(ptrace(PT_SYSCALL, child, (void *)1, 0) != -1); 5369 5370 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 5371 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5372 5373 validate_status_stopped(status, SIGTRAP); 5374 5375 DPRINTF("Before resuming the child process where it left off and " 5376 "without signal to be sent\n"); 5377 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 5378 5379 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 5380 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 5381 5382 validate_status_exited(status, exitval); 5383 5384 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 5385 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 5386} 5387 5388#include "t_ptrace_amd64_wait.h" 5389#include "t_ptrace_i386_wait.h" 5390#include "t_ptrace_x86_wait.h" 5391 5392ATF_TP_ADD_TCS(tp) 5393{ 5394 setvbuf(stdout, NULL, _IONBF, 0); 5395 setvbuf(stderr, NULL, _IONBF, 0); 5396 5397 ATF_TP_ADD_TC(tp, traceme_raise1); 5398 ATF_TP_ADD_TC(tp, traceme_raise2); 5399 ATF_TP_ADD_TC(tp, traceme_raise3); 5400 ATF_TP_ADD_TC(tp, traceme_raise4); 5401 ATF_TP_ADD_TC(tp, traceme_raise5); 5402 ATF_TP_ADD_TC(tp, traceme_raise6); 5403 ATF_TP_ADD_TC(tp, traceme_raise7); 5404 ATF_TP_ADD_TC(tp, traceme_raise8); 5405 ATF_TP_ADD_TC(tp, traceme_raise9); 5406 ATF_TP_ADD_TC(tp, traceme_raise10); 5407 5408 ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored1); 5409 ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored2); 5410 ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored3); 5411 ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored4); 5412 ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored5); 5413 ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored6); 5414 ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored7); 5415 ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored8); 5416 5417 ATF_TP_ADD_TC(tp, traceme_raisesignal_masked1); 5418 ATF_TP_ADD_TC(tp, traceme_raisesignal_masked2); 5419 ATF_TP_ADD_TC(tp, traceme_raisesignal_masked3); 5420 ATF_TP_ADD_TC(tp, traceme_raisesignal_masked4); 5421 ATF_TP_ADD_TC(tp, traceme_raisesignal_masked5); 5422 ATF_TP_ADD_TC(tp, traceme_raisesignal_masked6); 5423 ATF_TP_ADD_TC(tp, traceme_raisesignal_masked7); 5424 ATF_TP_ADD_TC(tp, traceme_raisesignal_masked8); 5425 5426 ATF_TP_ADD_TC(tp, traceme_crash_trap); 5427 ATF_TP_ADD_TC(tp, traceme_crash_segv); 5428 ATF_TP_ADD_TC(tp, traceme_crash_ill); 5429 ATF_TP_ADD_TC(tp, traceme_crash_fpe); 5430 ATF_TP_ADD_TC(tp, traceme_crash_bus); 5431 5432 ATF_TP_ADD_TC(tp, traceme_sendsignal_handle1); 5433 ATF_TP_ADD_TC(tp, traceme_sendsignal_handle2); 5434 ATF_TP_ADD_TC(tp, traceme_sendsignal_handle3); 5435 ATF_TP_ADD_TC(tp, traceme_sendsignal_handle4); 5436 ATF_TP_ADD_TC(tp, traceme_sendsignal_handle5); 5437 ATF_TP_ADD_TC(tp, traceme_sendsignal_handle6); 5438 ATF_TP_ADD_TC(tp, traceme_sendsignal_handle7); 5439 ATF_TP_ADD_TC(tp, traceme_sendsignal_handle8); 5440 5441 ATF_TP_ADD_TC(tp, traceme_sendsignal_masked1); 5442 ATF_TP_ADD_TC(tp, traceme_sendsignal_masked2); 5443 ATF_TP_ADD_TC(tp, traceme_sendsignal_masked3); 5444 ATF_TP_ADD_TC(tp, traceme_sendsignal_masked4); 5445 ATF_TP_ADD_TC(tp, traceme_sendsignal_masked5); 5446 ATF_TP_ADD_TC(tp, traceme_sendsignal_masked6); 5447 ATF_TP_ADD_TC(tp, traceme_sendsignal_masked7); 5448 ATF_TP_ADD_TC(tp, traceme_sendsignal_masked8); 5449 5450 ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored1); 5451 ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored2); 5452 ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored3); 5453 ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored4); 5454 ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored5); 5455 ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored6); 5456 ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored7); 5457 ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored8); 5458 5459 ATF_TP_ADD_TC(tp, traceme_sendsignal_simple1); 5460 ATF_TP_ADD_TC(tp, traceme_sendsignal_simple2); 5461 ATF_TP_ADD_TC(tp, traceme_sendsignal_simple3); 5462 ATF_TP_ADD_TC(tp, traceme_sendsignal_simple4); 5463 ATF_TP_ADD_TC(tp, traceme_sendsignal_simple5); 5464 ATF_TP_ADD_TC(tp, traceme_sendsignal_simple6); 5465 ATF_TP_ADD_TC(tp, traceme_sendsignal_simple7); 5466 ATF_TP_ADD_TC(tp, traceme_sendsignal_simple8); 5467 ATF_TP_ADD_TC(tp, traceme_sendsignal_simple9); 5468 ATF_TP_ADD_TC(tp, traceme_sendsignal_simple10); 5469 5470 ATF_TP_ADD_TC(tp, traceme_pid1_parent); 5471 5472 ATF_TP_ADD_TC(tp, traceme_vfork_raise1); 5473 ATF_TP_ADD_TC(tp, traceme_vfork_raise2); 5474 ATF_TP_ADD_TC(tp, traceme_vfork_raise3); 5475 ATF_TP_ADD_TC(tp, traceme_vfork_raise4); 5476 ATF_TP_ADD_TC(tp, traceme_vfork_raise5); 5477 ATF_TP_ADD_TC(tp, traceme_vfork_raise6); 5478 ATF_TP_ADD_TC(tp, traceme_vfork_raise7); 5479 ATF_TP_ADD_TC(tp, traceme_vfork_raise8); 5480 ATF_TP_ADD_TC(tp, traceme_vfork_raise9); 5481 ATF_TP_ADD_TC(tp, traceme_vfork_raise10); 5482 ATF_TP_ADD_TC(tp, traceme_vfork_raise11); 5483 ATF_TP_ADD_TC(tp, traceme_vfork_raise12); 5484 ATF_TP_ADD_TC(tp, traceme_vfork_raise13); 5485 5486 ATF_TP_ADD_TC(tp, traceme_vfork_crash_trap); 5487 ATF_TP_ADD_TC(tp, traceme_vfork_crash_segv); 5488 ATF_TP_ADD_TC(tp, traceme_vfork_crash_ill); 5489 ATF_TP_ADD_TC(tp, traceme_vfork_crash_fpe); 5490 ATF_TP_ADD_TC(tp, traceme_vfork_crash_bus); 5491 5492 ATF_TP_ADD_TC(tp, traceme_vfork_exec); 5493 5494 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_sees_crash_trap); 5495 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_sees_crash_segv); 5496 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_sees_crash_ill); 5497 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_sees_crash_fpe); 5498 ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_sees_crash_bus); 5499 5500 ATF_TP_ADD_TC_HAVE_PID(tp, tracer_sees_terminaton_before_the_parent); 5501 ATF_TP_ADD_TC_HAVE_PID(tp, tracer_sysctl_lookup_without_duplicates); 5502 ATF_TP_ADD_TC_HAVE_PID(tp, 5503 unrelated_tracer_sees_terminaton_before_the_parent); 5504 ATF_TP_ADD_TC_HAVE_PID(tp, tracer_attach_to_unrelated_stopped_process); 5505 5506 ATF_TP_ADD_TC(tp, parent_attach_to_its_child); 5507 ATF_TP_ADD_TC(tp, parent_attach_to_its_stopped_child); 5508 5509 ATF_TP_ADD_TC(tp, child_attach_to_its_parent); 5510 ATF_TP_ADD_TC(tp, child_attach_to_its_stopped_parent); 5511 5512 ATF_TP_ADD_TC_HAVE_PID(tp, 5513 tracee_sees_its_original_parent_getppid); 5514 ATF_TP_ADD_TC_HAVE_PID(tp, 5515 tracee_sees_its_original_parent_sysctl_kinfo_proc2); 5516 ATF_TP_ADD_TC_HAVE_PID(tp, 5517 tracee_sees_its_original_parent_procfs_status); 5518 5519 ATF_TP_ADD_TC(tp, eventmask_preserved_empty); 5520 ATF_TP_ADD_TC(tp, eventmask_preserved_fork); 5521 ATF_TP_ADD_TC(tp, eventmask_preserved_vfork); 5522 ATF_TP_ADD_TC(tp, eventmask_preserved_vfork_done); 5523 ATF_TP_ADD_TC(tp, eventmask_preserved_lwp_create); 5524 ATF_TP_ADD_TC(tp, eventmask_preserved_lwp_exit); 5525 5526 ATF_TP_ADD_TC(tp, fork1); 5527 ATF_TP_ADD_TC_HAVE_PID(tp, fork2); 5528 ATF_TP_ADD_TC_HAVE_PID(tp, fork3); 5529 ATF_TP_ADD_TC_HAVE_PID(tp, fork4); 5530 ATF_TP_ADD_TC(tp, fork5); 5531 ATF_TP_ADD_TC_HAVE_PID(tp, fork6); 5532 ATF_TP_ADD_TC_HAVE_PID(tp, fork7); 5533 ATF_TP_ADD_TC_HAVE_PID(tp, fork8); 5534 5535 ATF_TP_ADD_TC(tp, vfork1); 5536 ATF_TP_ADD_TC_HAVE_PID(tp, vfork2); 5537 ATF_TP_ADD_TC_HAVE_PID(tp, vfork3); 5538 ATF_TP_ADD_TC_HAVE_PID(tp, vfork4); 5539 ATF_TP_ADD_TC(tp, vfork5); 5540 ATF_TP_ADD_TC_HAVE_PID(tp, vfork6); 5541// thes tests hang on SMP machines, disable them for now 5542// ATF_TP_ADD_TC_HAVE_PID(tp, vfork7); 5543// ATF_TP_ADD_TC_HAVE_PID(tp, vfork8); 5544 5545 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_8); 5546 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_16); 5547 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_32); 5548 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_64); 5549 5550 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_8); 5551 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_16); 5552 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_32); 5553 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_64); 5554 5555 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_8); 5556 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_16); 5557 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_32); 5558 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_64); 5559 5560 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_8); 5561 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_16); 5562 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_32); 5563 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_64); 5564 5565 ATF_TP_ADD_TC(tp, bytes_transfer_read_d); 5566 ATF_TP_ADD_TC(tp, bytes_transfer_read_i); 5567 ATF_TP_ADD_TC(tp, bytes_transfer_write_d); 5568 ATF_TP_ADD_TC(tp, bytes_transfer_write_i); 5569 5570 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_8_text); 5571 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_16_text); 5572 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_32_text); 5573 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_64_text); 5574 5575 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_8_text); 5576 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_16_text); 5577 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_32_text); 5578 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_64_text); 5579 5580 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_8_text); 5581 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_16_text); 5582 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_32_text); 5583 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_64_text); 5584 5585 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_8_text); 5586 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_16_text); 5587 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_32_text); 5588 ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_64_text); 5589 5590 ATF_TP_ADD_TC(tp, bytes_transfer_read_d_text); 5591 ATF_TP_ADD_TC(tp, bytes_transfer_read_i_text); 5592 ATF_TP_ADD_TC(tp, bytes_transfer_write_d_text); 5593 ATF_TP_ADD_TC(tp, bytes_transfer_write_i_text); 5594 5595 ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_auxv); 5596 5597 ATF_TP_ADD_TC_HAVE_GPREGS(tp, access_regs1); 5598 ATF_TP_ADD_TC_HAVE_GPREGS(tp, access_regs2); 5599 ATF_TP_ADD_TC_HAVE_GPREGS(tp, access_regs3); 5600 ATF_TP_ADD_TC_HAVE_GPREGS(tp, access_regs4); 5601 ATF_TP_ADD_TC_HAVE_GPREGS(tp, access_regs5); 5602 ATF_TP_ADD_TC_HAVE_GPREGS(tp, access_regs6); 5603 5604 ATF_TP_ADD_TC_HAVE_FPREGS(tp, access_fpregs1); 5605 ATF_TP_ADD_TC_HAVE_FPREGS(tp, access_fpregs2); 5606 5607 ATF_TP_ADD_TC_PT_STEP(tp, step1); 5608 ATF_TP_ADD_TC_PT_STEP(tp, step2); 5609 ATF_TP_ADD_TC_PT_STEP(tp, step3); 5610 ATF_TP_ADD_TC_PT_STEP(tp, step4); 5611 5612 ATF_TP_ADD_TC_PT_STEP(tp, setstep1); 5613 ATF_TP_ADD_TC_PT_STEP(tp, setstep2); 5614 ATF_TP_ADD_TC_PT_STEP(tp, setstep3); 5615 ATF_TP_ADD_TC_PT_STEP(tp, setstep4); 5616 5617 ATF_TP_ADD_TC(tp, kill1); 5618 ATF_TP_ADD_TC(tp, kill2); 5619 ATF_TP_ADD_TC(tp, kill3); 5620 5621 ATF_TP_ADD_TC(tp, traceme_lwpinfo0); 5622 ATF_TP_ADD_TC(tp, traceme_lwpinfo1); 5623 ATF_TP_ADD_TC(tp, traceme_lwpinfo2); 5624 ATF_TP_ADD_TC(tp, traceme_lwpinfo3); 5625 5626 ATF_TP_ADD_TC_HAVE_PID(tp, attach_lwpinfo0); 5627 ATF_TP_ADD_TC_HAVE_PID(tp, attach_lwpinfo1); 5628 ATF_TP_ADD_TC_HAVE_PID(tp, attach_lwpinfo2); 5629 ATF_TP_ADD_TC_HAVE_PID(tp, attach_lwpinfo3); 5630 5631 ATF_TP_ADD_TC(tp, siginfo_set_unmodified); 5632 ATF_TP_ADD_TC(tp, siginfo_set_faked); 5633 5634 ATF_TP_ADD_TC(tp, traceme_exec); 5635 5636 ATF_TP_ADD_TC(tp, trace_thread1); 5637 ATF_TP_ADD_TC(tp, trace_thread2); 5638 ATF_TP_ADD_TC(tp, trace_thread3); 5639 ATF_TP_ADD_TC(tp, trace_thread4); 5640 5641 ATF_TP_ADD_TC(tp, signal_mask_unrelated); 5642 5643 ATF_TP_ADD_TC(tp, signal3); 5644 ATF_TP_ADD_TC_PT_STEP(tp, signal4); 5645 ATF_TP_ADD_TC(tp, signal5); 5646 ATF_TP_ADD_TC_HAVE_PID(tp, signal6); 5647 ATF_TP_ADD_TC_HAVE_PID(tp, signal7); 5648 ATF_TP_ADD_TC(tp, signal8); 5649 ATF_TP_ADD_TC(tp, signal9); 5650 ATF_TP_ADD_TC(tp, signal10); 5651 5652 ATF_TP_ADD_TC(tp, suspend1); 5653 ATF_TP_ADD_TC(tp, suspend2); 5654 5655 ATF_TP_ADD_TC(tp, resume1); 5656 5657 ATF_TP_ADD_TC(tp, syscall1); 5658 5659 ATF_TP_ADD_TC(tp, syscallemu1); 5660 5661 ATF_TP_ADD_TCS_PTRACE_WAIT_AMD64(); 5662 ATF_TP_ADD_TCS_PTRACE_WAIT_I386(); 5663 ATF_TP_ADD_TCS_PTRACE_WAIT_X86(); 5664 5665 return atf_no_error(); 5666} 5667