Commit 91ca180dbdd687d45fe4aab055b02d29c91b90df
1 parent
351b6825b3
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>
Showing 4 changed files with 19 additions and 5 deletions Side-by-side Diff
arch/mips/kernel/traps.c
... | ... | @@ -733,7 +733,7 @@ |
733 | 733 | else if (fcr31 & FPU_CSR_INE_X) |
734 | 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 | |
739 | 739 | int process_fpemu_return(int sig, void __user *fault_addr, unsigned long fcr31) |
arch/parisc/kernel/ptrace.c
... | ... | @@ -88,9 +88,9 @@ |
88 | 88 | ptrace_disable(task); |
89 | 89 | /* Don't wake up the task, but let the |
90 | 90 | parent know something happened. */ |
91 | - force_sig_fault(SIGTRAP, TRAP_TRACE, | |
92 | - (void __user *) (task_regs(task)->iaoq[0] & ~3), | |
93 | - task); | |
91 | + force_sig_fault_to_task(SIGTRAP, TRAP_TRACE, | |
92 | + (void __user *) (task_regs(task)->iaoq[0] & ~3), | |
93 | + task); | |
94 | 94 | /* notify_parent(task, SIGCHLD); */ |
95 | 95 | return; |
96 | 96 | } |
include/linux/sched/signal.h
... | ... | @@ -307,6 +307,10 @@ |
307 | 307 | # define ___ARCH_SI_IA64(_a1, _a2, _a3) |
308 | 308 | #endif |
309 | 309 | |
310 | +int 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); | |
310 | 314 | int force_sig_fault(int sig, int code, void __user *addr |
311 | 315 | ___ARCH_SI_TRAPNO(int trapno) |
312 | 316 | ___ARCH_SI_IA64(int imm, unsigned int flags, unsigned long isr) |
kernel/signal.c
... | ... | @@ -1620,7 +1620,7 @@ |
1620 | 1620 | force_sig(SIGSEGV); |
1621 | 1621 | } |
1622 | 1622 | |
1623 | -int force_sig_fault(int sig, int code, void __user *addr | |
1623 | +int force_sig_fault_to_task(int sig, int code, void __user *addr | |
1624 | 1624 | ___ARCH_SI_TRAPNO(int trapno) |
1625 | 1625 | ___ARCH_SI_IA64(int imm, unsigned int flags, unsigned long isr) |
1626 | 1626 | , struct task_struct *t) |
... | ... | @@ -1641,6 +1641,16 @@ |
1641 | 1641 | info.si_isr = isr; |
1642 | 1642 | #endif |
1643 | 1643 | return force_sig_info(info.si_signo, &info, t); |
1644 | +} | |
1645 | + | |
1646 | +int 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); | |
1644 | 1654 | } |
1645 | 1655 | |
1646 | 1656 | int send_sig_fault(int sig, int code, void __user *addr |