git: fa92eaede40b - stable/14 - ktrace: Record syscall violations with KTR_CAPFAIL

From: Jake Freeland <jfree_at_FreeBSD.org>
Date: Sun, 12 May 2024 00:08:28 UTC
The branch stable/14 has been updated by jfree:

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

commit fa92eaede40bce557c44e4f1b599cd6e443607b5
Author:     Jake Freeland <jfree@FreeBSD.org>
AuthorDate: 2024-04-06 18:31:18 +0000
Commit:     Jake Freeland <jfree@FreeBSD.org>
CommitDate: 2024-05-11 23:57:44 +0000

    ktrace: Record syscall violations with KTR_CAPFAIL
    
    Report syscalls that are not allowed in capability mode with
    CAPFAIL_SYSCALL.
    
    Reviewed by:    markj
    Approved by:    markj (mentor)
    MFC after:      1 month
    Differential Revision:  https://reviews.freebsd.org/D40678
    
    (cherry picked from commit 05296a0ff615566d25c77c5e6619b08724d2eecb)
---
 sys/amd64/amd64/sys_machdep.c | 52 +++++++++++++++++++++----------------------
 sys/arm/arm/sys_machdep.c     | 27 ++++++++++------------
 sys/i386/i386/sys_machdep.c   | 34 +++++++++++++---------------
 sys/kern/kern_descrip.c       |  2 ++
 sys/kern/kern_sig.c           | 12 +++++++---
 sys/kern/subr_syscall.c       | 11 +++++----
 6 files changed, 71 insertions(+), 67 deletions(-)

diff --git a/sys/amd64/amd64/sys_machdep.c b/sys/amd64/amd64/sys_machdep.c
index 6f8d6feaf60b..6c8b038bdb09 100644
--- a/sys/amd64/amd64/sys_machdep.c
+++ b/sys/amd64/amd64/sys_machdep.c
@@ -189,35 +189,33 @@ sysarch(struct thread *td, struct sysarch_args *uap)
 	 * explicitly indicate whether or not the operation is safe to
 	 * perform in capability mode.
 	 */
