diff options
author | Eric W. Biederman <ebiederm@xmission.com> | 2021-07-23 21:26:44 +0300 |
---|---|---|
committer | Eric W. Biederman <ebiederm@xmission.com> | 2021-07-23 21:31:52 +0300 |
commit | ee53488cc74143cadbe752d5332b1e3fd87eed49 (patch) | |
tree | ab6416ac382dc2e2d2500eb458cd0d150ac59b63 /kernel | |
parent | e73f0f0ee7541171d89f2e2491130c7771ba58d3 (diff) | |
parent | f4ac73023449e6f2f74f69e38f4840c83edfa840 (diff) | |
download | linux-ee53488cc74143cadbe752d5332b1e3fd87eed49.tar.xz |
Final si_trapno bits
As a part of a fix for the ABI of the newly added SIGTRAP TRAP_PERF a
si_trapno was reduced to an ordinary extention of the _sigfault case
of struct siginfo.
When Linus saw the complete set of changes come in as a fix he requested
that the set of changes be trimmed down to just what was necessary to
fix the SIGTRAP TRAP_PERF ABI.
I had intended to get the rest of the changes into the merge window for
v5.14 but I dropped the ball.
I have made the changes to stop using __ARCH_SI_TRAPNO be per
architecture so they are easier to review. In doing so I found one
place on alpha where I used send_sig_fault instead of
send_sig_fault_trapno(... si_trapno = 0). That would not have changed
the userspace behavior but it did make the kernel code less clear.
My rule in these patches is everywhere that siginfo layout calls
for SIL_FAULT_TRAPNO the code uses either force_sig_fault_trapno
or send_sig_fault_trapno.
And of course I have rebased and compile tested Marco's compile time
assert patches.
v1: https://lkml.kernel.org/r/m1zgxfs7zq.fsf_-_@fess.ebiederm.org
v2: https://lkml.kernel.org/r/m14kfjh8et.fsf_-_@fess.ebiederm.org
v3: https://lkml.kernel.org/r/m1tuni8ano.fsf_-_@fess.ebiederm.org
v4: https://lkml.kernel.org/r/m1a6ot5e2h.fsf_-_@fess.ebiederm.org
Link: https://lkml.kernel.org/r/87a6mnzbx2.fsf_-_@disp2133
Eric W. Biederman (5):
signal/sparc: si_trapno is only used with SIGILL ILL_ILLTRP
signal/alpha: si_trapno is only used with SIGFPE and SIGTRAP TRAP_UNK
signal: Remove the generic __ARCH_SI_TRAPNO support
signal: Verify the alignment and size of siginfo_t
signal: Rename SIL_PERF_EVENT SIL_FAULT_PERF_EVENT for consistency
Marco Elver (3):
sparc64: Add compile-time asserts for siginfo_t offsets
arm: Add compile-time asserts for siginfo_t offsets
arm64: Add compile-time asserts for siginfo_t offsets
arch/alpha/include/uapi/asm/siginfo.h | 2 --
arch/alpha/kernel/osf_sys.c | 2 +-
arch/alpha/kernel/signal.c | 4 +--
arch/alpha/kernel/traps.c | 26 +++++++--------
arch/alpha/mm/fault.c | 4 +--
arch/arm/kernel/signal.c | 39 ++++++++++++++++++++++
arch/arm64/kernel/signal.c | 39 ++++++++++++++++++++++
arch/arm64/kernel/signal32.c | 39 ++++++++++++++++++++++
arch/mips/include/uapi/asm/siginfo.h | 2 --
arch/sparc/include/uapi/asm/siginfo.h | 3 --
arch/sparc/kernel/process_64.c | 2 +-
arch/sparc/kernel/signal32.c | 37 +++++++++++++++++++++
arch/sparc/kernel/signal_64.c | 36 ++++++++++++++++++++
arch/sparc/kernel/sys_sparc_32.c | 2 +-
arch/sparc/kernel/sys_sparc_64.c | 2 +-
arch/sparc/kernel/traps_32.c | 22 ++++++-------
arch/sparc/kernel/traps_64.c | 44 +++++++++++--------------
arch/sparc/kernel/unaligned_32.c | 2 +-
arch/sparc/mm/fault_32.c | 2 +-
arch/sparc/mm/fault_64.c | 2 +-
arch/x86/kernel/signal_compat.c | 6 ++++
fs/signalfd.c | 4 +--
include/linux/sched/signal.h | 11 ++-----
include/linux/signal.h | 2 +-
include/uapi/asm-generic/siginfo.h | 5 +++
kernel/signal.c | 62 +++++++++++++++++++++++++----------
26 files changed, 305 insertions(+), 96 deletions(-)
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/signal.c | 62 |
1 files changed, 44 insertions, 18 deletions
diff --git a/kernel/signal.c b/kernel/signal.c index a3229add4455..332b21f2fe72 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -1213,7 +1213,7 @@ static inline bool has_si_pid_and_uid(struct kernel_siginfo *info) case SIL_FAULT_MCEERR: case SIL_FAULT_BNDERR: case SIL_FAULT_PKUERR: - case SIL_PERF_EVENT: + case SIL_FAULT_PERF_EVENT: case SIL_SYS: ret = false; break; @@ -1666,7 +1666,6 @@ void force_sigsegv(int sig) } int force_sig_fault_to_task(int sig, int code, void __user *addr - ___ARCH_SI_TRAPNO(int trapno) ___ARCH_SI_IA64(int imm, unsigned int flags, unsigned long isr) , struct task_struct *t) { @@ -1677,9 +1676,6 @@ int force_sig_fault_to_task(int sig, int code, void __user *addr info.si_errno = 0; info.si_code = code; info.si_addr = addr; -#ifdef __ARCH_SI_TRAPNO - info.si_trapno = trapno; -#endif #ifdef __ia64__ info.si_imm = imm; info.si_flags = flags; @@ -1689,16 +1685,13 @@ int force_sig_fault_to_task(int sig, int code, void __user *addr } int force_sig_fault(int sig, int code, void __user *addr - ___ARCH_SI_TRAPNO(int trapno) ___ARCH_SI_IA64(int imm, unsigned int flags, unsigned long isr)) { return force_sig_fault_to_task(sig, code, addr - ___ARCH_SI_TRAPNO(trapno) ___ARCH_SI_IA64(imm, flags, isr), current); } int send_sig_fault(int sig, int code, void __user *addr - ___ARCH_SI_TRAPNO(int trapno) ___ARCH_SI_IA64(int imm, unsigned int flags, unsigned long isr) , struct task_struct *t) { @@ -1709,9 +1702,6 @@ int send_sig_fault(int sig, int code, void __user *addr info.si_errno = 0; info.si_code = code; info.si_addr = addr; -#ifdef __ARCH_SI_TRAPNO - info.si_trapno = trapno; -#endif #ifdef __ia64__ info.si_imm = imm; info.si_flags = flags; @@ -1808,6 +1798,39 @@ int force_sig_ptrace_errno_trap(int errno, void __user *addr) return force_sig_info(&info); } +/* For the rare architectures that include trap information using + * si_trapno. + */ +int force_sig_fault_trapno(int sig, int code, void __user *addr, int trapno) +{ + struct kernel_siginfo info; + + clear_siginfo(&info); + info.si_signo = sig; + info.si_errno = 0; + info.si_code = code; + info.si_addr = addr; + info.si_trapno = trapno; + return force_sig_info(&info); +} + +/* For the rare architectures that include trap information using + * si_trapno. + */ +int send_sig_fault_trapno(int sig, int code, void __user *addr, int trapno, + struct task_struct *t) +{ + struct kernel_siginfo info; + + clear_siginfo(&info); + info.si_signo = sig; + info.si_errno = 0; + info.si_code = code; + info.si_addr = addr; + info.si_trapno = trapno; + return send_sig_info(info.si_signo, &info, t); +} + int kill_pgrp(struct pid *pid, int sig, int priv) { int ret; @@ -2557,7 +2580,7 @@ static void hide_si_addr_tag_bits(struct ksignal *ksig) case SIL_FAULT_MCEERR: case SIL_FAULT_BNDERR: case SIL_FAULT_PKUERR: - case SIL_PERF_EVENT: + case SIL_FAULT_PERF_EVENT: ksig->info.si_addr = arch_untagged_si_addr( ksig->info.si_addr, ksig->sig, ksig->info.si_code); break; @@ -3242,11 +3265,14 @@ enum siginfo_layout siginfo_layout(unsigned sig, int si_code) layout = SIL_FAULT_PKUERR; #endif else if ((sig == SIGTRAP) && (si_code == TRAP_PERF)) - layout = SIL_PERF_EVENT; -#ifdef __ARCH_SI_TRAPNO - else if (layout == SIL_FAULT) + layout = SIL_FAULT_PERF_EVENT; + else if (IS_ENABLED(CONFIG_SPARC) && + (sig == SIGILL) && (si_code == ILL_ILLTRP)) + layout = SIL_FAULT_TRAPNO; + else if (IS_ENABLED(CONFIG_ALPHA) && + ((sig == SIGFPE) || + ((sig == SIGTRAP) && (si_code == TRAP_UNK)))) layout = SIL_FAULT_TRAPNO; -#endif } else if (si_code <= NSIGPOLL) layout = SIL_POLL; @@ -3368,7 +3394,7 @@ void copy_siginfo_to_external32(struct compat_siginfo *to, to->si_addr = ptr_to_compat(from->si_addr); to->si_pkey = from->si_pkey; break; - case SIL_PERF_EVENT: + case SIL_FAULT_PERF_EVENT: to->si_addr = ptr_to_compat(from->si_addr); to->si_perf_data = from->si_perf_data; to->si_perf_type = from->si_perf_type; @@ -3445,7 +3471,7 @@ static int post_copy_siginfo_from_user32(kernel_siginfo_t *to, to->si_addr = compat_ptr(from->si_addr); to->si_pkey = from->si_pkey; break; - case SIL_PERF_EVENT: + case SIL_FAULT_PERF_EVENT: to->si_addr = compat_ptr(from->si_addr); to->si_perf_data = from->si_perf_data; to->si_perf_type = from->si_perf_type; |