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.

Signed-off-by: Scott Wood <[EMAIL PROTECTED]>
---
Unfortunately, this didn't make it into 2.6.22, but it should probably go
into the stable branch...

 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

Reply via email to