diff options
author | David Chisnall <theraven@FreeBSD.org> | 2021-07-10 16:19:52 +0000 |
---|---|---|
committer | David Chisnall <theraven@FreeBSD.org> | 2021-07-10 16:19:52 +0000 |
commit | 3a522ba1bc852c3d4660a4fa32e4a94999d09a47 (patch) | |
tree | bc54f3286f7e98b8903873c8e3ece1bb8c3374b1 /sys/arm | |
parent | 476ef25d321c4eb9fffe91265a03960983332bc2 (diff) | |
download | src-3a522ba1bc852c3d4660a4fa32e4a94999d09a47.tar.gz src-3a522ba1bc852c3d4660a4fa32e4a94999d09a47.zip |
Pass the syscall number to capsicum permission-denied signals
The syscall number is stored in the same register as the syscall return
on amd64 (and possibly other architectures) and so it is impossible to
recover in the signal handler after the call has returned. This small
tweak delivers it in the `si_value` field of the signal, which is
sufficient to catch capability violations and emulate them with a call
to a more-privileged process in the signal handler.
Approved by: markj (mentor)
Reviewed by: kib, bcr (manpages)
Differential Revision: https://reviews.freebsd.org/D29185
Diffstat (limited to 'sys/arm')
-rw-r--r-- | sys/arm/arm/syscall.c | 1 | ||||
-rw-r--r-- | sys/arm/cloudabi32/cloudabi32_sysvec.c | 1 | ||||
-rw-r--r-- | sys/arm/include/proc.h | 1 |
3 files changed, 3 insertions, 0 deletions
diff --git a/sys/arm/arm/syscall.c b/sys/arm/arm/syscall.c index a851db6e4556..a635de0ec716 100644 --- a/sys/arm/arm/syscall.c +++ b/sys/arm/arm/syscall.c @@ -108,6 +108,7 @@ cpu_fetch_syscall_args(struct thread *td) 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 index a8c5da47d265..4df57b22e13d 100644 --- a/sys/arm/cloudabi32/cloudabi32_sysvec.c +++ b/sys/arm/cloudabi32/cloudabi32_sysvec.c @@ -78,6 +78,7 @@ cloudabi32_fetch_syscall_args(struct thread *td) /* 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 index a37ccd8f621c..9566c264731e 100644 --- a/sys/arm/include/proc.h +++ b/sys/arm/include/proc.h @@ -75,6 +75,7 @@ struct mdproc { */ struct syscall_args { u_int code; + u_int original_code; struct sysent *callp; register_t args[MAXARGS]; } __aligned(8); |