1/* 2 * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) 3 * Licensed under the GPL 4 */ 5 6#include "linux/stddef.h" 7#include "linux/sys.h" 8#include "linux/sched.h" 9#include "linux/wait.h" 10#include "linux/kernel.h" 11#include "linux/smp_lock.h" 12#include "linux/module.h" 13#include "linux/slab.h" 14#include "linux/tty.h" 15#include "linux/binfmts.h" 16#include "linux/ptrace.h" 17#include "asm/signal.h" 18#include "asm/uaccess.h" 19#include "asm/unistd.h" 20#include "asm/ucontext.h" 21#include "kern_util.h" 22#include "signal_kern.h" 23#include "kern.h" 24#include "frame_kern.h" 25#include "sigcontext.h" 26#include "mode.h" 27 28EXPORT_SYMBOL(block_signals); 29EXPORT_SYMBOL(unblock_signals); 30 31#define _S(nr) (1<<((nr)-1)) 32 33#define _BLOCKABLE (~(_S(SIGKILL) | _S(SIGSTOP))) 34 35/* 36 * OK, we're invoking a handler 37 */ 38static int handle_signal(struct pt_regs *regs, unsigned long signr, 39 struct k_sigaction *ka, siginfo_t *info, 40 sigset_t *oldset) 41{ 42 unsigned long sp; 43 int err; 44 45 /* Always make any pending restarted system calls return -EINTR */ 46 current_thread_info()->restart_block.fn = do_no_restart_syscall; 47 48 /* Did we come from a system call? */ 49 if(PT_REGS_SYSCALL_NR(regs) >= 0){ 50 /* If so, check system call restarting.. */ 51 switch(PT_REGS_SYSCALL_RET(regs)){ 52 case -ERESTART_RESTARTBLOCK: 53 case -ERESTARTNOHAND: 54 PT_REGS_SYSCALL_RET(regs) = -EINTR; 55 break; 56 57 case -ERESTARTSYS: 58 if (!(ka->sa.sa_flags & SA_RESTART)) { 59 PT_REGS_SYSCALL_RET(regs) = -EINTR; 60 break; 61 } 62 /* fallthrough */ 63 case -ERESTARTNOINTR: 64 PT_REGS_RESTART_SYSCALL(regs); 65 PT_REGS_ORIG_SYSCALL(regs) = PT_REGS_SYSCALL_NR(regs); 66 break; 67 } 68 } 69 70 sp = PT_REGS_SP(regs); 71 if((ka->sa.sa_flags & SA_ONSTACK) && (sas_ss_flags(sp) == 0)) 72 sp = current->sas_ss_sp + current->sas_ss_size; 73 74#ifdef CONFIG_ARCH_HAS_SC_SIGNALS 75 if(!(ka->sa.sa_flags & SA_SIGINFO)) 76 err = setup_signal_stack_sc(sp, signr, ka, regs, oldset); 77 else 78#endif 79 err = setup_signal_stack_si(sp, signr, ka, regs, info, oldset); 80 81 if(err){ 82 spin_lock_irq(¤t->sighand->siglock); 83 current->blocked = *oldset; 84 recalc_sigpending(); 85 spin_unlock_irq(¤t->sighand->siglock); 86 force_sigsegv(signr, current); 87 } else { 88 spin_lock_irq(¤t->sighand->siglock); 89 sigorsets(¤t->blocked, ¤t->blocked, 90 &ka->sa.sa_mask); 91 if(!(ka->sa.sa_flags & SA_NODEFER)) 92 sigaddset(¤t->blocked, signr); 93 recalc_sigpending(); 94 spin_unlock_irq(¤t->sighand->siglock); 95 } 96 97 return err; 98} 99 100static int kern_do_signal(struct pt_regs *regs) 101{ 102 struct k_sigaction ka_copy; 103 siginfo_t info; 104 sigset_t *oldset; 105 int sig, handled_sig = 0; 106 107 if (test_thread_flag(TIF_RESTORE_SIGMASK)) 108 oldset = ¤t->saved_sigmask; 109 else 110 oldset = ¤t->blocked; 111 112 while((sig = get_signal_to_deliver(&info, &ka_copy, regs, NULL)) > 0){ 113 handled_sig = 1; 114 /* Whee! Actually deliver the signal. */ 115 if(!handle_signal(regs, sig, &ka_copy, &info, oldset)){ 116 /* a signal was successfully delivered; the saved 117 * sigmask will have been stored in the signal frame, 118 * and will be restored by sigreturn, so we can simply 119 * clear the TIF_RESTORE_SIGMASK flag */ 120 if (test_thread_flag(TIF_RESTORE_SIGMASK)) 121 clear_thread_flag(TIF_RESTORE_SIGMASK); 122 break; 123 } 124 } 125 126 /* Did we come from a system call? */ 127 if(!handled_sig && (PT_REGS_SYSCALL_NR(regs) >= 0)){ 128 /* Restart the system call - no handlers present */ 129 switch(PT_REGS_SYSCALL_RET(regs)){ 130 case -ERESTARTNOHAND: 131 case -ERESTARTSYS: 132 case -ERESTARTNOINTR: 133 PT_REGS_ORIG_SYSCALL(regs) = PT_REGS_SYSCALL_NR(regs); 134 PT_REGS_RESTART_SYSCALL(regs); 135 break; 136 case -ERESTART_RESTARTBLOCK: 137 PT_REGS_ORIG_SYSCALL(regs) = __NR_restart_syscall; 138 PT_REGS_RESTART_SYSCALL(regs); 139 break; 140 } 141 } 142 143 /* This closes a way to execute a system call on the host. If 144 * you set a breakpoint on a system call instruction and singlestep 145 * from it, the tracing thread used to PTRACE_SINGLESTEP the process 146 * rather than PTRACE_SYSCALL it, allowing the system call to execute 147 * on the host. The tracing thread will check this flag and 148 * PTRACE_SYSCALL if necessary. 149 */ 150 if(current->ptrace & PT_DTRACE) 151 current->thread.singlestep_syscall = 152 is_syscall(PT_REGS_IP(¤t->thread.regs)); 153 154 /* if there's no signal to deliver, we just put the saved sigmask 155 * back */ 156 if (!handled_sig && test_thread_flag(TIF_RESTORE_SIGMASK)) { 157 clear_thread_flag(TIF_RESTORE_SIGMASK); 158 sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); 159 } 160 return handled_sig; 161} 162 163int do_signal(void) 164{ 165 return kern_do_signal(¤t->thread.regs); 166} 167 168/* 169 * Atomically swap in the new signal mask, and wait for a signal. 170 */ 171long sys_sigsuspend(int history0, int history1, old_sigset_t mask) 172{ 173 mask &= _BLOCKABLE; 174 spin_lock_irq(¤t->sighand->siglock); 175 current->saved_sigmask = current->blocked; 176 siginitset(¤t->blocked, mask); 177 recalc_sigpending(); 178 spin_unlock_irq(¤t->sighand->siglock); 179 180 current->state = TASK_INTERRUPTIBLE; 181 schedule(); 182 set_thread_flag(TIF_RESTORE_SIGMASK); 183 return -ERESTARTNOHAND; 184} 185 186long sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss) 187{ 188 return do_sigaltstack(uss, uoss, PT_REGS_SP(¤t->thread.regs)); 189} 190