From 2f7292437d0c4b7173a3298b96a0d0e6156efa5f Mon Sep 17 00:00:00 2001 From: Mateusz Guzik Date: Fri, 14 Feb 2020 13:09:41 +0000 Subject: [PATCH] Merge audit and systrace checks This further shortens the syscall routine by not having to re-check after the system call. --- sys/kern/subr_syscall.c | 43 ++++++++++++++++++++------------------ sys/security/audit/audit.h | 9 +++++--- sys/sys/sysent.h | 4 ++++ 3 files changed, 33 insertions(+), 23 deletions(-) diff --git a/sys/kern/subr_syscall.c b/sys/kern/subr_syscall.c index ddc8f8427a7d..938e577fa9fb 100644 --- a/sys/kern/subr_syscall.c +++ b/sys/kern/subr_syscall.c @@ -131,15 +131,6 @@ syscallenter(struct thread *td) goto retval; } -#ifdef KDTRACE_HOOKS - /* Give the syscall:::entry DTrace probe a chance to fire. */ - if (__predict_false(systrace_enabled && sa->callp->sy_entry != 0)) - (*systrace_probe_func)(sa, SYSTRACE_ENTRY, 0); -#endif - - /* Let system calls set td_errno directly. */ - td->td_pflags &= ~TDP_NERRNO; - /* * Fetch fast sigblock value at the time of syscall * entry because sleepqueue primitives might call @@ -147,20 +138,32 @@ syscallenter(struct thread *td) */ fetch_sigfastblock(td); - AUDIT_SYSCALL_ENTER(sa->code, td); - error = (sa->callp->sy_call)(td, sa->args); - AUDIT_SYSCALL_EXIT(error, td); - - /* Save the latest error return value. */ - if (__predict_false((td->td_pflags & TDP_NERRNO) == 0)) - td->td_errno = error; + /* Let system calls set td_errno directly. */ + td->td_pflags &= ~TDP_NERRNO; + if (__predict_false(systrace_enabled || AUDIT_SYSCALL_ENTER(sa->code, td))) { #ifdef KDTRACE_HOOKS - /* Give the syscall:::return DTrace probe a chance to fire. */ - if (__predict_false(systrace_enabled && sa->callp->sy_return != 0)) - (*systrace_probe_func)(sa, SYSTRACE_RETURN, - error ? -1 : td->td_retval[0]); + /* Give the syscall:::entry DTrace probe a chance to fire. */ + if (__predict_false(sa->callp->sy_entry != 0)) + (*systrace_probe_func)(sa, SYSTRACE_ENTRY, 0); #endif + error = (sa->callp->sy_call)(td, sa->args); + /* Save the latest error return value. */ + if (__predict_false((td->td_pflags & TDP_NERRNO) == 0)) + td->td_errno = error; + AUDIT_SYSCALL_EXIT(error, td); +#ifdef KDTRACE_HOOKS + /* Give the syscall:::return DTrace probe a chance to fire. */ + if (__predict_false(sa->callp->sy_return != 0)) + (*systrace_probe_func)(sa, SYSTRACE_RETURN, + error ? -1 : td->td_retval[0]); +#endif + } else { + error = (sa->callp->sy_call)(td, sa->args); + /* Save the latest error return value. */ + if (__predict_false((td->td_pflags & TDP_NERRNO) == 0)) + td->td_errno = error; + } syscall_thread_exit(td, sa->callp); retval: diff --git a/sys/security/audit/audit.h b/sys/security/audit/audit.h index 0a708d0972d3..a7600d5c1f90 100644 --- a/sys/security/audit/audit.h +++ b/sys/security/audit/audit.h @@ -377,11 +377,14 @@ void audit_thread_free(struct thread *td); audit_arg_vnode2((vp)); \ } while (0) -#define AUDIT_SYSCALL_ENTER(code, td) do { \ +#define AUDIT_SYSCALL_ENTER(code, td) ({ \ + bool _audit_entered = false; \ if (__predict_false(audit_syscalls_enabled)) { \ audit_syscall_enter(code, td); \ + _audit_entered = true; \ } \ -} while (0) + _audit_entered; \ +}) /* * Wrap the audit_syscall_exit() function so that it is called only when @@ -449,7 +452,7 @@ void audit_thread_free(struct thread *td); #define AUDIT_ARG_VNODE1(vp) #define AUDIT_ARG_VNODE2(vp) -#define AUDIT_SYSCALL_ENTER(code, td) +#define AUDIT_SYSCALL_ENTER(code, td) 0 #define AUDIT_SYSCALL_EXIT(error, td) #define AUDIT_SYSCLOSE(p, fd) diff --git a/sys/sys/sysent.h b/sys/sys/sysent.h index d6213defd005..76e69b52f98e 100644 --- a/sys/sys/sysent.h +++ b/sys/sys/sysent.h @@ -54,7 +54,11 @@ typedef void (*systrace_probe_func_t)(struct syscall_args *, typedef void (*systrace_args_func_t)(int, void *, uint64_t *, int *); #ifdef _KERNEL +#ifdef KDTRACE_HOOKS extern bool systrace_enabled; +#else +#define systrace_enabled 0 +#endif #endif extern systrace_probe_func_t systrace_probe_func;