dotraplinkage void __kprobes do_general_protection(struct pt_regs *regs, long error_code) { struct task_struct *tsk; conditional_sti(regs); #ifdef CONFIG_X86_32 if (lazy_iobitmap_copy()) { /* restart the faulting instruction */ return; } if (regs->flags & X86_VM_MASK) goto gp_in_vm86; #endif tsk = current; if (!user_mode(regs)) goto gp_in_kernel; tsk->thread.error_code = error_code; tsk->thread.trap_no = 13; if (show_unhandled_signals && unhandled_signal(tsk, SIGSEGV) && printk_ratelimit()) { printk(KERN_INFO "%s[%d] general protection ip:%lx sp:%lx error:%lx", tsk->comm, task_pid_nr(tsk), regs->ip, regs->sp, error_code); print_vma_addr(" in ", regs->ip); printk("\n"); } force_sig(SIGSEGV, tsk); return; #ifdef CONFIG_X86_32 gp_in_vm86: local_irq_enable(); handle_vm86_fault((struct kernel_vm86_regs *) regs, error_code); return; #endif gp_in_kernel: if (fixup_exception(regs)) return; tsk->thread.error_code = error_code; tsk->thread.trap_no = 13; if (notify_die(DIE_GPF, "general protection fault", regs, error_code, 13, SIGSEGV) == NOTIFY_STOP) return; die("general protection fault", regs, error_code); }
void signal_fault(struct pt_regs *regs, void __user *frame, char *where) { struct task_struct *me = current; if (show_unhandled_signals && printk_ratelimit()) { printk("%s[%d] bad frame in %s frame:%p ip:%lx sp:%lx orax:%lx", me->comm,me->pid,where,frame,regs->ip,regs->sp,regs->orig_ax); print_vma_addr(" in ", regs->ip); printk("\n"); } force_sig(SIGSEGV, me); }
static inline void report_user_fault(struct pt_regs *regs, int signr) { if ((task_pid_nr(current) > 1) && !show_unhandled_signals) return; if (!unhandled_signal(current, signr)) return; if (!printk_ratelimit()) return; printk("User process fault: interruption code %04x ilc:%d ", regs->int_code & 0xffff, regs->int_code >> 17); print_vma_addr("in ", regs->psw.addr & PSW_ADDR_INSN); printk("\n"); show_regs(regs); }
static inline void report_user_fault(struct pt_regs *regs, long int_code, int signr, unsigned long address) { if ((task_pid_nr(current) > 1) && !show_unhandled_signals) return; if (!unhandled_signal(current, signr)) return; if (!printk_ratelimit()) return; printk("User process fault: interruption code 0x%lX ", int_code); print_vma_addr(KERN_CONT "in ", regs->psw.addr & PSW_ADDR_INSN); printk("\n"); printk("failing address: %lX\n", address); show_regs(regs); }
static inline void report_user_fault(struct pt_regs *regs, long signr) { if ((task_pid_nr(current) > 1) && !show_unhandled_signals) return; if (!unhandled_signal(current, signr)) return; if (!printk_ratelimit()) return; printk(KERN_ALERT "User process fault: interruption code 0x%X ", regs->int_code); print_vma_addr(KERN_CONT "in ", regs->psw.addr & PSW_ADDR_INSN); printk(KERN_CONT "\n"); printk(KERN_ALERT "failing address: %lX\n", regs->int_parm_long & __FAIL_ADDR_MASK); show_regs(regs); }
void report_user_fault(struct pt_regs *regs, long signr, int is_mm_fault) { if ((task_pid_nr(current) > 1) && !show_unhandled_signals) return; if (!unhandled_signal(current, signr)) return; if (!printk_ratelimit()) return; printk(KERN_ALERT "User process fault: interruption code %04x ilc:%d ", regs->int_code & 0xffff, regs->int_code >> 17); print_vma_addr(KERN_CONT "in ", regs->psw.addr); printk(KERN_CONT "\n"); if (is_mm_fault) dump_fault_info(regs); show_regs(regs); }
void trace_unhandled_signal(const char *type, struct pt_regs *regs, unsigned long address, int sig) { struct task_struct *tsk = current; if (show_unhandled_signals == 0) return; /* If the signal is handled, don't show it here. */ if (!is_global_init(tsk)) { void __user *handler = tsk->sighand->action[sig-1].sa.sa_handler; if (handler != SIG_IGN && handler != SIG_DFL) return; } /* Rate-limit the one-line output, not the detailed output. */ if (show_unhandled_signals <= 1 && !printk_ratelimit()) return; printk("%s%s[%d]: %s at %lx pc "REGFMT" signal %d", task_pid_nr(tsk) > 1 ? KERN_INFO : KERN_EMERG, tsk->comm, task_pid_nr(tsk), type, address, regs->pc, sig); print_vma_addr(KERN_CONT " in ", regs->pc); printk(KERN_CONT "\n"); if (show_unhandled_signals > 1) { switch (sig) { case SIGILL: case SIGFPE: case SIGSEGV: case SIGBUS: pr_err("User crash: signal %d," " trap %ld, address 0x%lx\n", sig, regs->faultnum, address); show_regs(regs); dump_mem((void __user *)address); break; default: pr_err("User crash: signal %d, trap %ld\n", sig, regs->faultnum); break; } } }
asmlinkage unsigned long sys_sigreturn(unsigned long __unused) { struct sigframe __user *frame; struct pt_regs *regs; unsigned long ax; sigset_t set; regs = (struct pt_regs *) &__unused; frame = (struct sigframe __user *)(regs->sp - 8); if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) goto badframe; if (__get_user(set.sig[0], &frame->sc.oldmask) || (_NSIG_WORDS > 1 && __copy_from_user(&set.sig[1], &frame->extramask, sizeof(frame->extramask)))) goto badframe; sigdelsetmask(&set, ~_BLOCKABLE); spin_lock_irq(¤t->sighand->siglock); current->blocked = set; recalc_sigpending(); spin_unlock_irq(¤t->sighand->siglock); if (restore_sigcontext(regs, &frame->sc, &ax)) goto badframe; return ax; badframe: if (show_unhandled_signals && printk_ratelimit()) { printk("%s%s[%d] bad frame in sigreturn frame:" "%p ip:%lx sp:%lx oeax:%lx", task_pid_nr(current) > 1 ? KERN_INFO : KERN_EMERG, current->comm, task_pid_nr(current), frame, regs->ip, regs->sp, regs->orig_ax); print_vma_addr(" in ", regs->ip); printk(KERN_CONT "\n"); } force_sig(SIGSEGV, current); return 0; }
static void show_segv_info(struct uml_pt_regs *regs) { struct task_struct *tsk = current; struct faultinfo *fi = UPT_FAULTINFO(regs); if (!unhandled_signal(tsk, SIGSEGV)) return; if (!printk_ratelimit()) return; printk("%s%s[%d]: segfault at %lx ip %p sp %p error %x", task_pid_nr(tsk) > 1 ? KERN_INFO : KERN_EMERG, tsk->comm, task_pid_nr(tsk), FAULT_ADDRESS(*fi), (void *)UPT_IP(regs), (void *)UPT_SP(regs), fi->error_code); print_vma_addr(KERN_CONT " in ", UPT_IP(regs)); printk(KERN_CONT "\n"); }
static void arm64_show_signal(int signo, const char *str) { static DEFINE_RATELIMIT_STATE(rs, DEFAULT_RATELIMIT_INTERVAL, DEFAULT_RATELIMIT_BURST); struct task_struct *tsk = current; unsigned int esr = tsk->thread.fault_code; struct pt_regs *regs = task_pt_regs(tsk); /* Leave if the signal won't be shown */ if (!show_unhandled_signals || !unhandled_signal(tsk, signo) || !__ratelimit(&rs)) return; pr_info("%s[%d]: unhandled exception: ", tsk->comm, task_pid_nr(tsk)); if (esr) pr_cont("%s, ESR 0x%08x, ", esr_get_class_string(esr), esr); pr_cont("%s", str); print_vma_addr(KERN_CONT " in ", regs->pc); pr_cont("\n"); __show_regs(regs); }
static void __kprobes do_trap(int trapnr, int signr, char *str, struct pt_regs *regs, long error_code, siginfo_t *info) { struct task_struct *tsk = current; #ifdef CONFIG_X86_32 if (regs->flags & X86_VM_MASK) { /* * traps 0, 1, 3, 4, and 5 should be forwarded to vm86. * On nmi (interrupt 2), do_trap should not be called. */ if (trapnr < 6) goto vm86_trap; goto trap_signal; } #endif if (!user_mode(regs)) goto kernel_trap; #ifdef CONFIG_X86_32 trap_signal: #endif /* * We want error_code and trap_no set for userspace faults and * kernelspace faults which result in die(), but not * kernelspace faults which are fixed up. die() gives the * process no chance to handle the signal and notice the * kernel fault information, so that won't result in polluting * the information about previously queued, but not yet * delivered, faults. See also do_general_protection below. */ tsk->thread.error_code = error_code; tsk->thread.trap_no = trapnr; #ifdef CONFIG_X86_64 if (show_unhandled_signals && unhandled_signal(tsk, signr) && printk_ratelimit()) { printk(KERN_INFO "%s[%d] trap %s ip:%lx sp:%lx error:%lx", tsk->comm, tsk->pid, str, regs->ip, regs->sp, error_code); print_vma_addr(" in ", regs->ip); printk("\n"); } #endif if (info) force_sig_info(signr, info, tsk); else force_sig(signr, tsk); return; kernel_trap: if (!fixup_exception(regs)) { tsk->thread.error_code = error_code; tsk->thread.trap_no = trapnr; die(str, regs, error_code); } return; #ifdef CONFIG_X86_32 vm86_trap: if (handle_vm86_trap((struct kernel_vm86_regs *) regs, error_code, trapnr)) goto trap_signal; return; #endif }
dotraplinkage void __kprobes do_general_protection(struct pt_regs *regs, long error_code) { struct task_struct *tsk; conditional_sti(regs); #ifdef CONFIG_X86_32 if (regs->flags & X86_VM_MASK) goto gp_in_vm86; #endif tsk = current; if (!user_mode(regs)) goto gp_in_kernel; #ifdef CONFIG_X86_32 { int cpu; int ok; cpu = get_cpu(); ok = check_lazy_exec_limit(cpu, regs, error_code); put_cpu(); if (ok) return; if (print_fatal_signals) { printk(KERN_ERR "#GPF(%ld[seg:%lx]) at %08lx, CPU#%d.\n", error_code, error_code/8, regs->ip, smp_processor_id()); printk(KERN_ERR "exec_limit: %08lx, user_cs: %08x/%08x.\n", current->mm->context.exec_limit, current->mm->context.user_cs.a, current->mm->context.user_cs.b); } } #endif /*CONFIG_X86_32*/ tsk->thread.error_code = error_code; tsk->thread.trap_no = 13; if (show_unhandled_signals && unhandled_signal(tsk, SIGSEGV) && printk_ratelimit()) { printk(KERN_INFO "%s[%d] general protection ip:%lx sp:%lx error:%lx", tsk->comm, task_pid_nr(tsk), regs->ip, regs->sp, error_code); print_vma_addr(" in ", regs->ip); printk("\n"); } force_sig(SIGSEGV, tsk); return; #ifdef CONFIG_X86_32 gp_in_vm86: local_irq_enable(); handle_vm86_fault((struct kernel_vm86_regs *) regs, error_code); return; #endif gp_in_kernel: if (fixup_exception(regs)) return; tsk->thread.error_code = error_code; tsk->thread.trap_no = 13; if (notify_die(DIE_GPF, "general protection fault", regs, error_code, 13, SIGSEGV) == NOTIFY_STOP) return; die("general protection fault", regs, error_code); }
dotraplinkage void __kprobes do_general_protection(struct pt_regs *regs, long error_code) { struct task_struct *tsk; conditional_sti(regs); #ifdef CONFIG_X86_32 if (v8086_mode(regs)) goto gp_in_vm86; #endif tsk = current; if (!user_mode_novm(regs)) goto gp_in_kernel; #if defined(CONFIG_X86_32) && defined(CONFIG_PAX_PAGEEXEC) if (!nx_enabled && tsk->mm && (tsk->mm->pax_flags & MF_PAX_PAGEEXEC)) { struct mm_struct *mm = tsk->mm; unsigned long limit; down_write(&mm->mmap_sem); limit = mm->context.user_cs_limit; if (limit < TASK_SIZE) { track_exec_limit(mm, limit, TASK_SIZE, VM_EXEC); up_write(&mm->mmap_sem); return; } up_write(&mm->mmap_sem); } #endif tsk->thread.error_code = error_code; tsk->thread.trap_no = 13; if (show_unhandled_signals && unhandled_signal(tsk, SIGSEGV) && printk_ratelimit()) { printk(KERN_INFO "%s[%d] general protection ip:%lx sp:%lx error:%lx", tsk->comm, task_pid_nr(tsk), regs->ip, regs->sp, error_code); print_vma_addr(" in ", regs->ip); printk("\n"); } force_sig(SIGSEGV, tsk); return; #ifdef CONFIG_X86_32 gp_in_vm86: local_irq_enable(); handle_vm86_fault((struct kernel_vm86_regs *) regs, error_code); return; #endif gp_in_kernel: if (fixup_exception(regs)) return; tsk->thread.error_code = error_code; tsk->thread.trap_no = 13; if (notify_die(DIE_GPF, "general protection fault", regs, error_code, 13, SIGSEGV) == NOTIFY_STOP) return; #if defined(CONFIG_X86_32) && defined(CONFIG_PAX_KERNEXEC) if ((regs->cs & 0xFFFF) == __KERNEL_CS) die("PAX: suspicious general protection fault", regs, error_code); else #endif die("general protection fault", regs, error_code); }
static void __kprobes do_trap(int trapnr, int signr, const char *str, struct pt_regs *regs, long error_code, siginfo_t *info) { struct task_struct *tsk = current; #ifdef CONFIG_X86_32 if (v8086_mode(regs)) { /* * traps 0, 1, 3, 4, and 5 should be forwarded to vm86. * On nmi (interrupt 2), do_trap should not be called. */ if (trapnr < 6) goto vm86_trap; goto trap_signal; } #endif if (!user_mode_novm(regs)) goto kernel_trap; #ifdef CONFIG_X86_32 trap_signal: #endif /* * We want error_code and trap_no set for userspace faults and * kernelspace faults which result in die(), but not * kernelspace faults which are fixed up. die() gives the * process no chance to handle the signal and notice the * kernel fault information, so that won't result in polluting * the information about previously queued, but not yet * delivered, faults. See also do_general_protection below. */ tsk->thread.error_code = error_code; tsk->thread.trap_no = trapnr; #ifdef CONFIG_X86_64 if (show_unhandled_signals && unhandled_signal(tsk, signr) && printk_ratelimit()) { printk(KERN_INFO "%s[%d] trap %s ip:%lx sp:%lx error:%lx", tsk->comm, task_pid_nr(tsk), str, regs->ip, regs->sp, error_code); print_vma_addr(" in ", regs->ip); printk("\n"); } #endif if (info) force_sig_info(signr, info, tsk); else force_sig(signr, tsk); return; kernel_trap: if (!fixup_exception(regs)) { tsk->thread.error_code = error_code; tsk->thread.trap_no = trapnr; #if defined(CONFIG_X86_32) && defined(CONFIG_PAX_KERNEXEC) if (trapnr == 12 && ((regs->cs & 0xFFFF) == __KERNEL_CS || (regs->cs & 0xFFFF) == __KERNEXEC_KERNEL_CS)) str = "PAX: suspicious stack segment fault"; #endif die(str, regs, error_code); } #ifdef CONFIG_PAX_REFCOUNT if (trapnr == 4) pax_report_refcount_overflow(regs); #endif return; #ifdef CONFIG_X86_32 vm86_trap: if (handle_vm86_trap((struct kernel_vm86_regs *) regs, error_code, trapnr)) goto trap_signal; return; #endif }