14Srgrimes/*- 21690Sdg * Copyright (C) 1994, David Greenman 31690Sdg * Copyright (c) 1990, 1993 41690Sdg * The Regents of the University of California. All rights reserved. 5225474Skib * Copyright (C) 2010 Konstantin Belousov <kib@freebsd.org> 64Srgrimes * 74Srgrimes * This code is derived from software contributed to Berkeley by 84Srgrimes * the University of Utah, and William Jolitz. 94Srgrimes * 104Srgrimes * Redistribution and use in source and binary forms, with or without 114Srgrimes * modification, are permitted provided that the following conditions 124Srgrimes * are met: 134Srgrimes * 1. Redistributions of source code must retain the above copyright 144Srgrimes * notice, this list of conditions and the following disclaimer. 154Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 164Srgrimes * notice, this list of conditions and the following disclaimer in the 174Srgrimes * documentation and/or other materials provided with the distribution. 184Srgrimes * 3. All advertising materials mentioning features or use of this software 194Srgrimes * must display the following acknowledgement: 204Srgrimes * This product includes software developed by the University of 214Srgrimes * California, Berkeley and its contributors. 224Srgrimes * 4. Neither the name of the University nor the names of its contributors 234Srgrimes * may be used to endorse or promote products derived from this software 244Srgrimes * without specific prior written permission. 254Srgrimes * 264Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 274Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 284Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 294Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 304Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 314Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 324Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 334Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 344Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 354Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 364Srgrimes * SUCH DAMAGE. 374Srgrimes * 38608Srgrimes * from: @(#)trap.c 7.4 (Berkeley) 5/13/91 394Srgrimes */ 404Srgrimes 41223668Sjonathan#include "opt_capsicum.h" 42118240Speter#include "opt_ktrace.h" 4313203Swollman 44225474Skib__FBSDID("$FreeBSD: stable/11/sys/kern/subr_syscall.c 331722 2018-03-29 02:50:57Z eadler $"); 45225474Skib 46263233Srwatson#include <sys/capsicum.h> 4799072Sjulian#include <sys/ktr.h> 48331017Skevans#include <sys/vmmeter.h> 49118240Speter#ifdef KTRACE 50118240Speter#include <sys/uio.h> 51118240Speter#include <sys/ktrace.h> 52118240Speter#endif 53208453Skib#include <security/audit/audit.h> 54118240Speter 55225474Skibstatic inline int 56321343Skibsyscallenter(struct thread *td) 57208453Skib{ 58208453Skib struct proc *p; 59321343Skib struct syscall_args *sa; 60208453Skib int error, traced; 61208453Skib 62208453Skib PCPU_INC(cnt.v_syscall); 63208453Skib p = td->td_proc; 64321343Skib sa = &td->td_sa; 65208453Skib 66208453Skib td->td_pticks = 0; 67284214Smjg if (td->td_cowgen != p->p_cowgen) 68284214Smjg thread_cow_update(td); 69287870Sjhb traced = (p->p_flag & P_TRACED) != 0; 70287870Sjhb if (traced || td->td_dbgflags & TDB_USERWR) { 71208453Skib PROC_LOCK(p); 72208453Skib td->td_dbgflags &= ~TDB_USERWR; 73287870Sjhb if (traced) 74287870Sjhb td->td_dbgflags |= TDB_SCE; 75208453Skib PROC_UNLOCK(p); 76287870Sjhb } 77321343Skib error = (p->p_sysent->sv_fetch_syscall_args)(td); 78208453Skib#ifdef KTRACE 79208453Skib if (KTRPOINT(td, KTR_SYSCALL)) 80208453Skib ktrsyscall(sa->code, sa->narg, sa->args); 81208453Skib#endif 82244445Sjeff KTR_START4(KTR_SYSC, "syscall", syscallname(p, sa->code), 83244765Sgonzo (uintptr_t)td, "pid:%d", td->td_proc->p_pid, "arg0:%p", sa->args[0], 84244445Sjeff "arg1:%p", sa->args[1], "arg2:%p", sa->args[2]); 85208453Skib 86244445Sjeff if (error == 0) { 87208453Skib 88208453Skib STOPEVENT(p, S_SCE, sa->narg); 89288949Sjhb if (p->p_flag & P_TRACED) { 90231521Skib PROC_LOCK(p); 91304188Sjhb if (p->p_ptevents & PTRACE_SCE) 92315949Sbadger ptracestop((td), SIGTRAP, NULL); 93231521Skib PROC_UNLOCK(p); 94231521Skib } 95208453Skib if (td->td_dbgflags & TDB_USERWR) { 96208453Skib /* 97208453Skib * Reread syscall number and arguments if 98208453Skib * debugger modified registers or memory. 99208453Skib */ 100321343Skib error = (p->p_sysent->sv_fetch_syscall_args)(td); 101208453Skib#ifdef KTRACE 102208453Skib if (KTRPOINT(td, KTR_SYSCALL)) 103208453Skib ktrsyscall(sa->code, sa->narg, sa->args); 104208453Skib#endif 105208453Skib if (error != 0) 106208453Skib goto retval; 107208453Skib } 108219133Srwatson 109223668Sjonathan#ifdef CAPABILITY_MODE 110219133Srwatson /* 111219133Srwatson * In capability mode, we only allow access to system calls 112219133Srwatson * flagged with SYF_CAPENABLED. 113219133Srwatson */ 114219133Srwatson if (IN_CAPABILITY_MODE(td) && 115219133Srwatson !(sa->callp->sy_flags & SYF_CAPENABLED)) { 116219133Srwatson error = ECAPMODE; 117219133Srwatson goto retval; 118219133Srwatson } 119219133Srwatson#endif 120219133Srwatson 121209579Skib error = syscall_thread_enter(td, sa->callp); 122209579Skib if (error != 0) 123209579Skib goto retval; 124208453Skib 125208453Skib#ifdef KDTRACE_HOOKS 126292388Smarkj /* Give the syscall:::entry DTrace probe a chance to fire. */ 127208453Skib if (systrace_probe_func != NULL && sa->callp->sy_entry != 0) 128292388Smarkj (*systrace_probe_func)(sa, SYSTRACE_ENTRY, 0); 129208453Skib#endif 130208453Skib 131208453Skib AUDIT_SYSCALL_ENTER(sa->code, td); 132208453Skib error = (sa->callp->sy_call)(td, sa->args); 133208453Skib AUDIT_SYSCALL_EXIT(error, td); 134208453Skib 135208453Skib /* Save the latest error return value. */ 136234172Skib if ((td->td_pflags & TDP_NERRNO) == 0) 137234172Skib td->td_errno = error; 138208453Skib 139208453Skib#ifdef KDTRACE_HOOKS 140292388Smarkj /* Give the syscall:::return DTrace probe a chance to fire. */ 141208453Skib if (systrace_probe_func != NULL && sa->callp->sy_return != 0) 142292388Smarkj (*systrace_probe_func)(sa, SYSTRACE_RETURN, 143292388Smarkj error ? -1 : td->td_retval[0]); 144208453Skib#endif 145209579Skib syscall_thread_exit(td, sa->callp); 146208453Skib } 147208453Skib retval: 148244445Sjeff KTR_STOP4(KTR_SYSC, "syscall", syscallname(p, sa->code), 149244765Sgonzo (uintptr_t)td, "pid:%d", td->td_proc->p_pid, "error:%d", error, 150244445Sjeff "retval0:%#lx", td->td_retval[0], "retval1:%#lx", 151244445Sjeff td->td_retval[1]); 152208453Skib if (traced) { 153208453Skib PROC_LOCK(p); 154208453Skib td->td_dbgflags &= ~TDB_SCE; 155208453Skib PROC_UNLOCK(p); 156208453Skib } 157208453Skib (p->p_sysent->sv_set_syscall_retval)(td, error); 158208453Skib return (error); 159208453Skib} 160208453Skib 161225474Skibstatic inline void 162321343Skibsyscallret(struct thread *td, int error) 163208453Skib{ 164232240Skib struct proc *p, *p2; 165321343Skib struct syscall_args *sa; 166306398Skib ksiginfo_t ksi; 167306398Skib int traced, error1; 168208453Skib 169289748Sed KASSERT((td->td_pflags & TDP_FORKING) == 0, 170289748Sed ("fork() did not clear TDP_FORKING upon completion")); 171289748Sed 172208453Skib p = td->td_proc; 173321343Skib sa = &td->td_sa; 174306398Skib if ((trap_enotcap || (p->p_flag2 & P2_TRAPCAP) != 0) && 175306398Skib IN_CAPABILITY_MODE(td)) { 176306398Skib error1 = (td->td_pflags & TDP_NERRNO) == 0 ? error : 177306398Skib td->td_errno; 178306398Skib if (error1 == ENOTCAPABLE || error1 == ECAPMODE) { 179306398Skib ksiginfo_init_trap(&ksi); 180306398Skib ksi.ksi_signo = SIGTRAP; 181306398Skib ksi.ksi_errno = error1; 182306398Skib ksi.ksi_code = TRAP_CAP; 183306398Skib trapsignal(td, &ksi); 184306398Skib } 185306398Skib } 186208453Skib 187208453Skib /* 188208453Skib * Handle reschedule and other end-of-syscall issues 189208453Skib */ 190208453Skib userret(td, td->td_frame); 191208453Skib 192208453Skib#ifdef KTRACE 193234172Skib if (KTRPOINT(td, KTR_SYSRET)) { 194234172Skib ktrsysret(sa->code, (td->td_pflags & TDP_NERRNO) == 0 ? 195234172Skib error : td->td_errno, td->td_retval[0]); 196234172Skib } 197208453Skib#endif 198234172Skib td->td_pflags &= ~TDP_NERRNO; 199208453Skib 200208453Skib if (p->p_flag & P_TRACED) { 201208453Skib traced = 1; 202208453Skib PROC_LOCK(p); 203208453Skib td->td_dbgflags |= TDB_SCX; 204208453Skib PROC_UNLOCK(p); 205208453Skib } else 206208453Skib traced = 0; 207208453Skib /* 208208453Skib * This works because errno is findable through the 209208453Skib * register set. If we ever support an emulation where this 210208453Skib * is not the case, this code will need to be revisited. 211208453Skib */ 212208453Skib STOPEVENT(p, S_SCX, sa->code); 213217819Skib if (traced || (td->td_dbgflags & (TDB_EXEC | TDB_FORK)) != 0) { 214208453Skib PROC_LOCK(p); 215225791Skib /* 216225791Skib * If tracing the execed process, trap to the debugger 217225791Skib * so that breakpoints can be set before the program 218225791Skib * executes. If debugger requested tracing of syscall 219225791Skib * returns, do it now too. 220225791Skib */ 221230785Skib if (traced && 222230785Skib ((td->td_dbgflags & (TDB_FORK | TDB_EXEC)) != 0 || 223304188Sjhb (p->p_ptevents & PTRACE_SCX) != 0)) 224315949Sbadger ptracestop(td, SIGTRAP, NULL); 225217819Skib td->td_dbgflags &= ~(TDB_SCX | TDB_EXEC | TDB_FORK); 226208453Skib PROC_UNLOCK(p); 227208453Skib } 228232240Skib 229232240Skib if (td->td_pflags & TDP_RFPPWAIT) { 230232240Skib /* 231232240Skib * Preserve synchronization semantics of vfork. If 232232240Skib * waiting for child to exec or exit, fork set 233232240Skib * P_PPWAIT on child, and there we sleep on our proc 234232240Skib * (in case of exit). 235232240Skib * 236232240Skib * Do it after the ptracestop() above is finished, to 237232240Skib * not block our debugger until child execs or exits 238232240Skib * to finish vfork wait. 239232240Skib */ 240232240Skib td->td_pflags &= ~TDP_RFPPWAIT; 241232240Skib p2 = td->td_rfppwait_p; 242275616Skibagain: 243232240Skib PROC_LOCK(p2); 244275616Skib while (p2->p_flag & P_PPWAIT) { 245275616Skib PROC_LOCK(p); 246275616Skib if (thread_suspend_check_needed()) { 247275616Skib PROC_UNLOCK(p2); 248275616Skib thread_suspend_check(0); 249275616Skib PROC_UNLOCK(p); 250275616Skib goto again; 251275616Skib } else { 252275616Skib PROC_UNLOCK(p); 253275616Skib } 254275616Skib cv_timedwait(&p2->p_pwait, &p2->p_mtx, hz); 255275616Skib } 256232240Skib PROC_UNLOCK(p2); 257304499Sjhb 258304499Sjhb if (td->td_dbgflags & TDB_VFORK) { 259304499Sjhb PROC_LOCK(p); 260304499Sjhb if (p->p_ptevents & PTRACE_VFORK) 261315949Sbadger ptracestop(td, SIGTRAP, NULL); 262304499Sjhb td->td_dbgflags &= ~TDB_VFORK; 263304499Sjhb PROC_UNLOCK(p); 264304499Sjhb } 265232240Skib } 266208453Skib} 267