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
This commit is contained in:
Jake Freeland 2024-04-06 13:31:18 -05:00
parent 96c8b3e509
commit 05296a0ff6
6 changed files with 70 additions and 66 deletions

View file

@ -187,35 +187,33 @@ sysarch(struct thread *td, struct sysarch_args *uap)
* explicitly indicate whether or not the operation is safe to * explicitly indicate whether or not the operation is safe to
* perform in capability mode. * perform in capability mode.
*/ */
if (IN_CAPABILITY_MODE(td)) { switch (uap->op) {
switch (uap->op) { case I386_GET_LDT:
case I386_GET_LDT: case I386_SET_LDT:
case I386_SET_LDT: case I386_GET_IOPERM:
case I386_GET_IOPERM: case I386_GET_FSBASE:
case I386_GET_FSBASE: case I386_SET_FSBASE:
case I386_SET_FSBASE: case I386_GET_GSBASE:
case I386_GET_GSBASE: case I386_SET_GSBASE:
case I386_SET_GSBASE: case I386_GET_XFPUSTATE:
case I386_GET_XFPUSTATE: case I386_SET_PKRU:
case I386_SET_PKRU: case I386_CLEAR_PKRU:
case I386_CLEAR_PKRU: case AMD64_GET_FSBASE:
case AMD64_GET_FSBASE: case AMD64_SET_FSBASE:
case AMD64_SET_FSBASE: case AMD64_GET_GSBASE:
case AMD64_GET_GSBASE: case AMD64_SET_GSBASE:
case AMD64_SET_GSBASE: case AMD64_GET_XFPUSTATE:
case AMD64_GET_XFPUSTATE: case AMD64_SET_PKRU:
case AMD64_SET_PKRU: case AMD64_CLEAR_PKRU:
case AMD64_CLEAR_PKRU: break;
break;
case I386_SET_IOPERM: case I386_SET_IOPERM:
default: default:
#ifdef KTRACE if (CAP_TRACING(td))
if (KTRPOINT(td, KTR_CAPFAIL)) ktrcapfail(CAPFAIL_SYSCALL, &uap->op);
ktrcapfail(CAPFAIL_SYSCALL, NULL, NULL); if (IN_CAPABILITY_MODE(td))
#endif
return (ECAPMODE); return (ECAPMODE);
} break;
} }
#endif #endif

View file

@ -175,22 +175,19 @@ sysarch(struct thread *td, struct sysarch_args *uap)
* explicitly indicate whether or not the operation is safe to * explicitly indicate whether or not the operation is safe to
* perform in capability mode. * perform in capability mode.
*/ */
if (IN_CAPABILITY_MODE(td)) { switch (uap->op) {
switch (uap->op) { case ARM_SYNC_ICACHE:
case ARM_SYNC_ICACHE: case ARM_DRAIN_WRITEBUF:
case ARM_DRAIN_WRITEBUF: case ARM_SET_TP:
case ARM_SET_TP: case ARM_GET_TP:
case ARM_GET_TP: case ARM_GET_VFPSTATE:
case ARM_GET_VFPSTATE: break;
break;
default: default:
#ifdef KTRACE if (CAP_TRACING(td))
if (KTRPOINT(td, KTR_CAPFAIL)) ktrcapfail(CAPFAIL_SYSCALL, &uap->op);
ktrcapfail(CAPFAIL_SYSCALL, NULL, NULL); if (IN_CAPABILITY_MODE(td))
#endif
return (ECAPMODE); return (ECAPMODE);
}
} }
#endif #endif

View file

@ -152,26 +152,24 @@ sysarch(struct thread *td, struct sysarch_args *uap)
* explicitly indicate whether or not the operation is safe to * explicitly indicate whether or not the operation is safe to
* perform in capability mode. * perform in capability mode.
*/ */
if (IN_CAPABILITY_MODE(td)) { switch (uap->op) {
switch (uap->op) { case I386_GET_LDT:
case I386_GET_LDT: case I386_SET_LDT:
case I386_SET_LDT: case I386_GET_IOPERM:
case I386_GET_IOPERM: case I386_GET_FSBASE:
case I386_GET_FSBASE: case I386_SET_FSBASE:
case I386_SET_FSBASE: case I386_GET_GSBASE:
case I386_GET_GSBASE: case I386_SET_GSBASE:
case I386_SET_GSBASE: case I386_GET_XFPUSTATE:
case I386_GET_XFPUSTATE: break;
break;
case I386_SET_IOPERM: case I386_SET_IOPERM:
default: default:
#ifdef KTRACE if (CAP_TRACING(td))
if (KTRPOINT(td, KTR_CAPFAIL)) ktrcapfail(CAPFAIL_SYSCALL, &uap->op);
ktrcapfail(CAPFAIL_SYSCALL, NULL, NULL); if (IN_CAPABILITY_MODE(td))
#endif
return (ECAPMODE); return (ECAPMODE);
} break;
} }
#endif #endif

View file

@ -875,6 +875,8 @@ kern_fcntl(struct thread *td, int fd, int cmd, intptr_t arg)
case F_KINFO: case F_KINFO:
#ifdef CAPABILITY_MODE #ifdef CAPABILITY_MODE
if (CAP_TRACING(td))
ktrcapfail(CAPFAIL_SYSCALL, &cmd);
if (IN_CAPABILITY_MODE(td)) { if (IN_CAPABILITY_MODE(td)) {
error = ECAPMODE; error = ECAPMODE;
break; break;

View file

@ -2677,10 +2677,16 @@ ptrace_syscallreq(struct thread *td, struct proc *p,
&td->td_proc->p_cowgen))) &td->td_proc->p_cowgen)))
thread_cow_update(td); thread_cow_update(td);
td->td_sa = tsr->ts_sa;
#ifdef CAPABILITY_MODE #ifdef CAPABILITY_MODE
if (IN_CAPABILITY_MODE(td) && (se->sy_flags & SYF_CAPENABLED) == 0) { if ((se->sy_flags & SYF_CAPENABLED) == 0) {
tsr->ts_ret.sr_error = ECAPMODE; if (CAP_TRACING(td))
return; ktrcapfail(CAPFAIL_SYSCALL, NULL);
if (IN_CAPABILITY_MODE(td)) {
tsr->ts_ret.sr_error = ECAPMODE;
return;
}
} }
#endif #endif

View file

@ -118,10 +118,13 @@ syscallenter(struct thread *td)
* In capability mode, we only allow access to system calls * In capability mode, we only allow access to system calls
* flagged with SYF_CAPENABLED. * flagged with SYF_CAPENABLED.
*/ */
if (__predict_false(IN_CAPABILITY_MODE(td) && if ((se->sy_flags & SYF_CAPENABLED) == 0) {
(se->sy_flags & SYF_CAPENABLED) == 0)) { if (CAP_TRACING(td))
td->td_errno = error = ECAPMODE; ktrcapfail(CAPFAIL_SYSCALL, NULL);
goto retval; if (IN_CAPABILITY_MODE(td)) {
td->td_errno = error = ECAPMODE;
goto retval;
}
} }
#endif #endif