void start_thread(struct pt_regs *regs, unsigned long eip, unsigned long esp) { PT_REGS_IP(regs) = eip; PT_REGS_SP(regs) = esp; current->ptrace &= ~PT_DTRACE; #ifdef SUBARCH_EXECVE1 SUBARCH_EXECVE1(regs->regs); #endif }
void start_thread_tt(struct pt_regs *regs, unsigned long eip, unsigned long esp) { set_fs(USER_DS); flush_tlb_mm(current->mm); PT_REGS_IP(regs) = eip; PT_REGS_SP(regs) = esp; PT_FIX_EXEC_STACK(esp); }
int setup_signal_stack_si(unsigned long stack_top, int sig, struct k_sigaction *ka, struct pt_regs *regs, siginfo_t *info, sigset_t *mask) { struct rt_sigframe __user *frame; void __user *restorer; unsigned long save_sp = PT_REGS_SP(regs); int err = 0; stack_top &= -8UL; frame = (struct rt_sigframe __user *) stack_top - 1; if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) return 1; restorer = frame->retcode; if(ka->sa.sa_flags & SA_RESTORER) restorer = ka->sa.sa_restorer; /* See comment above about why this is here */ PT_REGS_SP(regs) = (unsigned long) frame; err |= __put_user(restorer, &frame->pretcode); err |= __put_user(sig, &frame->sig); err |= __put_user(&frame->info, &frame->pinfo); err |= __put_user(&frame->uc, &frame->puc); err |= copy_siginfo_to_user(&frame->info, info); err |= copy_ucontext_to_user(&frame->uc, &frame->fpstate, mask, save_sp); /* * This is movl $,%eax ; int $0x80 * * WE DO NOT USE IT ANY MORE! It's only left here for historical * reasons and because gdb uses it as a signature to notice * signal handler stack frames. */ err |= __put_user(0xb8, (char __user *)(frame->retcode+0)); err |= __put_user(__NR_rt_sigreturn, (int __user *)(frame->retcode+1)); err |= __put_user(0x80cd, (short __user *)(frame->retcode+5)); if(err) goto err; PT_REGS_IP(regs) = (unsigned long) ka->sa.sa_handler; PT_REGS_EAX(regs) = (unsigned long) sig; PT_REGS_EDX(regs) = (unsigned long) &frame->info; PT_REGS_ECX(regs) = (unsigned long) &frame->uc; if ((current->ptrace & PT_DTRACE) && (current->ptrace & PT_PTRACED)) ptrace_notify(SIGTRAP); return 0; err: PT_REGS_SP(regs) = save_sp; return err; }
static int kern_do_signal(struct pt_regs *regs) { struct k_sigaction ka_copy; siginfo_t info; sigset_t *oldset; int sig, handled_sig = 0; if (test_thread_flag(TIF_RESTORE_SIGMASK)) oldset = ¤t->saved_sigmask; else oldset = ¤t->blocked; while ((sig = get_signal_to_deliver(&info, &ka_copy, regs, NULL)) > 0) { handled_sig = 1; /* Whee! Actually deliver the signal. */ handle_signal(regs, sig, &ka_copy, &info); } /* Did we come from a system call? */ if (!handled_sig && (PT_REGS_SYSCALL_NR(regs) >= 0)) { /* Restart the system call - no handlers present */ switch (PT_REGS_SYSCALL_RET(regs)) { case -ERESTARTNOHAND: case -ERESTARTSYS: case -ERESTARTNOINTR: PT_REGS_ORIG_SYSCALL(regs) = PT_REGS_SYSCALL_NR(regs); PT_REGS_RESTART_SYSCALL(regs); break; case -ERESTART_RESTARTBLOCK: PT_REGS_ORIG_SYSCALL(regs) = __NR_restart_syscall; PT_REGS_RESTART_SYSCALL(regs); break; } } /* * This closes a way to execute a system call on the host. If * you set a breakpoint on a system call instruction and singlestep * from it, the tracing thread used to PTRACE_SINGLESTEP the process * rather than PTRACE_SYSCALL it, allowing the system call to execute * on the host. The tracing thread will check this flag and * PTRACE_SYSCALL if necessary. */ if (current->ptrace & PT_DTRACE) current->thread.singlestep_syscall = is_syscall(PT_REGS_IP(¤t->thread.regs)); /* * if there's no signal to deliver, we just put the saved sigmask * back */ if (!handled_sig) restore_saved_sigmask(); return handled_sig; }
static int kern_do_signal(struct pt_regs *regs) { struct k_sigaction ka_copy; siginfo_t info; sigset_t *oldset; int sig, handled_sig = 0; if (test_thread_flag(TIF_RESTORE_SIGMASK)) oldset = ¤t->saved_sigmask; else oldset = ¤t->blocked; while ((sig = get_signal_to_deliver(&info, &ka_copy, regs, NULL)) > 0) { handled_sig = 1; if (!handle_signal(regs, sig, &ka_copy, &info, oldset)) { if (test_thread_flag(TIF_RESTORE_SIGMASK)) clear_thread_flag(TIF_RESTORE_SIGMASK); break; } } if (!handled_sig && (PT_REGS_SYSCALL_NR(regs) >= 0)) { switch (PT_REGS_SYSCALL_RET(regs)) { case -ERESTARTNOHAND: case -ERESTARTSYS: case -ERESTARTNOINTR: PT_REGS_ORIG_SYSCALL(regs) = PT_REGS_SYSCALL_NR(regs); PT_REGS_RESTART_SYSCALL(regs); break; case -ERESTART_RESTARTBLOCK: PT_REGS_ORIG_SYSCALL(regs) = __NR_restart_syscall; PT_REGS_RESTART_SYSCALL(regs); break; } } if (current->ptrace & PT_DTRACE) current->thread.singlestep_syscall = is_syscall(PT_REGS_IP(¤t->thread.regs)); if (!handled_sig && test_thread_flag(TIF_RESTORE_SIGMASK)) { clear_thread_flag(TIF_RESTORE_SIGMASK); sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); } return handled_sig; }
int setup_signal_stack_sc(unsigned long stack_top, int sig, struct k_sigaction *ka, struct pt_regs *regs, sigset_t *mask) { struct sigframe __user *frame; void *restorer; int err = 0; stack_top &= -8UL; frame = (struct sigframe *) stack_top - 1; if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) return 1; restorer = (void *) frame->retcode; if(ka->sa.sa_flags & SA_RESTORER) restorer = ka->sa.sa_restorer; err |= __put_user(restorer, &frame->pretcode); err |= __put_user(sig, &frame->sig); err |= copy_sc_to_user(&frame->sc, NULL, regs); err |= __put_user(mask->sig[0], &frame->sc.oldmask); if (_NSIG_WORDS > 1) err |= __copy_to_user(&frame->extramask, &mask->sig[1], sizeof(frame->extramask)); /* * This is popl %eax ; movl $,%eax ; int $0x80 * * WE DO NOT USE IT ANY MORE! It's only left here for historical * reasons and because gdb uses it as a signature to notice * signal handler stack frames. */ err |= __put_user(0xb858, (short __user *)(frame->retcode+0)); err |= __put_user(__NR_sigreturn, (int __user *)(frame->retcode+2)); err |= __put_user(0x80cd, (short __user *)(frame->retcode+6)); if(err) return(err); PT_REGS_SP(regs) = (unsigned long) frame; PT_REGS_IP(regs) = (unsigned long) ka->sa.sa_handler; PT_REGS_EAX(regs) = (unsigned long) sig; PT_REGS_EDX(regs) = (unsigned long) 0; PT_REGS_ECX(regs) = (unsigned long) 0; if ((current->ptrace & PT_DTRACE) && (current->ptrace & PT_PTRACED)) ptrace_notify(SIGTRAP); return(0); }
static int kern_do_signal(struct pt_regs *regs, sigset_t *oldset, int error) { siginfo_t info; struct k_sigaction *ka; int err, sig; if (!oldset) oldset = ¤t->blocked; sig = get_signal_to_deliver(&info, regs, NULL); if(sig == 0) return(0); /* Whee! Actually deliver the signal. */ ka = ¤t->sig->action[sig -1 ]; err = handle_signal(regs, sig, ka, &info, oldset, error); if(!err) return(1); /* Did we come from a system call? */ if(PT_REGS_SYSCALL_NR(regs) >= 0){ /* Restart the system call - no handlers present */ if(PT_REGS_SYSCALL_RET(regs) == -ERESTARTNOHAND || PT_REGS_SYSCALL_RET(regs) == -ERESTARTSYS || PT_REGS_SYSCALL_RET(regs) == -ERESTARTNOINTR){ PT_REGS_ORIG_SYSCALL(regs) = PT_REGS_SYSCALL_NR(regs); PT_REGS_RESTART_SYSCALL(regs); } else if(PT_REGS_SYSCALL_RET(regs) == -ERESTART_RESTARTBLOCK){ PT_REGS_SYSCALL_RET(regs) = __NR_restart_syscall; PT_REGS_RESTART_SYSCALL(regs); } } /* This closes a way to execute a system call on the host. If * you set a breakpoint on a system call instruction and singlestep * from it, the tracing thread used to PTRACE_SINGLESTEP the process * rather than PTRACE_SYSCALL it, allowing the system call to execute * on the host. The tracing thread will check this flag and * PTRACE_SYSCALL if necessary. */ if((current->ptrace & PT_DTRACE) && is_syscall(PT_REGS_IP(¤t->thread.regs))) (void) CHOOSE_MODE(current->thread.mode.tt.singlestep_syscall = 1, 0); return(0); }
int setup_signal_stack_sc(unsigned long stack_top, int sig, struct k_sigaction *ka, struct pt_regs *regs, sigset_t *mask) { struct frame_common *frame = &signal_frame_sc_sr.common; void *restorer; void *user_sc; int sig_size = (_NSIG_WORDS - 1) * sizeof(unsigned long); unsigned long sigs, sr; unsigned long start = stack_top - frame->len - sig_size; restorer = NULL; if(ka->sa.sa_flags & SA_RESTORER) restorer = ka->sa.sa_restorer; user_sc = (void *) (start + signal_frame_sc_sr.sc_index); if(restorer == NULL){ frame = &signal_frame_sc.common; user_sc = (void *) (start + signal_frame_sc.sc_index); sr = (unsigned long) frame->data; sr += frame->sr_index; sr = *((unsigned long *) sr); restorer = ((void (*)(void)) sr); } sigs = start + frame->len; if(copy_to_user((void *) start, frame->data, frame->len) || copy_to_user((void *) (start + frame->sig_index), &sig, sizeof(sig)) || copy_sc_to_user(user_sc, NULL, regs, &signal_frame_sc.common.arch) || copy_to_user(sc_sigmask(user_sc), mask, sizeof(mask->sig[0])) || copy_to_user((void *) sigs, &mask->sig[1], sig_size) || copy_restorer(restorer, start, frame->sr_index, frame->sr_relative)) return(1); PT_REGS_IP(regs) = (unsigned long) ka->sa.sa_handler; PT_REGS_SP(regs) = start + frame->sp_index; return(0); }
void __show_regs(struct pt_regs *regs) { printk("\n"); print_modules(); printk(KERN_INFO "Pid: %d, comm: %.20s %s %s\n", task_pid_nr(current), current->comm, print_tainted(), init_utsname()->release); printk(KERN_INFO "RIP: %04lx:[<%016lx>]\n", PT_REGS_CS(regs) & 0xffff, PT_REGS_IP(regs)); printk(KERN_INFO "RSP: %016lx EFLAGS: %08lx\n", PT_REGS_SP(regs), PT_REGS_EFLAGS(regs)); printk(KERN_INFO "RAX: %016lx RBX: %016lx RCX: %016lx\n", PT_REGS_AX(regs), PT_REGS_BX(regs), PT_REGS_CX(regs)); printk(KERN_INFO "RDX: %016lx RSI: %016lx RDI: %016lx\n", PT_REGS_DX(regs), PT_REGS_SI(regs), PT_REGS_DI(regs)); printk(KERN_INFO "RBP: %016lx R08: %016lx R09: %016lx\n", PT_REGS_BP(regs), PT_REGS_R8(regs), PT_REGS_R9(regs)); printk(KERN_INFO "R10: %016lx R11: %016lx R12: %016lx\n", PT_REGS_R10(regs), PT_REGS_R11(regs), PT_REGS_R12(regs)); printk(KERN_INFO "R13: %016lx R14: %016lx R15: %016lx\n", PT_REGS_R13(regs), PT_REGS_R14(regs), PT_REGS_R15(regs)); }
int setup_signal_stack_si(unsigned long stack_top, int sig, struct k_sigaction *ka, struct pt_regs *regs, siginfo_t *info, sigset_t *mask) { unsigned long start; void *restorer; void *sip, *ucp, *fp; start = stack_top - signal_frame_si.common.len; sip = (void *) (start + signal_frame_si.si_index); ucp = (void *) (start + signal_frame_si.uc_index); fp = (void *) (((unsigned long) ucp) + sizeof(struct ucontext)); restorer = NULL; if(ka->sa.sa_flags & SA_RESTORER) restorer = ka->sa.sa_restorer; if(restorer == NULL) panic("setup_signal_stack_si - no restorer"); if(copy_to_user((void *) start, signal_frame_si.common.data, signal_frame_si.common.len) || copy_to_user((void *) (start + signal_frame_si.common.sig_index), &sig, sizeof(sig)) || copy_siginfo_to_user(sip, info) || copy_to_user((void *) (start + signal_frame_si.sip_index), &sip, sizeof(sip)) || copy_ucontext_to_user(ucp, fp, mask, PT_REGS_SP(regs)) || copy_to_user((void *) (start + signal_frame_si.ucp_index), &ucp, sizeof(ucp)) || copy_restorer(restorer, start, signal_frame_si.common.sr_index, signal_frame_si.common.sr_relative)) return(1); PT_REGS_IP(regs) = (unsigned long) ka->sa.sa_handler; PT_REGS_SP(regs) = start + signal_frame_si.common.sp_index; return(0); }
void start_thread(struct pt_regs *regs, unsigned long eip, unsigned long esp) { PT_REGS_IP(regs) = eip; PT_REGS_SP(regs) = esp; }
int setup_signal_stack_sc(unsigned long stack_top, int sig, struct k_sigaction *ka, struct pt_regs *regs, sigset_t *mask) { struct sigframe __user *frame; void __user *restorer; unsigned long save_sp = PT_REGS_SP(regs); int err = 0; /* This is the same calculation as i386 - ((sp + 4) & 15) == 0 */ stack_top = ((stack_top + 4) & -16UL) - 4; frame = (struct sigframe __user *) stack_top - 1; if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) return 1; restorer = frame->retcode; if(ka->sa.sa_flags & SA_RESTORER) restorer = ka->sa.sa_restorer; /* Update SP now because the page fault handler refuses to extend * the stack if the faulting address is too far below the current * SP, which frame now certainly is. If there's an error, the original * value is restored on the way out. * When writing the sigcontext to the stack, we have to write the * original value, so that's passed to copy_sc_to_user, which does * the right thing with it. */ PT_REGS_SP(regs) = (unsigned long) frame; err |= __put_user(restorer, &frame->pretcode); err |= __put_user(sig, &frame->sig); err |= copy_sc_to_user(&frame->sc, NULL, regs, save_sp); err |= __put_user(mask->sig[0], &frame->sc.oldmask); if (_NSIG_WORDS > 1) err |= __copy_to_user(&frame->extramask, &mask->sig[1], sizeof(frame->extramask)); /* * This is popl %eax ; movl $,%eax ; int $0x80 * * WE DO NOT USE IT ANY MORE! It's only left here for historical * reasons and because gdb uses it as a signature to notice * signal handler stack frames. */ err |= __put_user(0xb858, (short __user *)(frame->retcode+0)); err |= __put_user(__NR_sigreturn, (int __user *)(frame->retcode+2)); err |= __put_user(0x80cd, (short __user *)(frame->retcode+6)); if(err) goto err; PT_REGS_SP(regs) = (unsigned long) frame; PT_REGS_IP(regs) = (unsigned long) ka->sa.sa_handler; PT_REGS_EAX(regs) = (unsigned long) sig; PT_REGS_EDX(regs) = (unsigned long) 0; PT_REGS_ECX(regs) = (unsigned long) 0; if ((current->ptrace & PT_DTRACE) && (current->ptrace & PT_PTRACED)) ptrace_notify(SIGTRAP); return 0; err: PT_REGS_SP(regs) = save_sp; return err; }