]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Handle the PROT_GROWSDOWN and PROT_GROWSUP mprotect flags properly
authorTom Hughes <tom@compton.nu>
Tue, 8 Nov 2005 16:51:55 +0000 (16:51 +0000)
committerTom Hughes <tom@compton.nu>
Tue, 8 Nov 2005 16:51:55 +0000 (16:51 +0000)
which stops glibc falling over when a program requires an executable
stack and glibc has been built to assume that PROT_GROWSDOWN will work.

git-svn-id: svn://svn.valgrind.org/valgrind/trunk@5041

coregrind/m_syswrap/syswrap-generic.c
include/vki-amd64-linux.h
include/vki-ppc32-linux.h
include/vki-x86-linux.h

index 4c2bd7b14bf46fbd35d5b4003f6d7d303817ab6c..0b5e10bb6095c98720e136403db0f08a498da510 100644 (file)
@@ -4552,8 +4552,43 @@ PRE(sys_mprotect)
    PRE_REG_READ3(long, "mprotect",
                  unsigned long, addr, vki_size_t, len, unsigned long, prot);
 
-   if (!ML_(valid_client_addr)(ARG1, ARG2, tid, "mprotect"))
+   if (!ML_(valid_client_addr)(ARG1, ARG2, tid, "mprotect")) {
       SET_STATUS_Failure( VKI_ENOMEM );
+   } else if (ARG3 & (VKI_PROT_GROWSDOWN|VKI_PROT_GROWSUP)) {
+      UInt grows = ARG3 & (VKI_PROT_GROWSDOWN|VKI_PROT_GROWSUP);
+      NSegment *aseg = VG_(am_find_nsegment)(ARG1);
+      NSegment *rseg;
+
+      vg_assert(aseg);
+
+      if (grows == VKI_PROT_GROWSDOWN) {
+         rseg = VG_(am_next_nsegment)( aseg, False/*backwards*/ );
+         if (rseg &&
+             rseg->kind == SkResvn &&
+             rseg->smode == SmUpper &&
+             rseg->end+1 == aseg->start) {
+            Addr end = ARG1 + ARG2;
+            ARG1 = aseg->start;
+            ARG2 = end - aseg->start;
+            ARG3 &= ~VKI_PROT_GROWSDOWN;
+         } else {
+            SET_STATUS_Failure( VKI_EINVAL );
+         }
+      } else if (grows == VKI_PROT_GROWSUP) {
+         rseg = VG_(am_next_nsegment)( aseg, True/*forwards*/ );
+         if (rseg &&
+             rseg->kind == SkResvn &&
+             rseg->smode == SmLower &&
+             aseg->end+1 == rseg->start) {
+            ARG2 = aseg->end - ARG1 + 1;
+            ARG3 &= ~VKI_PROT_GROWSUP;
+         } else {
+            SET_STATUS_Failure( VKI_EINVAL );
+         }
+      } else {
+         SET_STATUS_Failure( VKI_EINVAL );
+      }
+   }
 }
 
 POST(sys_mprotect)
index e4277ad3840a5f67af94d30cb1fab2c447a5e289..79f96a432df68525fe54405c6a4481aaf0d72760 100644 (file)
@@ -216,6 +216,8 @@ struct vki_sigcontext {
 #define VKI_PROT_WRITE 0x2             /* page can be written */
 #define VKI_PROT_EXEC  0x4             /* page can be executed */
 #define VKI_PROT_NONE  0x0             /* page can not be accessed */
+#define VKI_PROT_GROWSDOWN     0x01000000      /* mprotect flag: extend change to start of growsdown vma */
+#define VKI_PROT_GROWSUP       0x02000000      /* mprotect flag: extend change to end of growsup vma */
 
 #define VKI_MAP_SHARED 0x01            /* Share changes */
 #define VKI_MAP_PRIVATE        0x02            /* Changes are private */
index 7f8b752d0061a8b41695d6157722fcebdf842f54..d5ade89dc7a1815ef3139fa51354f1fa095912d9 100644 (file)
@@ -237,6 +237,8 @@ struct vki_sigcontext {
 #define VKI_PROT_READ          0x1      /* page can be read */
 #define VKI_PROT_WRITE         0x2      /* page can be written */
 #define VKI_PROT_EXEC          0x4      /* page can be executed */
+#define VKI_PROT_GROWSDOWN     0x01000000      /* mprotect flag: extend change to start of growsdown vma */
+#define VKI_PROT_GROWSUP       0x02000000      /* mprotect flag: extend change to end of growsup vma */
 
 #define VKI_MAP_SHARED         0x01     /* Share changes */
 #define VKI_MAP_PRIVATE                0x02     /* Changes are private */
index ae73305aead74650fff7d3f85a8a8252d99a3620..5d8d3296cc1fab36de10a83c420ea15ea7da304f 100644 (file)
@@ -246,6 +246,8 @@ struct vki_sigcontext {
 #define VKI_PROT_READ  0x1             /* page can be read */
 #define VKI_PROT_WRITE 0x2             /* page can be written */
 #define VKI_PROT_EXEC  0x4             /* page can be executed */
+#define VKI_PROT_GROWSDOWN     0x01000000      /* mprotect flag: extend change to start of growsdown vma */
+#define VKI_PROT_GROWSUP       0x02000000      /* mprotect flag: extend change to end of growsup vma */
 
 #define VKI_MAP_SHARED 0x01            /* Share changes */
 #define VKI_MAP_PRIVATE        0x02            /* Changes are private */