diff options
-rw-r--r-- | arch/x86/kernel/signal_32.c | 7 | ||||
-rw-r--r-- | arch/x86/kernel/signal_64.c | 7 | ||||
-rw-r--r-- | arch/x86/kernel/traps_32.c | 7 | ||||
-rw-r--r-- | arch/x86/kernel/traps_64.c | 14 | ||||
-rw-r--r-- | arch/x86/mm/fault_32.c | 4 | ||||
-rw-r--r-- | arch/x86/mm/fault_64.c | 4 | ||||
-rw-r--r-- | include/linux/mm.h | 1 | ||||
-rw-r--r-- | mm/memory.c | 31 |
8 files changed, 63 insertions, 12 deletions
diff --git a/arch/x86/kernel/signal_32.c b/arch/x86/kernel/signal_32.c index 74df55895c8c..89a690edf999 100644 --- a/arch/x86/kernel/signal_32.c +++ b/arch/x86/kernel/signal_32.c | |||
@@ -198,12 +198,15 @@ asmlinkage int sys_sigreturn(unsigned long __unused) | |||
198 | return ax; | 198 | return ax; |
199 | 199 | ||
200 | badframe: | 200 | badframe: |
201 | if (show_unhandled_signals && printk_ratelimit()) | 201 | if (show_unhandled_signals && printk_ratelimit()) { |
202 | printk("%s%s[%d] bad frame in sigreturn frame:%p ip:%lx" | 202 | printk("%s%s[%d] bad frame in sigreturn frame:%p ip:%lx" |
203 | " sp:%lx oeax:%lx\n", | 203 | " sp:%lx oeax:%lx", |
204 | task_pid_nr(current) > 1 ? KERN_INFO : KERN_EMERG, | 204 | task_pid_nr(current) > 1 ? KERN_INFO : KERN_EMERG, |
205 | current->comm, task_pid_nr(current), frame, regs->ip, | 205 | current->comm, task_pid_nr(current), frame, regs->ip, |
206 | regs->sp, regs->orig_ax); | 206 | regs->sp, regs->orig_ax); |
207 | print_vma_addr(" in ", regs->ip); | ||
208 | printk("\n"); | ||
209 | } | ||
207 | 210 | ||
208 | force_sig(SIGSEGV, current); | 211 | force_sig(SIGSEGV, current); |
209 | return 0; | 212 | return 0; |
diff --git a/arch/x86/kernel/signal_64.c b/arch/x86/kernel/signal_64.c index 4eb751c60390..7347bb14e306 100644 --- a/arch/x86/kernel/signal_64.c +++ b/arch/x86/kernel/signal_64.c | |||
@@ -484,9 +484,12 @@ do_notify_resume(struct pt_regs *regs, void *unused, __u32 thread_info_flags) | |||
484 | void signal_fault(struct pt_regs *regs, void __user *frame, char *where) | 484 | void signal_fault(struct pt_regs *regs, void __user *frame, char *where) |
485 | { | 485 | { |
486 | struct task_struct *me = current; | 486 | struct task_struct *me = current; |
487 | if (show_unhandled_signals && printk_ratelimit()) | 487 | if (show_unhandled_signals && printk_ratelimit()) { |
488 | printk("%s[%d] bad frame in %s frame:%p ip:%lx sp:%lx orax:%lx\n", | 488 | printk("%s[%d] bad frame in %s frame:%p ip:%lx sp:%lx orax:%lx", |
489 | me->comm,me->pid,where,frame,regs->ip,regs->sp,regs->orig_ax); | 489 | me->comm,me->pid,where,frame,regs->ip,regs->sp,regs->orig_ax); |
490 | print_vma_addr(" in ", regs->ip); | ||
491 | printk("\n"); | ||
492 | } | ||
490 | 493 | ||
491 | force_sig(SIGSEGV, me); | 494 | force_sig(SIGSEGV, me); |
492 | } | 495 | } |
diff --git a/arch/x86/kernel/traps_32.c b/arch/x86/kernel/traps_32.c index 6f3bb287c702..270cfd483160 100644 --- a/arch/x86/kernel/traps_32.c +++ b/arch/x86/kernel/traps_32.c | |||
@@ -609,11 +609,14 @@ void __kprobes do_general_protection(struct pt_regs * regs, | |||
609 | current->thread.error_code = error_code; | 609 | current->thread.error_code = error_code; |
610 | current->thread.trap_no = 13; | 610 | current->thread.trap_no = 13; |
611 | if (show_unhandled_signals && unhandled_signal(current, SIGSEGV) && | 611 | if (show_unhandled_signals && unhandled_signal(current, SIGSEGV) && |
612 | printk_ratelimit()) | 612 | printk_ratelimit()) { |
613 | printk(KERN_INFO | 613 | printk(KERN_INFO |
614 | "%s[%d] general protection ip:%lx sp:%lx error:%lx\n", | 614 | "%s[%d] general protection ip:%lx sp:%lx error:%lx", |
615 | current->comm, task_pid_nr(current), | 615 | current->comm, task_pid_nr(current), |
616 | regs->ip, regs->sp, error_code); | 616 | regs->ip, regs->sp, error_code); |
617 | print_vma_addr(" in ", regs->ip); | ||
618 | printk("\n"); | ||
619 | } | ||
617 | 620 | ||
618 | force_sig(SIGSEGV, current); | 621 | force_sig(SIGSEGV, current); |
619 | return; | 622 | return; |
diff --git a/arch/x86/kernel/traps_64.c b/arch/x86/kernel/traps_64.c index 814801f4eb9e..911ed28afff8 100644 --- a/arch/x86/kernel/traps_64.c +++ b/arch/x86/kernel/traps_64.c | |||
@@ -642,11 +642,14 @@ static void __kprobes do_trap(int trapnr, int signr, char *str, | |||
642 | tsk->thread.trap_no = trapnr; | 642 | tsk->thread.trap_no = trapnr; |
643 | 643 | ||
644 | if (show_unhandled_signals && unhandled_signal(tsk, signr) && | 644 | if (show_unhandled_signals && unhandled_signal(tsk, signr) && |
645 | printk_ratelimit()) | 645 | printk_ratelimit()) { |
646 | printk(KERN_INFO | 646 | printk(KERN_INFO |
647 | "%s[%d] trap %s ip:%lx sp:%lx error:%lx\n", | 647 | "%s[%d] trap %s ip:%lx sp:%lx error:%lx", |
648 | tsk->comm, tsk->pid, str, | 648 | tsk->comm, tsk->pid, str, |
649 | regs->ip, regs->sp, error_code); | 649 | regs->ip, regs->sp, error_code); |
650 | print_vma_addr(" in ", regs->ip); | ||
651 | printk("\n"); | ||
652 | } | ||
650 | 653 | ||
651 | if (info) | 654 | if (info) |
652 | force_sig_info(signr, info, tsk); | 655 | force_sig_info(signr, info, tsk); |
@@ -741,11 +744,14 @@ asmlinkage void __kprobes do_general_protection(struct pt_regs * regs, | |||
741 | tsk->thread.trap_no = 13; | 744 | tsk->thread.trap_no = 13; |
742 | 745 | ||
743 | if (show_unhandled_signals && unhandled_signal(tsk, SIGSEGV) && | 746 | if (show_unhandled_signals && unhandled_signal(tsk, SIGSEGV) && |
744 | printk_ratelimit()) | 747 | printk_ratelimit()) { |
745 | printk(KERN_INFO | 748 | printk(KERN_INFO |
746 | "%s[%d] general protection ip:%lx sp:%lx error:%lx\n", | 749 | "%s[%d] general protection ip:%lx sp:%lx error:%lx", |
747 | tsk->comm, tsk->pid, | 750 | tsk->comm, tsk->pid, |
748 | regs->ip, regs->sp, error_code); | 751 | regs->ip, regs->sp, error_code); |
752 | print_vma_addr(" in ", regs->ip); | ||
753 | printk("\n"); | ||
754 | } | ||
749 | 755 | ||
750 | force_sig(SIGSEGV, tsk); | 756 | force_sig(SIGSEGV, tsk); |
751 | return; | 757 | return; |
diff --git a/arch/x86/mm/fault_32.c b/arch/x86/mm/fault_32.c index 13d295506a17..276863dc4bdd 100644 --- a/arch/x86/mm/fault_32.c +++ b/arch/x86/mm/fault_32.c | |||
@@ -514,11 +514,13 @@ bad_area_nosemaphore: | |||
514 | #ifdef CONFIG_X86_32 | 514 | #ifdef CONFIG_X86_32 |
515 | "%s%s[%d]: segfault at %lx ip %08lx sp %08lx error %lx", | 515 | "%s%s[%d]: segfault at %lx ip %08lx sp %08lx error %lx", |
516 | #else | 516 | #else |
517 | "%s%s[%d]: segfault at %lx ip %lx sp %lx error %lx\n", | 517 | "%s%s[%d]: segfault at %lx ip %lx sp %lx error %lx", |
518 | #endif | 518 | #endif |
519 | task_pid_nr(tsk) > 1 ? KERN_INFO : KERN_EMERG, | 519 | task_pid_nr(tsk) > 1 ? KERN_INFO : KERN_EMERG, |
520 | tsk->comm, task_pid_nr(tsk), address, regs->ip, | 520 | tsk->comm, task_pid_nr(tsk), address, regs->ip, |
521 | regs->sp, error_code); | 521 | regs->sp, error_code); |
522 | print_vma_addr(" in ", regs->ip); | ||
523 | printk("\n"); | ||
522 | } | 524 | } |
523 | tsk->thread.cr2 = address; | 525 | tsk->thread.cr2 = address; |
524 | /* Kernel addresses are always protection faults */ | 526 | /* Kernel addresses are always protection faults */ |
diff --git a/arch/x86/mm/fault_64.c b/arch/x86/mm/fault_64.c index b606bdefbb72..9ef0306efe9e 100644 --- a/arch/x86/mm/fault_64.c +++ b/arch/x86/mm/fault_64.c | |||
@@ -552,11 +552,13 @@ bad_area_nosemaphore: | |||
552 | #ifdef CONFIG_X86_32 | 552 | #ifdef CONFIG_X86_32 |
553 | "%s%s[%d]: segfault at %lx ip %08lx sp %08lx error %lx", | 553 | "%s%s[%d]: segfault at %lx ip %08lx sp %08lx error %lx", |
554 | #else | 554 | #else |
555 | "%s%s[%d]: segfault at %lx ip %lx sp %lx error %lx\n", | 555 | "%s%s[%d]: segfault at %lx ip %lx sp %lx error %lx", |
556 | #endif | 556 | #endif |
557 | task_pid_nr(tsk) > 1 ? KERN_INFO : KERN_EMERG, | 557 | task_pid_nr(tsk) > 1 ? KERN_INFO : KERN_EMERG, |
558 | tsk->comm, task_pid_nr(tsk), address, regs->ip, | 558 | tsk->comm, task_pid_nr(tsk), address, regs->ip, |
559 | regs->sp, error_code); | 559 | regs->sp, error_code); |
560 | print_vma_addr(" in ", regs->ip); | ||
561 | printk("\n"); | ||
560 | } | 562 | } |
561 | 563 | ||
562 | tsk->thread.cr2 = address; | 564 | tsk->thread.cr2 = address; |
diff --git a/include/linux/mm.h b/include/linux/mm.h index 1897ca223eca..3c22d971afa7 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h | |||
@@ -1146,6 +1146,7 @@ extern int randomize_va_space; | |||
1146 | #endif | 1146 | #endif |
1147 | 1147 | ||
1148 | const char * arch_vma_name(struct vm_area_struct *vma); | 1148 | const char * arch_vma_name(struct vm_area_struct *vma); |
1149 | void print_vma_addr(char *prefix, unsigned long rip); | ||
1149 | 1150 | ||
1150 | struct page *sparse_mem_map_populate(unsigned long pnum, int nid); | 1151 | struct page *sparse_mem_map_populate(unsigned long pnum, int nid); |
1151 | pgd_t *vmemmap_pgd_populate(unsigned long addr, int node); | 1152 | pgd_t *vmemmap_pgd_populate(unsigned long addr, int node); |
diff --git a/mm/memory.c b/mm/memory.c index 673ebbf499c7..d902d0e25edc 100644 --- a/mm/memory.c +++ b/mm/memory.c | |||
@@ -2754,3 +2754,34 @@ int access_process_vm(struct task_struct *tsk, unsigned long addr, void *buf, in | |||
2754 | 2754 | ||
2755 | return buf - old_buf; | 2755 | return buf - old_buf; |
2756 | } | 2756 | } |
2757 | |||
2758 | /* | ||
2759 | * Print the name of a VMA. | ||
2760 | */ | ||
2761 | void print_vma_addr(char *prefix, unsigned long ip) | ||
2762 | { | ||
2763 | struct mm_struct *mm = current->mm; | ||
2764 | struct vm_area_struct *vma; | ||
2765 | |||
2766 | down_read(&mm->mmap_sem); | ||
2767 | vma = find_vma(mm, ip); | ||
2768 | if (vma && vma->vm_file) { | ||
2769 | struct file *f = vma->vm_file; | ||
2770 | char *buf = (char *)__get_free_page(GFP_KERNEL); | ||
2771 | if (buf) { | ||
2772 | char *p, *s; | ||
2773 | |||
2774 | p = d_path(f->f_dentry, f->f_vfsmnt, buf, PAGE_SIZE); | ||
2775 | if (IS_ERR(p)) | ||
2776 | p = "?"; | ||
2777 | s = strrchr(p, '/'); | ||
2778 | if (s) | ||
2779 | p = s+1; | ||
2780 | printk("%s%s[%lx+%lx]", prefix, p, | ||
2781 | vma->vm_start, | ||
2782 | vma->vm_end - vma->vm_start); | ||
2783 | free_page((unsigned long)buf); | ||
2784 | } | ||
2785 | } | ||
2786 | up_read(¤t->mm->mmap_sem); | ||
2787 | } | ||