43#include "opt_capsicum.h"
44#include "opt_ktrace.h"
48#include <sys/capsicum.h>
50#include <sys/vmmeter.h>
53#include <sys/ktrace.h>
55#include <security/audit/audit.h>
61 struct syscall_args *sa;
66 VM_CNT_INC(v_syscall);
71 if (__predict_false(td->td_cowgen != atomic_load_int(&p->p_cowgen)))
73 traced = (p->p_flag & P_TRACED) != 0;
74 if (__predict_false(traced || td->td_dbgflags & TDB_USERWR)) {
76 td->td_dbgflags &= ~TDB_USERWR;
78 td->td_dbgflags |= TDB_SCE;
81 error = (p->p_sysent->sv_fetch_syscall_args)(td);
84 if (KTRPOINT(td, KTR_SYSCALL))
85 ktrsyscall(sa->code, se->sy_narg, sa->args);
87 KTR_START4(KTR_SYSC,
"syscall",
syscallname(p, sa->code),
88 (uintptr_t)td,
"pid:%d", td->td_proc->p_pid,
"arg0:%p", sa->args[0],
89 "arg1:%p", sa->args[1],
"arg2:%p", sa->args[2]);
91 if (__predict_false(error != 0)) {
96 if (__predict_false(traced)) {
98 if (p->p_ptevents & PTRACE_SCE)
102 if ((td->td_dbgflags & TDB_USERWR) != 0) {
107 error = (p->p_sysent->sv_fetch_syscall_args)(td);
110 if (KTRPOINT(td, KTR_SYSCALL))
111 ktrsyscall(sa->code, se->sy_narg, sa->args);
114 td->td_errno = error;
120#ifdef CAPABILITY_MODE
125 if (__predict_false(IN_CAPABILITY_MODE(td) &&
126 (se->sy_flags & SYF_CAPENABLED) == 0)) {
127 td->td_errno = error = ECAPMODE;
140 KASSERT((td->td_pflags & TDP_NERRNO) == 0,
141 (
"%s: TDP_NERRNO set", __func__));
143 sy_thr_static = (se->sy_thrcnt & SY_THR_STATIC) != 0;
145 if (__predict_false(SYSTRACE_ENABLED() ||
146 AUDIT_SYSCALL_ENTER(sa->code, td) ||
148 if (!sy_thr_static) {
151 td->td_errno = error;
158 if (__predict_false(se->sy_entry != 0))
159 (*systrace_probe_func)(sa, SYSTRACE_ENTRY, 0);
161 error = (se->sy_call)(td, sa->args);
163 if (__predict_false((td->td_pflags & TDP_NERRNO) != 0))
164 td->td_pflags &= ~TDP_NERRNO;
166 td->td_errno = error;
177 AUDIT_SYSCALL_EXIT(error, td);
181 if (__predict_false(se->sy_return != 0))
182 (*systrace_probe_func)(sa, SYSTRACE_RETURN,
183 error ? -1 : td->td_retval[0]);
189 error = (se->sy_call)(td, sa->args);
191 if (__predict_false((td->td_pflags & TDP_NERRNO) != 0))
192 td->td_pflags &= ~TDP_NERRNO;
194 td->td_errno = error;
198 KTR_STOP4(KTR_SYSC,
"syscall",
syscallname(p, sa->code),
199 (uintptr_t)td,
"pid:%d", td->td_proc->p_pid,
"error:%d", error,
200 "retval0:%#lx", td->td_retval[0],
"retval1:%#lx",
202 if (__predict_false(traced)) {
204 td->td_dbgflags &= ~TDB_SCE;
207 (p->p_sysent->sv_set_syscall_retval)(td, error);
214 struct syscall_args *sa;
218 KASSERT(td->td_errno != ERELOOKUP,
219 (
"ERELOOKUP not consumed syscall %d", td->td_sa.code));
223 if (__predict_false(td->td_errno == ENOTCAPABLE ||
224 td->td_errno == ECAPMODE)) {
226 (p->p_flag2 & P2_TRAPCAP) != 0) && IN_CAPABILITY_MODE(td)) {
227 ksiginfo_init_trap(&ksi);
228 ksi.ksi_signo = SIGTRAP;
229 ksi.ksi_errno = td->td_errno;
230 ksi.ksi_code = TRAP_CAP;
231 ksi.ksi_info.si_syscall = sa->original_code;
242 if (KTRPOINT(td, KTR_SYSRET)) {
243 ktrsysret(sa->code, td->td_errno, td->td_retval[0]);
248 if (__predict_false(p->p_flag & P_TRACED)) {
251 td->td_dbgflags |= TDB_SCX;
254 if (__predict_false(traced ||
255 (td->td_dbgflags & (TDB_EXEC | TDB_FORK)) != 0)) {
270 if (traced && (td->td_dbgflags & TDB_EXEC) != 0 &&
271 SV_PROC_ABI(p->p_pptr) == SV_ABI_LINUX) {
273 td->td_dbgflags &= ~TDB_EXEC;
282 ((td->td_dbgflags & (TDB_FORK | TDB_EXEC)) != 0 ||
283 (p->p_ptevents & PTRACE_SCX) != 0))
285 td->td_dbgflags &= ~(TDB_SCX | TDB_EXEC | TDB_FORK);
void sigfastblock_fetch(struct thread *td)
void trapsignal(struct thread *td, ksiginfo_t *ksi)
__read_frequently bool sigfastblock_fetch_always
int ptracestop(struct thread *td, int sig, ksiginfo_t *si)
void syscall_thread_exit(struct thread *td, struct sysent *se)
int syscall_thread_enter(struct thread *td, struct sysent *se)
void thread_cow_update(struct thread *td)
static void syscallenter(struct thread *td)
static void syscallret(struct thread *td)
void userret(struct thread *td, struct trapframe *frame)
const char * syscallname(struct proc *p, u_int code)
bool __read_frequently trap_enotcap