Line data Source code
1 : // SPDX-License-Identifier: GPL-2.0 2 : /* 3 : * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) 4 : */ 5 : 6 : #include <linux/module.h> 7 : #include <linux/ptrace.h> 8 : #include <linux/sched.h> 9 : #include <linux/ftrace.h> 10 : #include <asm/siginfo.h> 11 : #include <asm/signal.h> 12 : #include <asm/unistd.h> 13 : #include <frame_kern.h> 14 : #include <kern_util.h> 15 : #include <os.h> 16 : 17 : EXPORT_SYMBOL(block_signals); 18 : EXPORT_SYMBOL(unblock_signals); 19 : 20 2752 : void block_signals_trace(void) 21 : { 22 2752 : block_signals(); 23 2752 : if (current_thread_info()) 24 : trace_hardirqs_off(); 25 2752 : } 26 : 27 2750 : void unblock_signals_trace(void) 28 : { 29 2750 : if (current_thread_info()) 30 : trace_hardirqs_on(); 31 2750 : unblock_signals(); 32 2750 : } 33 : 34 2 : void um_trace_signals_on(void) 35 : { 36 2 : if (current_thread_info()) 37 : trace_hardirqs_on(); 38 2 : } 39 : 40 2 : void um_trace_signals_off(void) 41 : { 42 2 : if (current_thread_info()) 43 : trace_hardirqs_off(); 44 2 : } 45 : 46 : /* 47 : * OK, we're invoking a handler 48 : */ 49 0 : static void handle_signal(struct ksignal *ksig, struct pt_regs *regs) 50 : { 51 0 : sigset_t *oldset = sigmask_to_save(); 52 0 : int singlestep = 0; 53 : unsigned long sp; 54 : int err; 55 : 56 0 : if (test_thread_flag(TIF_SINGLESTEP) && (current->ptrace & PT_PTRACED)) 57 0 : singlestep = 1; 58 : 59 : /* Did we come from a system call? */ 60 0 : if (PT_REGS_SYSCALL_NR(regs) >= 0) { 61 : /* If so, check system call restarting.. */ 62 0 : switch (PT_REGS_SYSCALL_RET(regs)) { 63 : case -ERESTART_RESTARTBLOCK: 64 : case -ERESTARTNOHAND: 65 0 : PT_REGS_SYSCALL_RET(regs) = -EINTR; 66 0 : break; 67 : 68 : case -ERESTARTSYS: 69 0 : if (!(ksig->ka.sa.sa_flags & SA_RESTART)) { 70 0 : PT_REGS_SYSCALL_RET(regs) = -EINTR; 71 0 : break; 72 : } 73 : fallthrough; 74 : case -ERESTARTNOINTR: 75 0 : PT_REGS_RESTART_SYSCALL(regs); 76 0 : PT_REGS_ORIG_SYSCALL(regs) = PT_REGS_SYSCALL_NR(regs); 77 0 : break; 78 : } 79 : } 80 : 81 0 : sp = PT_REGS_SP(regs); 82 0 : if ((ksig->ka.sa.sa_flags & SA_ONSTACK) && (sas_ss_flags(sp) == 0)) 83 0 : sp = current->sas_ss_sp + current->sas_ss_size; 84 : 85 : #ifdef CONFIG_ARCH_HAS_SC_SIGNALS 86 : if (!(ksig->ka.sa.sa_flags & SA_SIGINFO)) 87 : err = setup_signal_stack_sc(sp, ksig, regs, oldset); 88 : else 89 : #endif 90 0 : err = setup_signal_stack_si(sp, ksig, regs, oldset); 91 : 92 0 : signal_setup_done(err, ksig, singlestep); 93 0 : } 94 : 95 0 : void do_signal(struct pt_regs *regs) 96 : { 97 : struct ksignal ksig; 98 0 : int handled_sig = 0; 99 : 100 0 : while (get_signal(&ksig)) { 101 0 : handled_sig = 1; 102 : /* Whee! Actually deliver the signal. */ 103 0 : handle_signal(&ksig, regs); 104 : } 105 : 106 : /* Did we come from a system call? */ 107 0 : if (!handled_sig && (PT_REGS_SYSCALL_NR(regs) >= 0)) { 108 : /* Restart the system call - no handlers present */ 109 0 : switch (PT_REGS_SYSCALL_RET(regs)) { 110 : case -ERESTARTNOHAND: 111 : case -ERESTARTSYS: 112 : case -ERESTARTNOINTR: 113 0 : PT_REGS_ORIG_SYSCALL(regs) = PT_REGS_SYSCALL_NR(regs); 114 0 : PT_REGS_RESTART_SYSCALL(regs); 115 0 : break; 116 : case -ERESTART_RESTARTBLOCK: 117 0 : PT_REGS_ORIG_SYSCALL(regs) = __NR_restart_syscall; 118 0 : PT_REGS_RESTART_SYSCALL(regs); 119 0 : break; 120 : } 121 : } 122 : 123 : /* 124 : * This closes a way to execute a system call on the host. If 125 : * you set a breakpoint on a system call instruction and singlestep 126 : * from it, the tracing thread used to PTRACE_SINGLESTEP the process 127 : * rather than PTRACE_SYSCALL it, allowing the system call to execute 128 : * on the host. The tracing thread will check this flag and 129 : * PTRACE_SYSCALL if necessary. 130 : */ 131 0 : if (test_thread_flag(TIF_SINGLESTEP)) 132 0 : current->thread.singlestep_syscall = 133 0 : is_syscall(PT_REGS_IP(¤t->thread.regs)); 134 : 135 : /* 136 : * if there's no signal to deliver, we just put the saved sigmask 137 : * back 138 : */ 139 0 : if (!handled_sig) 140 0 : restore_saved_sigmask(); 141 0 : }