Index: sys/kern/subr_syscall.c =================================================================== --- sys/kern/subr_syscall.c +++ sys/kern/subr_syscall.c @@ -165,12 +165,22 @@ syscallret(struct thread *td, int error, struct syscall_args *sa) { struct proc *p, *p2; + ksiginfo_t ksi; int traced; KASSERT((td->td_pflags & TDP_FORKING) == 0, ("fork() did not clear TDP_FORKING upon completion")); p = td->td_proc; + if (trap_enotcap && IN_CAPABILITY_MODE(td) && + ((td->td_pflags & TDP_NERRNO) == 0 ? error : td->td_errno) == + ENOTCAPABLE) { + ksiginfo_init_trap(&ksi); + ksi.ksi_signo = SIGTRAP; + ksi.ksi_errno = ENOTCAPABLE; + ksi.ksi_code = TRAP_CAP; + trapsignal(td, &ksi); + } /* * Handle reschedule and other end-of-syscall issues Index: sys/kern/sys_capability.c =================================================================== --- sys/kern/sys_capability.c +++ sys/kern/sys_capability.c @@ -83,6 +83,10 @@ #include #include +int trap_enotcap; +SYSCTL_INT(_kern, OID_AUTO, trap_enotcap, CTLFLAG_RW, &trap_enotcap, 0, + "Deliver SIGTRAP on ENOTCAPABLE"); + #ifdef CAPABILITY_MODE FEATURE(security_capability_mode, "Capsicum Capability Mode"); Index: sys/sys/capsicum.h =================================================================== --- sys/sys/capsicum.h +++ sys/sys/capsicum.h @@ -368,6 +368,8 @@ int cap_fcntl_check_fde(struct filedescent *fde, int cmd); int cap_fcntl_check(struct filedesc *fdp, int fd, int cmd); +extern int trap_enotcap; + #else /* !_KERNEL */ __BEGIN_DECLS Index: sys/sys/signal.h =================================================================== --- sys/sys/signal.h +++ sys/sys/signal.h @@ -291,6 +291,7 @@ #define TRAP_BRKPT 1 /* Process breakpoint. */ #define TRAP_TRACE 2 /* Process trace trap. */ #define TRAP_DTRACE 3 /* DTrace induced trap. */ +#define TRAP_CAP 4 /* Capabilities protective trap. */ /* codes for SIGCHLD */ #define CLD_EXITED 1 /* Child has exited */