t_ptrace_wait.c revision 1.190
11.190Skamil/* $NetBSD: t_ptrace_wait.c,v 1.190 2020/05/05 01:24:29 kamil Exp $ */ 21.1Skamil 31.1Skamil/*- 41.181Skamil * Copyright (c) 2016, 2017, 2018, 2019, 2020 The NetBSD Foundation, Inc. 51.1Skamil * All rights reserved. 61.1Skamil * 71.1Skamil * Redistribution and use in source and binary forms, with or without 81.1Skamil * modification, are permitted provided that the following conditions 91.1Skamil * are met: 101.1Skamil * 1. Redistributions of source code must retain the above copyright 111.1Skamil * notice, this list of conditions and the following disclaimer. 121.1Skamil * 2. Redistributions in binary form must reproduce the above copyright 131.1Skamil * notice, this list of conditions and the following disclaimer in the 141.1Skamil * documentation and/or other materials provided with the distribution. 151.1Skamil * 161.1Skamil * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 171.1Skamil * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 181.1Skamil * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 191.1Skamil * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 201.1Skamil * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 211.1Skamil * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 221.1Skamil * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 231.1Skamil * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 241.1Skamil * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 251.1Skamil * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 261.1Skamil * POSSIBILITY OF SUCH DAMAGE. 271.1Skamil */ 281.1Skamil 291.1Skamil#include <sys/cdefs.h> 301.190Skamil__RCSID("$NetBSD: t_ptrace_wait.c,v 1.190 2020/05/05 01:24:29 kamil Exp $"); 311.143Skamil 321.143Skamil#define __LEGACY_PT_LWPINFO 331.1Skamil 341.1Skamil#include <sys/param.h> 351.1Skamil#include <sys/types.h> 361.130Smgorny#include <sys/exec_elf.h> 371.39Skamil#include <sys/mman.h> 381.1Skamil#include <sys/ptrace.h> 391.1Skamil#include <sys/resource.h> 401.1Skamil#include <sys/stat.h> 411.1Skamil#include <sys/syscall.h> 421.1Skamil#include <sys/sysctl.h> 431.129Smgorny#include <sys/uio.h> 441.1Skamil#include <sys/wait.h> 451.1Skamil#include <machine/reg.h> 461.132Skamil#include <assert.h> 471.1Skamil#include <elf.h> 481.1Skamil#include <err.h> 491.1Skamil#include <errno.h> 501.130Smgorny#include <fcntl.h> 511.1Skamil#include <lwp.h> 521.77Skamil#include <pthread.h> 531.1Skamil#include <sched.h> 541.1Skamil#include <signal.h> 551.124Skamil#include <spawn.h> 561.1Skamil#include <stdint.h> 571.1Skamil#include <stdio.h> 581.1Skamil#include <stdlib.h> 591.1Skamil#include <strings.h> 601.26Skamil#include <time.h> 611.1Skamil#include <unistd.h> 621.1Skamil 631.121Smgorny#if defined(__i386__) || defined(__x86_64__) 641.121Smgorny#include <cpuid.h> 651.121Smgorny#include <x86/cpu_extended_state.h> 661.129Smgorny#include <x86/specialreg.h> 671.121Smgorny#endif 681.121Smgorny 691.130Smgorny#include <libelf.h> 701.130Smgorny#include <gelf.h> 711.130Smgorny 721.1Skamil#include <atf-c.h> 731.1Skamil 741.165Skamil#ifdef ENABLE_TESTS 751.165Skamil 761.132Skamil/* Assumptions in the kernel code that must be kept. */ 771.171Skamil__CTASSERT(sizeof(((struct ptrace_state *)0)->pe_report_event) == 781.171Skamil sizeof(((siginfo_t *)0)->si_pe_report_event)); 791.171Skamil__CTASSERT(sizeof(((struct ptrace_state *)0)->pe_other_pid) == 801.171Skamil sizeof(((siginfo_t *)0)->si_pe_other_pid)); 811.171Skamil__CTASSERT(sizeof(((struct ptrace_state *)0)->pe_lwp) == 821.171Skamil sizeof(((siginfo_t *)0)->si_pe_lwp)); 831.171Skamil__CTASSERT(sizeof(((struct ptrace_state *)0)->pe_other_pid) == 841.171Skamil sizeof(((struct ptrace_state *)0)->pe_lwp)); 851.132Skamil 861.1Skamil#include "h_macros.h" 871.1Skamil 881.1Skamil#include "t_ptrace_wait.h" 891.1Skamil#include "msg.h" 901.1Skamil 911.13Schristos#define SYSCALL_REQUIRE(expr) ATF_REQUIRE_MSG(expr, "%s: %s", # expr, \ 921.13Schristos strerror(errno)) 931.18Schristos#define SYSCALL_REQUIRE_ERRNO(res, exp) ATF_REQUIRE_MSG(res == exp, \ 941.18Schristos "%d(%s) != %d", res, strerror(res), exp) 951.13Schristos 961.152Skamilstatic int debug = 0; 971.13Schristos 981.13Schristos#define DPRINTF(a, ...) do \ 991.123Skamil if (debug) \ 1001.142Skamil printf("%s() %d.%d %s:%d " a, \ 1011.142Skamil __func__, getpid(), _lwp_self(), __FILE__, __LINE__, ##__VA_ARGS__); \ 1021.13Schristos while (/*CONSTCOND*/0) 1031.1Skamil 1041.34Skamil/// ---------------------------------------------------------------------------- 1051.34Skamil 1061.83Skamilstatic void 1071.122Skamiluser_va0_disable(int operation) 1081.122Skamil{ 1091.122Skamil pid_t child, wpid; 1101.122Skamil#if defined(TWAIT_HAVE_STATUS) 1111.122Skamil int status; 1121.122Skamil#endif 1131.122Skamil const int sigval = SIGSTOP; 1141.122Skamil int rv; 1151.122Skamil 1161.122Skamil struct ptrace_siginfo info; 1171.122Skamil 1181.122Skamil if (get_user_va0_disable() == 0) 1191.122Skamil atf_tc_skip("vm.user_va0_disable is set to 0"); 1201.122Skamil 1211.122Skamil memset(&info, 0, sizeof(info)); 1221.122Skamil 1231.122Skamil DPRINTF("Before forking process PID=%d\n", getpid()); 1241.122Skamil SYSCALL_REQUIRE((child = fork()) != -1); 1251.122Skamil if (child == 0) { 1261.122Skamil DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 1271.122Skamil FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 1281.122Skamil 1291.122Skamil DPRINTF("Before raising %s from child\n", strsignal(sigval)); 1301.122Skamil FORKEE_ASSERT(raise(sigval) == 0); 1311.122Skamil 1321.122Skamil /* NOTREACHED */ 1331.122Skamil FORKEE_ASSERTX(0 && "This shall not be reached"); 1341.122Skamil __unreachable(); 1351.122Skamil } 1361.122Skamil DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 1371.122Skamil 1381.122Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1391.122Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1401.122Skamil 1411.122Skamil validate_status_stopped(status, sigval); 1421.122Skamil 1431.122Skamil DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for " 1441.122Skamil "child\n"); 1451.122Skamil SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, 1461.122Skamil sizeof(info)) != -1); 1471.122Skamil 1481.122Skamil DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 1491.122Skamil DPRINTF("Signal properties: si_signo=%#x si_code=%#x " 1501.122Skamil "si_errno=%#x\n", 1511.122Skamil info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 1521.122Skamil info.psi_siginfo.si_errno); 1531.122Skamil 1541.122Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 1551.122Skamil ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); 1561.122Skamil 1571.122Skamil DPRINTF("Before resuming the child process in PC=0x0 " 1581.122Skamil "and without signal to be sent\n"); 1591.122Skamil errno = 0; 1601.122Skamil rv = ptrace(operation, child, (void *)0, 0); 1611.122Skamil ATF_REQUIRE_EQ(errno, EINVAL); 1621.122Skamil ATF_REQUIRE_EQ(rv, -1); 1631.122Skamil 1641.122Skamil SYSCALL_REQUIRE(ptrace(PT_KILL, child, NULL, 0) != -1); 1651.122Skamil 1661.122Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1671.122Skamil TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1681.122Skamil validate_status_signaled(status, SIGKILL, 0); 1691.122Skamil 1701.122Skamil DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1711.122Skamil TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 1721.122Skamil} 1731.122Skamil 1741.122Skamil#define USER_VA0_DISABLE(test, operation) \ 1751.122SkamilATF_TC(test); \ 1761.122SkamilATF_TC_HEAD(test, tc) \ 1771.122Skamil{ \ 1781.122Skamil atf_tc_set_md_var(tc, "descr", \ 1791.122Skamil "Verify behavior of " #operation " with PC set to 0x0"); \ 1801.122Skamil} \ 1811.122Skamil \ 1821.122SkamilATF_TC_BODY(test, tc) \ 1831.122Skamil{ \ 1841.122Skamil \ 1851.122Skamil user_va0_disable(operation); \ 1861.122Skamil} 1871.122Skamil 1881.122SkamilUSER_VA0_DISABLE(user_va0_disable_pt_continue, PT_CONTINUE) 1891.122SkamilUSER_VA0_DISABLE(user_va0_disable_pt_syscall, PT_SYSCALL) 1901.122SkamilUSER_VA0_DISABLE(user_va0_disable_pt_detach, PT_DETACH) 1911.122Skamil 1921.122Skamil/// ---------------------------------------------------------------------------- 1931.122Skamil 1941.174Skamil#include "t_ptrace_register_wait.h" 1951.175Skamil#include "t_ptrace_syscall_wait.h" 1961.176Skamil#include "t_ptrace_step_wait.h" 1971.177Skamil#include "t_ptrace_kill_wait.h" 1981.178Skamil#include "t_ptrace_bytetransfer_wait.h" 1991.179Skamil#include "t_ptrace_clone_wait.h" 2001.180Skamil#include "t_ptrace_fork_wait.h" 2011.181Skamil#include "t_ptrace_signal_wait.h" 2021.183Skamil#include "t_ptrace_eventmask_wait.h" 2031.185Skamil#include "t_ptrace_lwp_wait.h" 2041.186Skamil#include "t_ptrace_exec_wait.h" 2051.187Skamil#include "t_ptrace_topology_wait.h" 2061.188Skamil#include "t_ptrace_threads_wait.h" 2071.189Skamil#include "t_ptrace_siginfo_wait.h" 2081.190Skamil#include "t_ptrace_core_wait.h" 2091.174Skamil 2101.174Skamil/// ---------------------------------------------------------------------------- 2111.174Skamil 2121.1Skamil#include "t_ptrace_amd64_wait.h" 2131.1Skamil#include "t_ptrace_i386_wait.h" 2141.1Skamil#include "t_ptrace_x86_wait.h" 2151.1Skamil 2161.165Skamil/// ---------------------------------------------------------------------------- 2171.165Skamil 2181.165Skamil#else 2191.165SkamilATF_TC(dummy); 2201.165SkamilATF_TC_HEAD(dummy, tc) 2211.165Skamil{ 2221.165Skamil atf_tc_set_md_var(tc, "descr", "A dummy test"); 2231.165Skamil} 2241.165Skamil 2251.165SkamilATF_TC_BODY(dummy, tc) 2261.165Skamil{ 2271.165Skamil 2281.165Skamil // Dummy, skipped 2291.165Skamil // The ATF framework requires at least a single defined test. 2301.165Skamil} 2311.165Skamil#endif 2321.165Skamil 2331.1SkamilATF_TP_ADD_TCS(tp) 2341.1Skamil{ 2351.1Skamil setvbuf(stdout, NULL, _IONBF, 0); 2361.1Skamil setvbuf(stderr, NULL, _IONBF, 0); 2371.33Skamil 2381.165Skamil#ifdef ENABLE_TESTS 2391.122Skamil ATF_TP_ADD_TC(tp, user_va0_disable_pt_continue); 2401.122Skamil ATF_TP_ADD_TC(tp, user_va0_disable_pt_syscall); 2411.122Skamil ATF_TP_ADD_TC(tp, user_va0_disable_pt_detach); 2421.122Skamil 2431.174Skamil ATF_TP_ADD_TCS_PTRACE_WAIT_REGISTER(); 2441.175Skamil ATF_TP_ADD_TCS_PTRACE_WAIT_SYSCALL(); 2451.176Skamil ATF_TP_ADD_TCS_PTRACE_WAIT_STEP(); 2461.177Skamil ATF_TP_ADD_TCS_PTRACE_WAIT_KILL(); 2471.178Skamil ATF_TP_ADD_TCS_PTRACE_WAIT_BYTETRANSFER(); 2481.179Skamil ATF_TP_ADD_TCS_PTRACE_WAIT_CLONE(); 2491.180Skamil ATF_TP_ADD_TCS_PTRACE_WAIT_FORK(); 2501.181Skamil ATF_TP_ADD_TCS_PTRACE_WAIT_SIGNAL(); 2511.183Skamil ATF_TP_ADD_TCS_PTRACE_WAIT_EVENTMASK(); 2521.185Skamil ATF_TP_ADD_TCS_PTRACE_WAIT_LWP(); 2531.186Skamil ATF_TP_ADD_TCS_PTRACE_WAIT_EXEC(); 2541.187Skamil ATF_TP_ADD_TCS_PTRACE_WAIT_TOPOLOGY(); 2551.188Skamil ATF_TP_ADD_TCS_PTRACE_WAIT_THREADS(); 2561.189Skamil ATF_TP_ADD_TCS_PTRACE_WAIT_SIGINFO(); 2571.190Skamil ATF_TP_ADD_TCS_PTRACE_WAIT_CORE(); 2581.174Skamil 2591.1Skamil ATF_TP_ADD_TCS_PTRACE_WAIT_AMD64(); 2601.1Skamil ATF_TP_ADD_TCS_PTRACE_WAIT_I386(); 2611.1Skamil ATF_TP_ADD_TCS_PTRACE_WAIT_X86(); 2621.1Skamil 2631.165Skamil#else 2641.165Skamil ATF_TP_ADD_TC(tp, dummy); 2651.165Skamil#endif 2661.165Skamil 2671.1Skamil return atf_no_error(); 2681.1Skamil} 269