audit: Fix short-circuiting in syscallenter()

syscallenter() has a slow path to handle syscall auditing and dtrace
syscall tracing.  It uses AUDIT_SYSCALL_ENTER() to check whether to take
the slow path, but this macro also has side effects: it writes the audit
log entry.  When systrace (dtrace syscall tracing) is enabled, this
would get short-circuited, and we end up not writing audit log entries.

Introduce a pure macro to check whether auditing is enabled, use it in
syscallenter() instead of AUDIT_SYSCALL_ENTER().

Approved by:	so
Security:	FreeBSD-EN-25:02.audit
Reviewed by:	kib
Reported by:	Joe Duin <jd@firexfly.com>
Fixes:		2f7292437d0c ("Merge audit and systrace checks")
MFC after:	3 days
Sponsored by:	The FreeBSD Foundation
Differential Revision:	https://reviews.freebsd.org/D48448

(cherry picked from commit f78fe930854cac6eed55859b45e0a7b5d87189d6)
(cherry picked from commit 4b9ba274d736de74676051c8f13e7d3dd536334b)
This commit is contained in:
Mark Johnston 2025-01-14 14:19:24 +00:00 committed by Franco Fichtner
parent 3717a36932
commit 26312c233e
2 changed files with 9 additions and 4 deletions

View File

@ -143,9 +143,8 @@ syscallenter(struct thread *td)
sy_thr_static = (se->sy_thrcnt & SY_THR_STATIC) != 0;
if (__predict_false(SYSTRACE_ENABLED() ||
AUDIT_SYSCALL_ENTER(sa->code, td) ||
!sy_thr_static)) {
if (__predict_false(AUDIT_SYSCALL_ENABLED() ||
SYSTRACE_ENABLED() || !sy_thr_static)) {
if (!sy_thr_static) {
error = syscall_thread_enter(td, &se);
sy_thr_static = (se->sy_thrcnt & SY_THR_STATIC) != 0;
@ -160,6 +159,9 @@ syscallenter(struct thread *td)
if (__predict_false(se->sy_entry != 0))
(*systrace_probe_func)(sa, SYSTRACE_ENTRY, 0);
#endif
AUDIT_SYSCALL_ENTER(sa->code, td);
error = (se->sy_call)(td, sa->args);
/* Save the latest error return value. */
if (__predict_false((td->td_pflags & TDP_NERRNO) != 0))

View File

@ -389,9 +389,11 @@ void audit_thread_free(struct thread *td);
audit_arg_vnode2((vp)); \
} while (0)
#define AUDIT_SYSCALL_ENABLED() audit_syscalls_enabled
#define AUDIT_SYSCALL_ENTER(code, td) ({ \
bool _audit_entered = false; \
if (__predict_false(audit_syscalls_enabled)) { \
if (audit_syscalls_enabled) { \
audit_syscall_enter(code, td); \
_audit_entered = true; \
} \
@ -468,6 +470,7 @@ void audit_thread_free(struct thread *td);
#define AUDITING_TD(td) 0
#define AUDIT_SYSCALL_ENABLED() 0
#define AUDIT_SYSCALL_ENTER(code, td) 0
#define AUDIT_SYSCALL_EXIT(error, td)