-	if (IN_CAPABILITY_MODE(td)) {
-		switch (uap->op) {
-		case I386_GET_LDT:
-		case I386_SET_LDT:
-		case I386_GET_IOPERM:
-		case I386_GET_FSBASE:
-		case I386_SET_FSBASE:
-		case I386_GET_GSBASE:
-		case I386_SET_GSBASE:
-		case I386_GET_XFPUSTATE:
-		case I386_SET_PKRU:
-		case I386_CLEAR_PKRU:
-		case AMD64_GET_FSBASE:
-		case AMD64_SET_FSBASE:
-		case AMD64_GET_GSBASE:
-		case AMD64_SET_GSBASE:
-		case AMD64_GET_XFPUSTATE:
-		case AMD64_SET_PKRU:
-		case AMD64_CLEAR_PKRU:
-			break;
+	switch (uap->op) {
+	case I386_GET_LDT:
+	case I386_SET_LDT:
+	case I386_GET_IOPERM:
+	case I386_GET_FSBASE:
+	case I386_SET_FSBASE:
+	case I386_GET_GSBASE:
+	case I386_SET_GSBASE:
+	case I386_GET_XFPUSTATE:
+	case I386_SET_PKRU:
+	case I386_CLEAR_PKRU:
+	case AMD64_GET_FSBASE:
+	case AMD64_SET_FSBASE:
+	case AMD64_GET_GSBASE:
+	case AMD64_SET_GSBASE:
+	case AMD64_GET_XFPUSTATE:
+	case AMD64_SET_PKRU:
+	case AMD64_CLEAR_PKRU:
+		break;
 
-		case I386_SET_IOPERM:
-		default:
-#ifdef KTRACE
-			if (KTRPOINT(td, KTR_CAPFAIL))
-				ktrcapfail(CAPFAIL_SYSCALL, NULL, NULL);
-#endif
+	case I386_SET_IOPERM:
+	default:
+		if (CAP_TRACING(td))
+			ktrcapfail(CAPFAIL_SYSCALL, &uap->op);
+		if (IN_CAPABILITY_MODE(td))
 			return (ECAPMODE);
-		}
+		break;
 	}
 #endif
 
diff --git a/sys/arm/arm/sys_machdep.c b/sys/arm/arm/sys_machdep.c
index 208026db85ba..d167c757952b 100644
--- a/sys/arm/arm/sys_machdep.c
+++ b/sys/arm/arm/sys_machdep.c
@@ -177,22 +177,19 @@ sysarch(struct thread *td, struct sysarch_args *uap)
 	 * explicitly indicate whether or not the operation is safe to
 	 * perform in capability mode.
 	 */
-	if (IN_CAPABILITY_MODE(td)) {
-		switch (uap->op) {
-		case ARM_SYNC_ICACHE:
-		case ARM_DRAIN_WRITEBUF:
-		case ARM_SET_TP:
-		case ARM_GET_TP:
-		case ARM_GET_VFPSTATE:
-			break;
-
-		default:
-#ifdef KTRACE
-			if (KTRPOINT(td, KTR_CAPFAIL))
-				ktrcapfail(CAPFAIL_SYSCALL, NULL, NULL);
-#endif
+	switch (uap->op) {
+	case ARM_SYNC_ICACHE:
+	case ARM_DRAIN_WRITEBUF:
+	case ARM_SET_TP:
+	case ARM_GET_TP:
+	case ARM_GET_VFPSTATE:
+		break;
+
+	default:
+		if (CAP_TRACING(td))
+			ktrcapfail(CAPFAIL_SYSCALL, &uap->op);
+		if (IN_CAPABILITY_MODE(td))
 			return (ECAPMODE);
-		}
 	}
 #endif
 
diff --git a/sys/i386/i386/sys_machdep.c b/sys/i386/i386/sys_machdep.c
index 1634041daf2a..3a7b7c2f6c71 100644
--- a/sys/i386/i386/sys_machdep.c
+++ b/sys/i386/i386/sys_machdep.c
@@ -154,26 +154,24 @@ sysarch(struct thread *td, struct sysarch_args *uap)
 	 * explicitly indicate whether or not the operation is safe to
 	 * perform in capability mode.
 	 */
-	if (IN_CAPABILITY_MODE(td)) {
-		switch (uap->op) {
-		case I386_GET_LDT:
-		case I386_SET_LDT:
-		case I386_GET_IOPERM:
-		case I386_GET_FSBASE:
-		case I386_SET_FSBASE:
-		case I386_GET_GSBASE:
-		case I386_SET_GSBASE:
-		case I386_GET_XFPUSTATE:
-			break;
+	switch (uap->op) {
+	case I386_GET_LDT:
+	case I386_SET_LDT:
+	case I386_GET_IOPERM:
+	case I386_GET_FSBASE:
+	case I386_SET_FSBASE:
+	case I386_GET_GSBASE:
+	case I386_SET_GSBASE:
+	case I386_GET_XFPUSTATE:
+		break;
 
-		case I386_SET_IOPERM:
-		default:
-#ifdef KTRACE
-			if (KTRPOINT(td, KTR_CAPFAIL))
-				ktrcapfail(CAPFAIL_SYSCALL, NULL, NULL);
-#endif
+	case I386_SET_IOPERM:
+	default:
+		if (CAP_TRACING(td))
+			ktrcapfail(CAPFAIL_SYSCALL, &uap->op);
+		if (IN_CAPABILITY_MODE(td))
 			return (ECAPMODE);
-		}
+		break;
 	}
 #endif
 
diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c
index 30d82f74d725..b72ae27e2a0b 100644
--- a/sys/kern/kern_descrip.c
+++ b/sys/kern/kern_descrip.c
@@ -877,6 +877,8 @@ revert_f_setfl:
 
 	case F_KINFO:
 #ifdef CAPABILITY_MODE
+		if (CAP_TRACING(td))
+			ktrcapfail(CAPFAIL_SYSCALL, &cmd);
 		if (IN_CAPABILITY_MODE(td)) {
 			error = ECAPMODE;
 			break;
diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c
index 2f2ec7edfb12..b1860bf23cf2 100644
--- a/sys/kern/kern_sig.c
+++ b/sys/kern/kern_sig.c
@@ -2690,10 +2690,16 @@ ptrace_syscallreq(struct thread *td, struct proc *p,
 	    &td->td_proc->p_cowgen)))
 		thread_cow_update(td);
 
+	td->td_sa = tsr->ts_sa;
+
 #ifdef CAPABILITY_MODE
-	if (IN_CAPABILITY_MODE(td) && (se->sy_flags & SYF_CAPENABLED) == 0) {
-		tsr->ts_ret.sr_error = ECAPMODE;
-		return;
+	if ((se->sy_flags & SYF_CAPENABLED) == 0) {
+		if (CAP_TRACING(td))
+			ktrcapfail(CAPFAIL_SYSCALL, NULL);
+		if (IN_CAPABILITY_MODE(td)) {
+			tsr->ts_ret.sr_error = ECAPMODE;
+			return;
+		}
 	}
 #endif
 
diff --git a/sys/kern/subr_syscall.c b/sys/kern/subr_syscall.c
index ff13672501b2..725467e1215f 100644
--- a/sys/kern/subr_syscall.c
+++ b/sys/kern/subr_syscall.c
@@ -120,10 +120,13 @@ syscallenter(struct thread *td)
 	 * In capability mode, we only allow access to system calls
 	 * flagged with SYF_CAPENABLED.
 	 */
-	if (__predict_false(IN_CAPABILITY_MODE(td) &&
-	    (se->sy_flags & SYF_CAPENABLED) == 0)) {
-		td->td_errno = error = ECAPMODE;
-		goto retval;
+	if ((se->sy_flags & SYF_CAPENABLED) == 0) {
+		if (CAP_TRACING(td))
+			ktrcapfail(CAPFAIL_SYSCALL, NULL);
+		if (IN_CAPABILITY_MODE(td)) {
+			td->td_errno = error = ECAPMODE;
+			goto retval;
+		}
 	}
 #endif