Page MenuHomeFreeBSD

D29185.diff
No OneTemporary

D29185.diff

diff --git a/lib/libc/sys/procctl.2 b/lib/libc/sys/procctl.2
--- a/lib/libc/sys/procctl.2
+++ b/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
diff --git a/share/man/man3/siginfo.3 b/share/man/man3/siginfo.3
--- a/share/man/man3/siginfo.3
+++ b/share/man/man3/siginfo.3
@@ -85,6 +85,8 @@
.It Vt int Ta Va si_mqd Ta
.Tn POSIX
message queue ID
+.It Vt int Ta Va si_syscall Ta
+system-call number for system calls blocked by Capsicum
.El
.Pp
The
diff --git a/sys/amd64/amd64/trap.c b/sys/amd64/amd64/trap.c
--- a/sys/amd64/amd64/trap.c
+++ b/sys/amd64/amd64/trap.c
@@ -1059,6 +1059,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 ||
diff --git a/sys/amd64/cloudabi32/cloudabi32_sysvec.c b/sys/amd64/cloudabi32/cloudabi32_sysvec.c
--- a/sys/amd64/cloudabi32/cloudabi32_sysvec.c
+++ b/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];
diff --git a/sys/amd64/cloudabi64/cloudabi64_sysvec.c b/sys/amd64/cloudabi64/cloudabi64_sysvec.c
--- a/sys/amd64/cloudabi64/cloudabi64_sysvec.c
+++ b/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];
diff --git a/sys/amd64/ia32/ia32_syscall.c b/sys/amd64/ia32/ia32_syscall.c
--- a/sys/amd64/ia32/ia32_syscall.c
+++ b/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.
diff --git a/sys/amd64/include/proc.h b/sys/amd64/include/proc.h
--- a/sys/amd64/include/proc.h
+++ b/sys/amd64/include/proc.h
@@ -92,6 +92,7 @@
struct syscall_args {
u_int code;
+ u_int original_code;
struct sysent *callp;
register_t args[8];
};
diff --git a/sys/amd64/linux/linux_sysvec.c b/sys/amd64/linux/linux_sysvec.c
--- a/sys/amd64/linux/linux_sysvec.c
+++ b/sys/amd64/linux/linux_sysvec.c
@@ -191,6 +191,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 */
diff --git a/sys/amd64/linux32/linux32_sysvec.c b/sys/amd64/linux32/linux32_sysvec.c
--- a/sys/amd64/linux32/linux32_sysvec.c
+++ b/sys/amd64/linux32/linux32_sysvec.c
@@ -662,6 +662,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 */
diff --git a/sys/arm/arm/syscall.c b/sys/arm/arm/syscall.c
--- a/sys/arm/arm/syscall.c
+++ b/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++;
diff --git a/sys/arm/cloudabi32/cloudabi32_sysvec.c b/sys/arm/cloudabi32/cloudabi32_sysvec.c
--- a/sys/arm/cloudabi32/cloudabi32_sysvec.c
+++ b/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];
diff --git a/sys/arm/include/proc.h b/sys/arm/include/proc.h
--- a/sys/arm/include/proc.h
+++ b/sys/arm/include/proc.h
@@ -75,6 +75,7 @@
*/
struct syscall_args {
u_int code;
+ u_int original_code;
struct sysent *callp;
register_t args[MAXARGS];
} __aligned(8);
diff --git a/sys/arm64/arm64/elf32_machdep.c b/sys/arm64/arm64/elf32_machdep.c
--- a/sys/arm64/arm64/elf32_machdep.c
+++ b/sys/arm64/arm64/elf32_machdep.c
@@ -175,6 +175,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++;
diff --git a/sys/arm64/arm64/trap.c b/sys/arm64/arm64/trap.c
--- a/sys/arm64/arm64/trap.c
+++ b/sys/arm64/arm64/trap.c
@@ -130,6 +130,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++;
diff --git a/sys/arm64/cloudabi32/cloudabi32_sysvec.c b/sys/arm64/cloudabi32/cloudabi32_sysvec.c
--- a/sys/arm64/cloudabi32/cloudabi32_sysvec.c
+++ b/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];
diff --git a/sys/arm64/cloudabi64/cloudabi64_sysvec.c b/sys/arm64/cloudabi64/cloudabi64_sysvec.c
--- a/sys/arm64/cloudabi64/cloudabi64_sysvec.c
+++ b/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];
diff --git a/sys/arm64/include/proc.h b/sys/arm64/include/proc.h
--- a/sys/arm64/include/proc.h
+++ b/sys/arm64/include/proc.h
@@ -49,6 +49,7 @@
#define MAXARGS 8
struct syscall_args {
u_int code;
+ u_int original_code;
struct sysent *callp;
register_t args[MAXARGS];
};
diff --git a/sys/arm64/linux/linux_sysvec.c b/sys/arm64/linux/linux_sysvec.c
--- a/sys/arm64/linux/linux_sysvec.c
+++ b/sys/arm64/linux/linux_sysvec.c
@@ -125,6 +125,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];
diff --git a/sys/i386/cloudabi32/cloudabi32_sysvec.c b/sys/i386/cloudabi32/cloudabi32_sysvec.c
--- a/sys/i386/cloudabi32/cloudabi32_sysvec.c
+++ b/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];
diff --git a/sys/i386/i386/trap.c b/sys/i386/i386/trap.c
--- a/sys/i386/i386/trap.c
+++ b/sys/i386/i386/trap.c
@@ -1052,6 +1052,7 @@
#endif
sa->code = frame->tf_eax;
+ sa->original_code = sa->code;
params = (caddr_t)frame->tf_esp + sizeof(uint32_t);
/*
diff --git a/sys/i386/include/proc.h b/sys/i386/include/proc.h
--- a/sys/i386/include/proc.h
+++ b/sys/i386/include/proc.h
@@ -64,6 +64,7 @@
struct syscall_args {
u_int code;
+ u_int original_code;
struct sysent *callp;
register_t args[8];
};
diff --git a/sys/i386/linux/linux_sysvec.c b/sys/i386/linux/linux_sysvec.c
--- a/sys/i386/linux/linux_sysvec.c
+++ b/sys/i386/linux/linux_sysvec.c
@@ -756,6 +756,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;
diff --git a/sys/kern/subr_syscall.c b/sys/kern/subr_syscall.c
--- a/sys/kern/subr_syscall.c
+++ b/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);
}
}
diff --git a/sys/mips/include/proc.h b/sys/mips/include/proc.h
--- a/sys/mips/include/proc.h
+++ b/sys/mips/include/proc.h
@@ -84,6 +84,7 @@
#define MAXARGS 8
struct syscall_args {
u_int code;
+ u_int original_code;
struct sysent *callp;
register_t args[MAXARGS];
};
diff --git a/sys/mips/mips/trap.c b/sys/mips/mips/trap.c
--- a/sys/mips/mips/trap.c
+++ b/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:
diff --git a/sys/powerpc/include/proc.h b/sys/powerpc/include/proc.h
--- a/sys/powerpc/include/proc.h
+++ b/sys/powerpc/include/proc.h
@@ -62,6 +62,7 @@
#define MAXARGS 8
struct syscall_args {
u_int code;
+ u_int original_code;
struct sysent *callp;
register_t args[MAXARGS];
};
diff --git a/sys/powerpc/powerpc/trap.c b/sys/powerpc/powerpc/trap.c
--- a/sys/powerpc/powerpc/trap.c
+++ b/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;
diff --git a/sys/riscv/include/proc.h b/sys/riscv/include/proc.h
--- a/sys/riscv/include/proc.h
+++ b/sys/riscv/include/proc.h
@@ -48,6 +48,7 @@
#define MAXARGS 8
struct syscall_args {
u_int code;
+ u_int original_code;
struct sysent *callp;
register_t args[MAXARGS];
};
diff --git a/sys/riscv/riscv/trap.c b/sys/riscv/riscv/trap.c
--- a/sys/riscv/riscv/trap.c
+++ b/sys/riscv/riscv/trap.c
@@ -103,6 +103,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++;
diff --git a/sys/sys/signal.h b/sys/sys/signal.h
--- a/sys/sys/signal.h
+++ b/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 denied 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 {

File Metadata

Mime Type
text/plain
Expires
Fri, Nov 15, 1:47 PM (16 h, 42 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
14643084
Default Alt Text
D29185.diff (10 KB)

Event Timeline