summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric W. Biederman <ebiederm@xmission.com>2019-02-06 17:39:13 -0500
committerEric W. Biederman <ebiederm@xmission.com>2019-05-29 10:31:43 -0400
commit91ca180dbdd687d45fe4aab055b02d29c91b90df (patch)
tree468888ea5dfa8f2177bbd62efcefe6484fb3870f
parent351b6825b3a9f70bab080fba67aec104ff9a41d6 (diff)
signal: Use force_sig_fault_to_task for the two calls that don't deliver to current
In preparation for removing the task parameter from force_sig_fault introduce force_sig_fault_to_task and use it for the two cases where it matters. On mips force_fcr31_sig calls force_sig_fault and is called on either the current task, or a task that is suspended and is being switched to by the scheduler. This is safe because the task being switched to by the scheduler is guaranteed to be suspended. This ensures that task->sighand is stable while the signal is delivered to it. On parisc user_enable_single_step calls force_sig_fault and is in turn called by ptrace_request. The function ptrace_request always calls user_enable_single_step on a child that is stopped for tracing. The child being traced and not reaped ensures that child->sighand is not NULL, and that the child will not change child->sighand. Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
-rw-r--r--arch/mips/kernel/traps.c2
-rw-r--r--arch/parisc/kernel/ptrace.c6
-rw-r--r--include/linux/sched/signal.h4
-rw-r--r--kernel/signal.c12
4 files changed, 19 insertions, 5 deletions
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
index a6031b045b95..62df48b6fb46 100644
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -733,7 +733,7 @@ void force_fcr31_sig(unsigned long fcr31, void __user *fault_addr,
733 else if (fcr31 & FPU_CSR_INE_X) 733 else if (fcr31 & FPU_CSR_INE_X)
734 si_code = FPE_FLTRES; 734 si_code = FPE_FLTRES;
735 735
736 force_sig_fault(SIGFPE, si_code, fault_addr, tsk); 736 force_sig_fault_to_task(SIGFPE, si_code, fault_addr, tsk);
737} 737}
738 738
739int process_fpemu_return(int sig, void __user *fault_addr, unsigned long fcr31) 739int process_fpemu_return(int sig, void __user *fault_addr, unsigned long fcr31)
diff --git a/arch/parisc/kernel/ptrace.c b/arch/parisc/kernel/ptrace.c
index a3d2fb4e6dd2..f642ba378ffa 100644
--- a/arch/parisc/kernel/ptrace.c
+++ b/arch/parisc/kernel/ptrace.c
@@ -88,9 +88,9 @@ void user_enable_single_step(struct task_struct *task)
88 ptrace_disable(task); 88 ptrace_disable(task);
89 /* Don't wake up the task, but let the 89 /* Don't wake up the task, but let the
90 parent know something happened. */ 90 parent know something happened. */
91 force_sig_fault(SIGTRAP, TRAP_TRACE, 91 force_sig_fault_to_task(SIGTRAP, TRAP_TRACE,
92 (void __user *) (task_regs(task)->iaoq[0] & ~3), 92 (void __user *) (task_regs(task)->iaoq[0] & ~3),
93 task); 93 task);
94 /* notify_parent(task, SIGCHLD); */ 94 /* notify_parent(task, SIGCHLD); */
95 return; 95 return;
96 } 96 }
diff --git a/include/linux/sched/signal.h b/include/linux/sched/signal.h
index 4178bb1f7709..507af66a1fc8 100644
--- a/include/linux/sched/signal.h
+++ b/include/linux/sched/signal.h
@@ -307,6 +307,10 @@ static inline void kernel_signal_stop(void)
307# define ___ARCH_SI_IA64(_a1, _a2, _a3) 307# define ___ARCH_SI_IA64(_a1, _a2, _a3)
308#endif 308#endif
309 309
310int force_sig_fault_to_task(int sig, int code, void __user *addr
311 ___ARCH_SI_TRAPNO(int trapno)
312 ___ARCH_SI_IA64(int imm, unsigned int flags, unsigned long isr)
313 , struct task_struct *t);
310int force_sig_fault(int sig, int code, void __user *addr 314int force_sig_fault(int sig, int code, void __user *addr
311 ___ARCH_SI_TRAPNO(int trapno) 315 ___ARCH_SI_TRAPNO(int trapno)
312 ___ARCH_SI_IA64(int imm, unsigned int flags, unsigned long isr) 316 ___ARCH_SI_IA64(int imm, unsigned int flags, unsigned long isr)
diff --git a/kernel/signal.c b/kernel/signal.c
index 398489facf9f..e420489ac4c9 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -1620,7 +1620,7 @@ void force_sigsegv(int sig)
1620 force_sig(SIGSEGV); 1620 force_sig(SIGSEGV);
1621} 1621}
1622 1622
1623int force_sig_fault(int sig, int code, void __user *addr 1623int force_sig_fault_to_task(int sig, int code, void __user *addr
1624 ___ARCH_SI_TRAPNO(int trapno) 1624 ___ARCH_SI_TRAPNO(int trapno)
1625 ___ARCH_SI_IA64(int imm, unsigned int flags, unsigned long isr) 1625 ___ARCH_SI_IA64(int imm, unsigned int flags, unsigned long isr)
1626 , struct task_struct *t) 1626 , struct task_struct *t)
@@ -1643,6 +1643,16 @@ int force_sig_fault(int sig, int code, void __user *addr
1643 return force_sig_info(info.si_signo, &info, t); 1643 return force_sig_info(info.si_signo, &info, t);
1644} 1644}
1645 1645
1646int force_sig_fault(int sig, int code, void __user *addr
1647 ___ARCH_SI_TRAPNO(int trapno)
1648 ___ARCH_SI_IA64(int imm, unsigned int flags, unsigned long isr)
1649 , struct task_struct *t)
1650{
1651 return force_sig_fault_to_task(sig, code, addr
1652 ___ARCH_SI_TRAPNO(trapno)
1653 ___ARCH_SI_IA64(imm, flags, isr), t);
1654}
1655
1646int send_sig_fault(int sig, int code, void __user *addr 1656int send_sig_fault(int sig, int code, void __user *addr
1647 ___ARCH_SI_TRAPNO(int trapno) 1657 ___ARCH_SI_TRAPNO(int trapno)
1648 ___ARCH_SI_IA64(int imm, unsigned int flags, unsigned long isr) 1658 ___ARCH_SI_IA64(int imm, unsigned int flags, unsigned long isr)