summaryrefslogtreecommitdiffstats
path: root/kernel/signal.c
diff options
context:
space:
mode:
authorEric W. Biederman <ebiederm@xmission.com>2021-07-23 13:26:44 -0500
committerEric W. Biederman <ebiederm@xmission.com>2021-07-23 13:31:52 -0500
commitee53488cc74143cadbe752d5332b1e3fd87eed49 (patch)
treeab6416ac382dc2e2d2500eb458cd0d150ac59b63 /kernel/signal.c
parente73f0f0ee7541171d89f2e2491130c7771ba58d3 (diff)
parentf4ac73023449e6f2f74f69e38f4840c83edfa840 (diff)
downloadlinux-stable-ee53488cc74143cadbe752d5332b1e3fd87eed49.tar.gz
linux-stable-ee53488cc74143cadbe752d5332b1e3fd87eed49.tar.bz2
linux-stable-ee53488cc74143cadbe752d5332b1e3fd87eed49.zip
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/signal.c')
-rw-r--r--kernel/signal.c62
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;