X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=arch%2Fppc64%2Fmm%2Ffault.c;h=20b0f37e8bf8fbe3ac28c2f0113a97b6aa951675;hb=f7f1b0f1e2fbadeab12d24236000e778aa9b1ead;hp=2b383974a8f32680b4f3112d55b370fdae0b3d97;hpb=e3f6fb6212a7102bdb56ba38fa1e98fe72950475;p=linux-2.6.git diff --git a/arch/ppc64/mm/fault.c b/arch/ppc64/mm/fault.c index 2b383974a..20b0f37e8 100644 --- a/arch/ppc64/mm/fault.c +++ b/arch/ppc64/mm/fault.c @@ -91,8 +91,9 @@ int do_page_fault(struct pt_regs *regs, unsigned long address, struct mm_struct *mm = current->mm; siginfo_t info; unsigned long code = SEGV_MAPERR; - unsigned long is_write = error_code & 0x02000000; + unsigned long is_write = error_code & DSISR_ISSTORE; unsigned long trap = TRAP(regs); + unsigned long is_exec = trap == 0x400; BUG_ON((trap == 0x380) || (trap == 0x480)); @@ -109,7 +110,7 @@ int do_page_fault(struct pt_regs *regs, unsigned long address, if (!user_mode(regs) && (address >= TASK_SIZE)) return SIGSEGV; - if (error_code & 0x00400000) { + if (error_code & DSISR_DABRMATCH) { if (notify_die(DIE_DABR_MATCH, "dabr_match", regs, error_code, 11, SIGSEGV) == NOTIFY_STOP) return 0; @@ -199,16 +200,19 @@ int do_page_fault(struct pt_regs *regs, unsigned long address, good_area: code = SEGV_ACCERR; + if (is_exec) { + /* protection fault */ + if (error_code & DSISR_PROTFAULT) + goto bad_area; + if (!(vma->vm_flags & VM_EXEC)) + goto bad_area; /* a write */ - if (is_write) { + } else if (is_write) { if (!(vma->vm_flags & VM_WRITE)) goto bad_area; /* a read */ } else { - /* protection fault */ - if (error_code & 0x08000000) - goto bad_area; - if (!(vma->vm_flags & (VM_READ | VM_EXEC))) + if (!(vma->vm_flags & VM_READ)) goto bad_area; } @@ -251,6 +255,12 @@ bad_area_nosemaphore: return 0; } + if (trap == 0x400 && (error_code & DSISR_PROTFAULT) + && printk_ratelimit()) + printk(KERN_CRIT "kernel tried to execute NX-protected" + " page (%lx) - exploit attempt? (uid: %d)\n", + address, current->uid); + return SIGSEGV; /*