git: f78fe930854c - main - audit: Fix short-circuiting in syscallenter()

From: Mark Johnston <markj_at_FreeBSD.org>
Date: Tue, 14 Jan 2025 15:26:16 UTC
The branch main has been updated by markj:

URL: https://cgit.FreeBSD.org/src/commit/?id=f78fe930854cac6eed55859b45e0a7b5d87189d6

commit f78fe930854cac6eed55859b45e0a7b5d87189d6
Author:     Mark Johnston <markj@FreeBSD.org>
AuthorDate: 2025-01-14 14:19:24 +0000
Commit:     Mark Johnston <markj@FreeBSD.org>
CommitDate: 2025-01-14 14:19:28 +0000

    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().
    
    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
---
 sys/kern/subr_syscall.c    | 8 +++++---
 sys/security/audit/audit.h | 5 ++++-
 2 files changed, 9 insertions(+), 4 deletions(-)

diff --git a/sys/kern/subr_syscall.c b/sys/kern/subr_syscall.c
index 22bc35774e70..16fa47c5605a 100644
--- a/sys/kern/subr_syscall.c
+++ b/sys/kern/subr_syscall.c
@@ -141,9 +141,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;
@@ -158,6 +157,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))
diff --git a/sys/security/audit/audit.h b/sys/security/audit/audit.h
index b87dd52e0773..28e84dce79f3 100644
--- a/sys/security/audit/audit.h
+++ b/sys/security/audit/audit.h
@@ -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)