From 275c821d3ddab9571c7532c68eb4007dbdea39cf Mon Sep 17 00:00:00 2001 From: Kyle Evans Date: Sat, 24 Oct 2020 14:39:17 +0000 Subject: [PATCH] audit: correct reporting of *execve(2) success r326145 corrected do_execve() to return EJUSTRETURN upon success so that important registers are not clobbered. This had the side effect of tapping out 'failures' for all *execve(2) audit records, which is less than useful for auditing purposes. Audit exec returns earlier, where we can know for sure that EJUSTRETURN translates to success. Note that this unsets TDP_AUDITREC as we commit the audit record, so the usual audit in the syscall return path will do nothing. PR: 249179 Reported by: Eirik Oeverby Reviewed by: csjp, kib MFC after: 1 week Sponsored by: Klara, Inc. Differential Revision: https://reviews.freebsd.org/D26922 --- sys/compat/freebsd32/freebsd32_misc.c | 2 ++ sys/kern/kern_exec.c | 3 +++ sys/kern/subr_syscall.c | 11 +++++++++++ 3 files changed, 16 insertions(+) diff --git a/sys/compat/freebsd32/freebsd32_misc.c b/sys/compat/freebsd32/freebsd32_misc.c index 0677fae89ff..7913f43f78a 100644 --- a/sys/compat/freebsd32/freebsd32_misc.c +++ b/sys/compat/freebsd32/freebsd32_misc.c @@ -442,6 +442,7 @@ freebsd32_execve(struct thread *td, struct freebsd32_execve_args *uap) if (error == 0) error = kern_execve(td, &eargs, NULL, oldvmspace); post_execve(td, error, oldvmspace); + AUDIT_SYSCALL_EXIT(error == EJUSTRETURN ? 0 : error, td); return (error); } @@ -462,6 +463,7 @@ freebsd32_fexecve(struct thread *td, struct freebsd32_fexecve_args *uap) error = kern_execve(td, &eargs, NULL, oldvmspace); } post_execve(td, error, oldvmspace); + AUDIT_SYSCALL_EXIT(error == EJUSTRETURN ? 0 : error, td); return (error); } diff --git a/sys/kern/kern_exec.c b/sys/kern/kern_exec.c index c6c2f058a71..d4452fe2a40 100644 --- a/sys/kern/kern_exec.c +++ b/sys/kern/kern_exec.c @@ -225,6 +225,7 @@ sys_execve(struct thread *td, struct execve_args *uap) if (error == 0) error = kern_execve(td, &args, NULL, oldvmspace); post_execve(td, error, oldvmspace); + AUDIT_SYSCALL_EXIT(error == EJUSTRETURN ? 0 : error, td); return (error); } @@ -252,6 +253,7 @@ sys_fexecve(struct thread *td, struct fexecve_args *uap) error = kern_execve(td, &args, NULL, oldvmspace); } post_execve(td, error, oldvmspace); + AUDIT_SYSCALL_EXIT(error == EJUSTRETURN ? 0 : error, td); return (error); } @@ -280,6 +282,7 @@ sys___mac_execve(struct thread *td, struct __mac_execve_args *uap) if (error == 0) error = kern_execve(td, &args, uap->mac_p, oldvmspace); post_execve(td, error, oldvmspace); + AUDIT_SYSCALL_EXIT(error == EJUSTRETURN ? 0 : error, td); return (error); #else return (ENOSYS); diff --git a/sys/kern/subr_syscall.c b/sys/kern/subr_syscall.c index 5ed9a402caa..381756b3732 100644 --- a/sys/kern/subr_syscall.c +++ b/sys/kern/subr_syscall.c @@ -154,7 +154,18 @@ syscallenter(struct thread *td) td->td_pflags &= ~TDP_NERRNO; else td->td_errno = error; + + /* + * Note that some syscall implementations (e.g., sys_execve) + * will commit the audit record just before their final return. + * These were done under the assumption that nothing of interest + * would happen between their return and here, where we would + * normally commit the audit record. These assumptions will + * need to be revisited should any substantial logic be added + * above. + */ 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))