subr_syscall.c revision 304499
1139749Simp/*- 239234Sgibbs * Copyright (C) 1994, David Greenman 339234Sgibbs * Copyright (c) 1990, 1993 439234Sgibbs * The Regents of the University of California. All rights reserved. 539234Sgibbs * Copyright (C) 2010 Konstantin Belousov <kib@freebsd.org> 639234Sgibbs * 739234Sgibbs * This code is derived from software contributed to Berkeley by 839234Sgibbs * the University of Utah, and William Jolitz. 939234Sgibbs * 1039234Sgibbs * Redistribution and use in source and binary forms, with or without 1139234Sgibbs * modification, are permitted provided that the following conditions 1239234Sgibbs * are met: 1339234Sgibbs * 1. Redistributions of source code must retain the above copyright 1439234Sgibbs * notice, this list of conditions and the following disclaimer. 1539234Sgibbs * 2. Redistributions in binary form must reproduce the above copyright 1639234Sgibbs * notice, this list of conditions and the following disclaimer in the 1739234Sgibbs * documentation and/or other materials provided with the distribution. 1839234Sgibbs * 3. All advertising materials mentioning features or use of this software 1939234Sgibbs * must display the following acknowledgement: 2039234Sgibbs * This product includes software developed by the University of 2139234Sgibbs * California, Berkeley and its contributors. 2239234Sgibbs * 4. Neither the name of the University nor the names of its contributors 2339234Sgibbs * may be used to endorse or promote products derived from this software 2439234Sgibbs * without specific prior written permission. 2539234Sgibbs * 2639234Sgibbs * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 2739234Sgibbs * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2839234Sgibbs * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 29201807Strasz * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 3039234Sgibbs * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 3139234Sgibbs * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 3239234Sgibbs * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 3339234Sgibbs * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 3439234Sgibbs * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3539234Sgibbs * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3639234Sgibbs * SUCH DAMAGE. 3739234Sgibbs * 3839234Sgibbs * from: @(#)trap.c 7.4 (Berkeley) 5/13/91 3939234Sgibbs */ 4039234Sgibbs 4139234Sgibbs#include "opt_capsicum.h" 4239234Sgibbs#include "opt_ktrace.h" 4339234Sgibbs#include "opt_kdtrace.h" 4439234Sgibbs 4539234Sgibbs__FBSDID("$FreeBSD: stable/10/sys/kern/subr_syscall.c 304499 2016-08-19 20:17:57Z jhb $"); 4639234Sgibbs 4739234Sgibbs#include <sys/capsicum.h> 4839234Sgibbs#include <sys/ktr.h> 4939234Sgibbs#ifdef KTRACE 5039234Sgibbs#include <sys/uio.h> 5139234Sgibbs#include <sys/ktrace.h> 5239234Sgibbs#endif 5339234Sgibbs#include <security/audit/audit.h> 5439234Sgibbs 5539234Sgibbsstatic inline int 5639234Sgibbssyscallenter(struct thread *td, struct syscall_args *sa) 5739234Sgibbs{ 5839234Sgibbs struct proc *p; 5939234Sgibbs int error, traced; 6039234Sgibbs 6139234Sgibbs PCPU_INC(cnt.v_syscall); 6239234Sgibbs p = td->td_proc; 6339234Sgibbs 6439234Sgibbs td->td_pticks = 0; 6539234Sgibbs if (td->td_ucred != p->p_ucred) 6639234Sgibbs cred_update_thread(td); 6739234Sgibbs traced = (p->p_flag & P_TRACED) != 0; 6839234Sgibbs if (traced || td->td_dbgflags & TDB_USERWR) { 6939234Sgibbs PROC_LOCK(p); 7039234Sgibbs td->td_dbgflags &= ~TDB_USERWR; 7139234Sgibbs if (traced) 7239234Sgibbs td->td_dbgflags |= TDB_SCE; 7339234Sgibbs PROC_UNLOCK(p); 7439234Sgibbs } 7539234Sgibbs error = (p->p_sysent->sv_fetch_syscall_args)(td, sa); 7639234Sgibbs#ifdef KTRACE 7739234Sgibbs if (KTRPOINT(td, KTR_SYSCALL)) 7839234Sgibbs ktrsyscall(sa->code, sa->narg, sa->args); 7939234Sgibbs#endif 8039234Sgibbs KTR_START4(KTR_SYSC, "syscall", syscallname(p, sa->code), 8139234Sgibbs (uintptr_t)td, "pid:%d", td->td_proc->p_pid, "arg0:%p", sa->args[0], 8239234Sgibbs "arg1:%p", sa->args[1], "arg2:%p", sa->args[2]); 8339234Sgibbs 8439234Sgibbs if (error == 0) { 8539234Sgibbs 8639234Sgibbs STOPEVENT(p, S_SCE, sa->narg); 8739234Sgibbs if (p->p_flag & P_TRACED) { 8839234Sgibbs PROC_LOCK(p); 8939234Sgibbs td->td_dbg_sc_code = sa->code; 9039515Sgibbs td->td_dbg_sc_narg = sa->narg; 9139234Sgibbs if (p->p_ptevents & PTRACE_SCE) 9239234Sgibbs ptracestop((td), SIGTRAP); 9339234Sgibbs PROC_UNLOCK(p); 9439234Sgibbs } 9539234Sgibbs if (td->td_dbgflags & TDB_USERWR) { 9639234Sgibbs /* 9739234Sgibbs * Reread syscall number and arguments if 9839234Sgibbs * debugger modified registers or memory. 9939234Sgibbs */ 10039234Sgibbs error = (p->p_sysent->sv_fetch_syscall_args)(td, sa); 10139234Sgibbs PROC_LOCK(p); 10239234Sgibbs td->td_dbg_sc_code = sa->code; 10339234Sgibbs td->td_dbg_sc_narg = sa->narg; 10439234Sgibbs PROC_UNLOCK(p); 10539234Sgibbs#ifdef KTRACE 10639234Sgibbs if (KTRPOINT(td, KTR_SYSCALL)) 10739234Sgibbs ktrsyscall(sa->code, sa->narg, sa->args); 10839234Sgibbs#endif 10939234Sgibbs if (error != 0) 11039234Sgibbs goto retval; 11139234Sgibbs } 11239234Sgibbs 11339234Sgibbs#ifdef CAPABILITY_MODE 11439234Sgibbs /* 11539234Sgibbs * In capability mode, we only allow access to system calls 11639234Sgibbs * flagged with SYF_CAPENABLED. 11739234Sgibbs */ 11839234Sgibbs if (IN_CAPABILITY_MODE(td) && 11939234Sgibbs !(sa->callp->sy_flags & SYF_CAPENABLED)) { 12039234Sgibbs error = ECAPMODE; 12139234Sgibbs goto retval; 12239234Sgibbs } 12339234Sgibbs#endif 12439234Sgibbs 12539234Sgibbs error = syscall_thread_enter(td, sa->callp); 12639234Sgibbs if (error != 0) 12739234Sgibbs goto retval; 12839234Sgibbs 12939234Sgibbs#ifdef KDTRACE_HOOKS 13039234Sgibbs /* 13139234Sgibbs * If the systrace module has registered it's probe 13239234Sgibbs * callback and if there is a probe active for the 13339234Sgibbs * syscall 'entry', process the probe. 13439234Sgibbs */ 13539234Sgibbs if (systrace_probe_func != NULL && sa->callp->sy_entry != 0) 13639234Sgibbs (*systrace_probe_func)(sa->callp->sy_entry, sa->code, 13739234Sgibbs sa->callp, sa->args, 0); 13839234Sgibbs#endif 13939234Sgibbs 14039234Sgibbs AUDIT_SYSCALL_ENTER(sa->code, td); 14139234Sgibbs error = (sa->callp->sy_call)(td, sa->args); 14239234Sgibbs AUDIT_SYSCALL_EXIT(error, td); 14339234Sgibbs 14439234Sgibbs /* Save the latest error return value. */ 145234540Sdim if ((td->td_pflags & TDP_NERRNO) == 0) 14639234Sgibbs td->td_errno = error; 14739234Sgibbs 14839234Sgibbs#ifdef KDTRACE_HOOKS 14939234Sgibbs /* 15039234Sgibbs * If the systrace module has registered it's probe 15139234Sgibbs * callback and if there is a probe active for the 15239234Sgibbs * syscall 'return', process the probe. 15339234Sgibbs */ 15439234Sgibbs if (systrace_probe_func != NULL && sa->callp->sy_return != 0) 15539234Sgibbs (*systrace_probe_func)(sa->callp->sy_return, sa->code, 15639234Sgibbs sa->callp, NULL, (error) ? -1 : td->td_retval[0]); 15739234Sgibbs#endif 15839234Sgibbs syscall_thread_exit(td, sa->callp); 15939234Sgibbs } 16039234Sgibbs retval: 16139234Sgibbs KTR_STOP4(KTR_SYSC, "syscall", syscallname(p, sa->code), 16239234Sgibbs (uintptr_t)td, "pid:%d", td->td_proc->p_pid, "error:%d", error, 16339234Sgibbs "retval0:%#lx", td->td_retval[0], "retval1:%#lx", 16439234Sgibbs td->td_retval[1]); 16539234Sgibbs if (traced) { 16639234Sgibbs PROC_LOCK(p); 16739234Sgibbs td->td_dbgflags &= ~TDB_SCE; 16839234Sgibbs PROC_UNLOCK(p); 16939234Sgibbs } 17039234Sgibbs (p->p_sysent->sv_set_syscall_retval)(td, error); 17139234Sgibbs return (error); 17239234Sgibbs} 17339234Sgibbs 17439234Sgibbsstatic inline void 17539234Sgibbssyscallret(struct thread *td, int error, struct syscall_args *sa __unused) 17639234Sgibbs{ 17739234Sgibbs struct proc *p, *p2; 17839234Sgibbs int traced; 17939234Sgibbs 18039234Sgibbs p = td->td_proc; 18139234Sgibbs 18239234Sgibbs /* 18339234Sgibbs * Handle reschedule and other end-of-syscall issues 18439234Sgibbs */ 18539234Sgibbs userret(td, td->td_frame); 18639234Sgibbs 18739234Sgibbs#ifdef KTRACE 18839234Sgibbs if (KTRPOINT(td, KTR_SYSRET)) { 18939234Sgibbs ktrsysret(sa->code, (td->td_pflags & TDP_NERRNO) == 0 ? 19039234Sgibbs error : td->td_errno, td->td_retval[0]); 19139234Sgibbs } 19239234Sgibbs#endif 19339234Sgibbs td->td_pflags &= ~TDP_NERRNO; 19439234Sgibbs 19539234Sgibbs if (p->p_flag & P_TRACED) { 19639234Sgibbs traced = 1; 19739234Sgibbs PROC_LOCK(p); 19839234Sgibbs td->td_dbgflags |= TDB_SCX; 19939234Sgibbs PROC_UNLOCK(p); 20039234Sgibbs } else 20139234Sgibbs traced = 0; 20239234Sgibbs /* 20339234Sgibbs * This works because errno is findable through the 20439234Sgibbs * register set. If we ever support an emulation where this 20539234Sgibbs * is not the case, this code will need to be revisited. 20639234Sgibbs */ 20739234Sgibbs STOPEVENT(p, S_SCX, sa->code); 20839234Sgibbs if (traced || (td->td_dbgflags & (TDB_EXEC | TDB_FORK)) != 0) { 20939234Sgibbs PROC_LOCK(p); 21039234Sgibbs /* 21139234Sgibbs * If tracing the execed process, trap to the debugger 21239234Sgibbs * so that breakpoints can be set before the program 21339234Sgibbs * executes. If debugger requested tracing of syscall 21439234Sgibbs * returns, do it now too. 21539234Sgibbs */ 21639234Sgibbs if (traced && 21739234Sgibbs ((td->td_dbgflags & (TDB_FORK | TDB_EXEC)) != 0 || 21839234Sgibbs (p->p_ptevents & PTRACE_SCX) != 0)) 21939234Sgibbs ptracestop(td, SIGTRAP); 22039234Sgibbs td->td_dbgflags &= ~(TDB_SCX | TDB_EXEC | TDB_FORK); 22139234Sgibbs PROC_UNLOCK(p); 22239234Sgibbs } 22339234Sgibbs 22489056Smsmith if (td->td_pflags & TDP_RFPPWAIT) { 22539234Sgibbs /* 22639234Sgibbs * Preserve synchronization semantics of vfork. If 22739234Sgibbs * waiting for child to exec or exit, fork set 22839234Sgibbs * P_PPWAIT on child, and there we sleep on our proc 22939234Sgibbs * (in case of exit). 23039234Sgibbs * 23139234Sgibbs * Do it after the ptracestop() above is finished, to 23239234Sgibbs * not block our debugger until child execs or exits 23339234Sgibbs * to finish vfork wait. 23439234Sgibbs */ 23539234Sgibbs td->td_pflags &= ~TDP_RFPPWAIT; 23689056Smsmith p2 = td->td_rfppwait_p; 23739234Sgibbsagain: 23839234Sgibbs PROC_LOCK(p2); 23939234Sgibbs while (p2->p_flag & P_PPWAIT) { 24039234Sgibbs PROC_LOCK(p); 24139234Sgibbs if (thread_suspend_check_needed()) { 24239234Sgibbs PROC_UNLOCK(p2); 24339234Sgibbs thread_suspend_check(0); 24439234Sgibbs PROC_UNLOCK(p); 24539234Sgibbs goto again; 24639234Sgibbs } else { 24739234Sgibbs PROC_UNLOCK(p); 24839234Sgibbs } 24939234Sgibbs cv_timedwait(&p2->p_pwait, &p2->p_mtx, hz); 25039234Sgibbs } 25139234Sgibbs PROC_UNLOCK(p2); 25239234Sgibbs 25339234Sgibbs if (td->td_dbgflags & TDB_VFORK) { 25439234Sgibbs PROC_LOCK(p); 25539234Sgibbs if (p->p_ptevents & PTRACE_VFORK) 25639234Sgibbs ptracestop(td, SIGTRAP); 25739234Sgibbs td->td_dbgflags &= ~TDB_VFORK; 25839234Sgibbs PROC_UNLOCK(p); 25939234Sgibbs } 26039234Sgibbs } 26139234Sgibbs} 26239234Sgibbs