0001
0002
0003
0004
0005
0006 #include <linux/module.h>
0007 #include <linux/ptrace.h>
0008 #include <linux/sched.h>
0009 #include <linux/ftrace.h>
0010 #include <asm/siginfo.h>
0011 #include <asm/signal.h>
0012 #include <asm/unistd.h>
0013 #include <frame_kern.h>
0014 #include <kern_util.h>
0015 #include <os.h>
0016
0017 EXPORT_SYMBOL(block_signals);
0018 EXPORT_SYMBOL(unblock_signals);
0019
0020 void block_signals_trace(void)
0021 {
0022 block_signals();
0023 if (current_thread_info())
0024 trace_hardirqs_off();
0025 }
0026
0027 void unblock_signals_trace(void)
0028 {
0029 if (current_thread_info())
0030 trace_hardirqs_on();
0031 unblock_signals();
0032 }
0033
0034 void um_trace_signals_on(void)
0035 {
0036 if (current_thread_info())
0037 trace_hardirqs_on();
0038 }
0039
0040 void um_trace_signals_off(void)
0041 {
0042 if (current_thread_info())
0043 trace_hardirqs_off();
0044 }
0045
0046
0047
0048
0049 static void handle_signal(struct ksignal *ksig, struct pt_regs *regs)
0050 {
0051 sigset_t *oldset = sigmask_to_save();
0052 int singlestep = 0;
0053 unsigned long sp;
0054 int err;
0055
0056 if (test_thread_flag(TIF_SINGLESTEP) && (current->ptrace & PT_PTRACED))
0057 singlestep = 1;
0058
0059
0060 if (PT_REGS_SYSCALL_NR(regs) >= 0) {
0061
0062 switch (PT_REGS_SYSCALL_RET(regs)) {
0063 case -ERESTART_RESTARTBLOCK:
0064 case -ERESTARTNOHAND:
0065 PT_REGS_SYSCALL_RET(regs) = -EINTR;
0066 break;
0067
0068 case -ERESTARTSYS:
0069 if (!(ksig->ka.sa.sa_flags & SA_RESTART)) {
0070 PT_REGS_SYSCALL_RET(regs) = -EINTR;
0071 break;
0072 }
0073 fallthrough;
0074 case -ERESTARTNOINTR:
0075 PT_REGS_RESTART_SYSCALL(regs);
0076 PT_REGS_ORIG_SYSCALL(regs) = PT_REGS_SYSCALL_NR(regs);
0077 break;
0078 }
0079 }
0080
0081 sp = PT_REGS_SP(regs);
0082 if ((ksig->ka.sa.sa_flags & SA_ONSTACK) && (sas_ss_flags(sp) == 0))
0083 sp = current->sas_ss_sp + current->sas_ss_size;
0084
0085 #ifdef CONFIG_ARCH_HAS_SC_SIGNALS
0086 if (!(ksig->ka.sa.sa_flags & SA_SIGINFO))
0087 err = setup_signal_stack_sc(sp, ksig, regs, oldset);
0088 else
0089 #endif
0090 err = setup_signal_stack_si(sp, ksig, regs, oldset);
0091
0092 signal_setup_done(err, ksig, singlestep);
0093 }
0094
0095 void do_signal(struct pt_regs *regs)
0096 {
0097 struct ksignal ksig;
0098 int handled_sig = 0;
0099
0100 while (get_signal(&ksig)) {
0101 handled_sig = 1;
0102
0103 handle_signal(&ksig, regs);
0104 }
0105
0106
0107 if (!handled_sig && (PT_REGS_SYSCALL_NR(regs) >= 0)) {
0108
0109 switch (PT_REGS_SYSCALL_RET(regs)) {
0110 case -ERESTARTNOHAND:
0111 case -ERESTARTSYS:
0112 case -ERESTARTNOINTR:
0113 PT_REGS_ORIG_SYSCALL(regs) = PT_REGS_SYSCALL_NR(regs);
0114 PT_REGS_RESTART_SYSCALL(regs);
0115 break;
0116 case -ERESTART_RESTARTBLOCK:
0117 PT_REGS_ORIG_SYSCALL(regs) = __NR_restart_syscall;
0118 PT_REGS_RESTART_SYSCALL(regs);
0119 break;
0120 }
0121 }
0122
0123
0124
0125
0126
0127
0128
0129
0130
0131 if (test_thread_flag(TIF_SINGLESTEP))
0132 current->thread.singlestep_syscall =
0133 is_syscall(PT_REGS_IP(¤t->thread.regs));
0134
0135
0136
0137
0138
0139 if (!handled_sig)
0140 restore_saved_sigmask();
0141 }