In older versions of glibc (through 2.3), the dynamic linker executes a small amount of code from the data segment, which is not marked as executable. A recent change (commit 9ba4ace39fdfe22268daca9f28c5df384ae462cf) stops this from working; there should be a deprecation period before older glibc versions stop working.
The problem has been observed on glibc 2.2. While glibc 2.3 has the same code, I did not see the problem; it may be that it accesses the page in question as data before executing from it, and thus it is already mapped. Note that this only applies to the classic 32-bit PowerPC MMU and the MPC8xx MMU, not Book E, 64-bit, etc. These MMUs do not support per-page no-exec, and thus this patch isn't taking away any effective protection enforcement. Currently, such accesses will fail only if the page in question has not already been faulted on (and thus mapped). Signed-off-by: Scott Wood <[EMAIL PROTECTED]> --- v2: Added to the changelog to explain why this change isn't harmful. arch/powerpc/mm/fault.c | 22 +++++++++++++++++++++- 1 files changed, 21 insertions(+), 1 deletions(-) diff --git a/arch/powerpc/mm/fault.c b/arch/powerpc/mm/fault.c index 0ece513..2445512 100644 --- a/arch/powerpc/mm/fault.c +++ b/arch/powerpc/mm/fault.c @@ -125,6 +125,18 @@ static void do_dabr(struct pt_regs *regs, unsigned long address, } #endif /* !(CONFIG_4xx || CONFIG_BOOKE)*/ +#ifdef CONFIG_PPC32 +static void warn_exec_from_noexec(void) +{ + if (printk_ratelimit()) + printk(KERN_WARNING "Process %s (%d) attempted to execute from " + "a non-executable page.\n" + KERN_WARNING "This may stop working in future kernels. " + "Please upgrade your libc.\n", + current->comm, current->pid); +} +#endif + /* * For 600- and 800-family processors, the error_code parameter is DSISR * for a data fault, SRR1 for an instruction fault. For 400-family processors @@ -283,8 +295,16 @@ good_area: /* protection fault */ if (error_code & DSISR_PROTFAULT) goto bad_area; - if (!(vma->vm_flags & VM_EXEC)) + if (!(vma->vm_flags & VM_EXEC)) { +#ifdef CONFIG_PPC32 + if (vma->vm_flags & VM_READ) + warn_exec_from_noexec(); + else + goto bad_area; +#else goto bad_area; +#endif + } #else pte_t *ptep; pmd_t *pmdp; -- 1.5.0.3 _______________________________________________ Linuxppc-dev mailing list Linuxppc-dev@ozlabs.org https://ozlabs.org/mailman/listinfo/linuxppc-dev