On 8/12/06, Paul Mackerras <[EMAIL PROTECTED]> wrote:
Of course, that won't make all that much difference on your Cube, because the G4 CPU doesn't have hardware support for non-executable pages (any readable page is executable).
I now have an evil grin, and a kernel that prevents execution from the stack. It passes that one part of paxtest now. If the -msecure-plt actually did something (it's a nop according to md5sum) and the executable mappings didn't share with other ones, I'd have it all protected. Signed-off-by: Albert Cahalan --------- --- linux-2.6.17-rc5/arch/powerpc/kernel/head_32.S 2006-05-24 21:50:17.000000000 -0400 +++ linux-17rc5-secure/arch/powerpc/kernel/head_32.S 2006-08-13 10:48:38.000000000 -0400 @@ -1182,7 +1182,7 @@ _GLOBAL(set_context) mulli r3,r3,897 /* multiply context by skew factor */ rlwinm r3,r3,4,8,27 /* VSID = (context & 0xfffff) << 4 */ - addis r3,r3,0x6000 /* Set Ks, Ku bits */ + addis r3,r3,0x7000 /* Set Ks, Ku, N bits */ li r0,NUM_USER_SEGMENTS mtctr r0 --- linux-2.6.17-rc5/arch/powerpc/mm/fault.c 2006-05-24 21:50:17.000000000 -0400 +++ linux-17rc5-secure/arch/powerpc/mm/fault.c 2006-08-13 19:17:22.000000000 -0400 @@ -134,8 +134,8 @@ * bits we are interested in. But there are some bits which * indicate errors in DSISR but can validly be set in SRR1. */ - if (trap == 0x400) - error_code &= 0x48200000; + if (is_exec) + error_code &= 0x58200000; else is_write = error_code & DSISR_ISSTORE; #else @@ -242,7 +242,7 @@ good_area: code = SEGV_ACCERR; #if defined(CONFIG_6xx) - if (error_code & 0x95700000) + if (error_code & 0x85700000) /* an error such as lwarx to I/O controller space, address matching DABR, eciwx, etc. */ goto bad_area; @@ -258,12 +258,24 @@ #endif /* CONFIG_8xx */ if (is_exec) { + if (!(vma->vm_flags & VM_EXEC)) { +#if 0 + static __typeof__(jiffies) oldjif; + static int count; + if(count++ < 5) + printk(KERN_CRIT "fuckup @ %08lx with trap 0x%x code %08lx by %s\n", + address, trap, error_code, current->comm); + if(jiffies/(HZ*15) != oldjif/(HZ*15)) { + oldjif = jiffies; + count = 0; + } +#endif + goto bad_area; + } #ifdef CONFIG_PPC64 /* protection fault */ if (error_code & DSISR_PROTFAULT) goto bad_area; - if (!(vma->vm_flags & VM_EXEC)) - goto bad_area; #endif #if defined(CONFIG_4xx) || defined(CONFIG_BOOKE) pte_t *ptep; @@ -291,6 +303,27 @@ pte_unmap_unlock(ptep, ptl); } #endif +#if !defined(CONFIG_4xx) && !defined(CONFIG_BOOKE) && !defined(CONFIG_PPC64) + if (!(error_code & 0x10000000)) + goto survive; + /* It was an ISI exception with SRR1 bit 3 set. + * We have no-execute bits in the 256 MiB segments. + * We sometimes take faults to turn the bits on. + * Faults happen when the user executes from guarded mem, + * no-execute segment, or (extinct) direct-store segment. + * The segment-related faults happen first. */ + unsigned segreg; + __asm__ __volatile__("mfsrin %0,%1":"=r"(segreg):"r"(address)); + /* if current segment is no-execute but not direct-store */ + if (segreg>>28==7) { + /* clear the N bit to make it executable */ + segreg &= 0x6fffffff; + __asm__ __volatile__("mtsrin %0,%1"::"r"(segreg),"r"(address)); + /* TODO: as this one goes executable, make other segments not */ + up_read(&mm->mmap_sem); + return 0; + } +#endif /* a write */ } else if (is_write) { if (!(vma->vm_flags & VM_WRITE)) @@ -300,7 +333,7 @@ /* protection fault */ if (error_code & 0x08000000) goto bad_area; - if (!(vma->vm_flags & (VM_READ | VM_EXEC))) + if (!(vma->vm_flags & (VM_READ | VM_EXEC))) /* VM_EXEC wrong for ppc32? */ goto bad_area; } --- linux-2.6.17-rc5/include/asm-powerpc/page.h 2006-05-24 21:50:17.000000000 -0400 +++ linux-17rc5-secure/include/asm-powerpc/page.h 2006-08-13 11:58:25.000000000 -0400 @@ -90,6 +90,9 @@ #define VM_DATA_DEFAULT_FLAGS64 (VM_READ | VM_WRITE | \ VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) +#define VM_STACK_DEFAULT_FLAGS (VM_READ | VM_WRITE | \ + VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) + #ifdef __powerpc64__ #include <asm/page_64.h> #else -- To UNSUBSCRIBE, email to [EMAIL PROTECTED] with a subject of "unsubscribe". Trouble? Contact [EMAIL PROTECTED]