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