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