Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

+19 -5
+1 -1
arch/mips/kernel/traps.c
··· 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)
+3 -3
arch/parisc/kernel/ptrace.c
··· 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 }
+4
include/linux/sched/signal.h
··· 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)
+11 -1
kernel/signal.c
··· 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 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