Index: lib/libc/sys/procctl.2 =================================================================== --- lib/libc/sys/procctl.2 +++ lib/libc/sys/procctl.2 @@ -454,6 +454,16 @@ .Va si_code member is set to .Dv TRAP_CAP . +The system call number is stored in the +.Va si_syscall +field of the +.Fa siginfo +signal handler parameter. +The other system call parameters can be read from the +.Fa ucontext_t +but the system call number is typically stored in the register +that also contains the return value and so is unavailable in the +signal handler. .Pp See .Xr capsicum 4 Index: sys/amd64/amd64/trap.c =================================================================== --- sys/amd64/amd64/trap.c +++ sys/amd64/amd64/trap.c @@ -1030,6 +1030,7 @@ sa = &td->td_sa; sa->code = frame->tf_rax; + sa->original_code = sa->code; if (__predict_false(sa->code == SYS_syscall || sa->code == SYS___syscall || Index: sys/amd64/cloudabi32/cloudabi32_sysvec.c =================================================================== --- sys/amd64/cloudabi32/cloudabi32_sysvec.c +++ sys/amd64/cloudabi32/cloudabi32_sysvec.c @@ -101,6 +101,7 @@ /* Obtain system call number. */ sa->code = frame->tf_rax; + sa->original_code = sa->code; if (sa->code >= CLOUDABI32_SYS_MAXSYSCALL) return (ENOSYS); sa->callp = &cloudabi32_sysent[sa->code]; Index: sys/amd64/cloudabi64/cloudabi64_sysvec.c =================================================================== --- sys/amd64/cloudabi64/cloudabi64_sysvec.c +++ sys/amd64/cloudabi64/cloudabi64_sysvec.c @@ -98,6 +98,7 @@ /* Obtain system call number. */ sa->code = frame->tf_rax; + sa->original_code = sa->code; if (sa->code >= CLOUDABI64_SYS_MAXSYSCALL) return (ENOSYS); sa->callp = &cloudabi64_sysent[sa->code]; Index: sys/amd64/ia32/ia32_syscall.c =================================================================== --- sys/amd64/ia32/ia32_syscall.c +++ sys/amd64/ia32/ia32_syscall.c @@ -150,6 +150,7 @@ params = (caddr_t)frame->tf_rsp + sizeof(u_int32_t); sa->code = frame->tf_rax; + sa->original_code = sa->code; /* * Need to check if this is a 32 bit or 64 bit syscall. Index: sys/amd64/include/proc.h =================================================================== --- sys/amd64/include/proc.h +++ sys/amd64/include/proc.h @@ -91,6 +91,7 @@ #define KINFO_PROC32_SIZE 768 struct syscall_args { + u_int original_code; u_int code; struct sysent *callp; register_t args[8]; Index: sys/amd64/linux/linux_sysvec.c =================================================================== --- sys/amd64/linux/linux_sysvec.c +++ sys/amd64/linux/linux_sysvec.c @@ -192,6 +192,7 @@ sa->args[4] = frame->tf_r8; sa->args[5] = frame->tf_r9; sa->code = frame->tf_rax; + sa->original_code = sa->code; if (sa->code >= p->p_sysent->sv_size) /* nosys */ Index: sys/amd64/linux32/linux32_sysvec.c =================================================================== --- sys/amd64/linux32/linux32_sysvec.c +++ sys/amd64/linux32/linux32_sysvec.c @@ -656,6 +656,7 @@ sa->args[4] = frame->tf_rdi; sa->args[5] = frame->tf_rbp; /* Unconfirmed */ sa->code = frame->tf_rax; + sa->original_code = sa->code; if (sa->code >= p->p_sysent->sv_size) /* nosys */ Index: sys/arm/arm/syscall.c =================================================================== --- sys/arm/arm/syscall.c +++ sys/arm/arm/syscall.c @@ -108,6 +108,7 @@ nap = 4; sa = &td->td_sa; sa->code = td->td_frame->tf_r7; + sa->original_code = sa->code; ap = &td->td_frame->tf_r0; if (sa->code == SYS_syscall) { sa->code = *ap++; Index: sys/arm/cloudabi32/cloudabi32_sysvec.c =================================================================== --- sys/arm/cloudabi32/cloudabi32_sysvec.c +++ sys/arm/cloudabi32/cloudabi32_sysvec.c @@ -78,6 +78,7 @@ /* Obtain system call number. */ sa->code = frame->tf_r12; + sa->original_code = sa->code; if (sa->code >= CLOUDABI32_SYS_MAXSYSCALL) return (ENOSYS); sa->callp = &cloudabi32_sysent[sa->code]; Index: sys/arm/include/proc.h =================================================================== --- sys/arm/include/proc.h +++ sys/arm/include/proc.h @@ -74,6 +74,7 @@ * buffer. */ struct syscall_args { + u_int original_code; u_int code; struct sysent *callp; register_t args[MAXARGS]; Index: sys/arm64/arm64/elf32_machdep.c =================================================================== --- sys/arm64/arm64/elf32_machdep.c +++ sys/arm64/arm64/elf32_machdep.c @@ -170,6 +170,7 @@ /* r7 is the syscall id */ sa->code = td->td_frame->tf_x[7]; + sa->original_code = sa->code; if (sa->code == SYS_syscall) { sa->code = *ap++; Index: sys/arm64/arm64/trap.c =================================================================== --- sys/arm64/arm64/trap.c +++ sys/arm64/arm64/trap.c @@ -132,6 +132,7 @@ dst_ap = &sa->args[0]; sa->code = td->td_frame->tf_x[8]; + sa->original_code = sa->code; if (__predict_false(sa->code == SYS_syscall || sa->code == SYS___syscall)) { sa->code = *ap++; Index: sys/arm64/cloudabi32/cloudabi32_sysvec.c =================================================================== --- sys/arm64/cloudabi32/cloudabi32_sysvec.c +++ sys/arm64/cloudabi32/cloudabi32_sysvec.c @@ -75,6 +75,7 @@ /* Obtain system call number. */ sa->code = frame->tf_x[0]; + sa->original_code = sa->code; if (sa->code >= CLOUDABI32_SYS_MAXSYSCALL) return (ENOSYS); sa->callp = &cloudabi32_sysent[sa->code]; Index: sys/arm64/cloudabi64/cloudabi64_sysvec.c =================================================================== --- sys/arm64/cloudabi64/cloudabi64_sysvec.c +++ sys/arm64/cloudabi64/cloudabi64_sysvec.c @@ -78,6 +78,7 @@ /* Obtain system call number. */ sa->code = frame->tf_x[8]; + sa->original_code = sa->code; if (sa->code >= CLOUDABI64_SYS_MAXSYSCALL) return (ENOSYS); sa->callp = &cloudabi64_sysent[sa->code]; Index: sys/arm64/include/proc.h =================================================================== --- sys/arm64/include/proc.h +++ sys/arm64/include/proc.h @@ -48,6 +48,7 @@ #define MAXARGS 8 struct syscall_args { + u_int original_code; u_int code; struct sysent *callp; register_t args[MAXARGS]; Index: sys/arm64/linux/linux_sysvec.c =================================================================== --- sys/arm64/linux/linux_sysvec.c +++ sys/arm64/linux/linux_sysvec.c @@ -124,6 +124,7 @@ sa = &td->td_sa; sa->code = td->td_frame->tf_x[8]; + sa->original_code = sa->code; /* LINUXTODO: generic syscall? */ if (sa->code >= p->p_sysent->sv_size) sa->callp = &p->p_sysent->sv_table[0]; Index: sys/i386/cloudabi32/cloudabi32_sysvec.c =================================================================== --- sys/i386/cloudabi32/cloudabi32_sysvec.c +++ sys/i386/cloudabi32/cloudabi32_sysvec.c @@ -96,6 +96,7 @@ /* Obtain system call number. */ sa->code = frame->tf_eax; + sa->original_code = sa->code; if (sa->code >= CLOUDABI32_SYS_MAXSYSCALL) return (ENOSYS); sa->callp = &cloudabi32_sysent[sa->code]; Index: sys/i386/i386/trap.c =================================================================== --- sys/i386/i386/trap.c +++ sys/i386/i386/trap.c @@ -1054,6 +1054,7 @@ #endif sa->code = frame->tf_eax; + sa->original_code = sa->code; params = (caddr_t)frame->tf_esp + sizeof(uint32_t); /* Index: sys/i386/include/proc.h =================================================================== --- sys/i386/include/proc.h +++ sys/i386/include/proc.h @@ -63,6 +63,7 @@ #define KINFO_PROC_SIZE 768 struct syscall_args { + u_int original_code; u_int code; struct sysent *callp; register_t args[8]; Index: sys/i386/linux/linux_sysvec.c =================================================================== --- sys/i386/linux/linux_sysvec.c +++ sys/i386/linux/linux_sysvec.c @@ -767,6 +767,7 @@ sa = &td->td_sa; sa->code = frame->tf_eax; + sa->original_code = sa->code; sa->args[0] = frame->tf_ebx; sa->args[1] = frame->tf_ecx; sa->args[2] = frame->tf_edx; Index: sys/kern/subr_syscall.c =================================================================== --- sys/kern/subr_syscall.c +++ sys/kern/subr_syscall.c @@ -230,6 +230,7 @@ ksi.ksi_signo = SIGTRAP; ksi.ksi_errno = td->td_errno; ksi.ksi_code = TRAP_CAP; + ksi.ksi_info.si_syscall = sa->original_code; trapsignal(td, &ksi); } } Index: sys/mips/include/proc.h =================================================================== --- sys/mips/include/proc.h +++ sys/mips/include/proc.h @@ -83,6 +83,7 @@ #define MAXARGS 8 struct syscall_args { + u_int original_code; u_int code; struct sysent *callp; register_t args[MAXARGS]; Index: sys/mips/mips/trap.c =================================================================== --- sys/mips/mips/trap.c +++ sys/mips/mips/trap.c @@ -355,6 +355,7 @@ else locr0->pc += sizeof(int); sa->code = locr0->v0; + sa->original_code = sa->code; switch (sa->code) { case SYS___syscall: Index: sys/powerpc/include/proc.h =================================================================== --- sys/powerpc/include/proc.h +++ sys/powerpc/include/proc.h @@ -61,6 +61,7 @@ #define MAXARGS 8 struct syscall_args { + u_int original_code; u_int code; struct sysent *callp; register_t args[MAXARGS]; Index: sys/powerpc/powerpc/trap.c =================================================================== --- sys/powerpc/powerpc/trap.c +++ sys/powerpc/powerpc/trap.c @@ -667,6 +667,7 @@ sa = &td->td_sa; sa->code = frame->fixreg[0]; + sa->original_code = sa->code; params = (caddr_t)(frame->fixreg + FIRSTARG); n = NARGREG; Index: sys/riscv/include/proc.h =================================================================== --- sys/riscv/include/proc.h +++ sys/riscv/include/proc.h @@ -47,6 +47,7 @@ #define MAXARGS 8 struct syscall_args { + u_int original_code; u_int code; struct sysent *callp; register_t args[MAXARGS]; Index: sys/riscv/riscv/trap.c =================================================================== --- sys/riscv/riscv/trap.c +++ sys/riscv/riscv/trap.c @@ -105,6 +105,7 @@ dst_ap = &sa->args[0]; sa->code = td->td_frame->tf_t[0]; + sa->original_code = sa->code; if (__predict_false(sa->code == SYS_syscall || sa->code == SYS___syscall)) { sa->code = *ap++; Index: sys/sys/signal.h =================================================================== --- sys/sys/signal.h +++ sys/sys/signal.h @@ -255,6 +255,12 @@ struct { long _band; /* band event for SIGPOLL */ } _poll; /* was this ever used ? */ + struct { + int _syscall; /* Syscall number for signals + * delivered as a result of + * system calls blocked by + * Capsicum. */ + } _capsicum; struct { long __spare1__; int __spare2__[7]; @@ -267,6 +273,7 @@ #define si_overrun _reason._timer._overrun #define si_mqd _reason._mesgq._mqd #define si_band _reason._poll._band +#define si_syscall _reason._capsicum._syscall #if defined(_WANT_LWPINFO32) || (defined(_KERNEL) && defined(__LP64__)) struct siginfo32 {