]> git.ipfire.org Git - thirdparty/glibc.git/blobdiff - elf/check-textrel.c
conformtest: Update expectations for some ISO C headers.
[thirdparty/glibc.git] / elf / check-textrel.c
index c0592a2336bf286f7d78520ca7e16dd0963d0f9b..6372019a9cf9812611e23a75c031495b88500614 100644 (file)
@@ -1,5 +1,5 @@
 /* Check for text relocations in DSOs.
-   Copyright (C) 2002 Free Software Foundation, Inc.
+   Copyright (C) 2002, 2003, 2006 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contribute by Ulrich Drepper <drepper@redhat.com>. 2002.
 
@@ -14,9 +14,8 @@
    Lesser General Public License for more details.
 
    You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, write to the Free
-   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-   02111-1307 USA.  */
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
 
 #include <byteswap.h>
 #include <elf.h>
 # define __E(name, bits) Elf##bits##_##name
 # define SWAP(val) \
   ({ __typeof (val) __res;                                                   \
-     if ((ehdr.e_ident[EI_DATA] == ELFDATA2MSB && BYTE_ORDER == LITTLE_ENDIAN \
-         || ehdr.e_ident[EI_DATA] == ELFDATA2LSB && BYTE_ORDER == BIG_ENDIAN)\
+     if (((ehdr.e_ident[EI_DATA] == ELFDATA2MSB                                      \
+          && BYTE_ORDER == LITTLE_ENDIAN)                                    \
+         || (ehdr.e_ident[EI_DATA] == ELFDATA2LSB                            \
+             && BYTE_ORDER == BIG_ENDIAN))                                   \
         && sizeof (val) != 1)                                                \
        {                                                                     \
         if (sizeof (val) == 2)                                               \
@@ -77,20 +78,36 @@ AB(handle_file) (const char *fname, int fd)
 
   /* Search for the PT_DYNAMIC entry.  */
   size_t cnt;
+  E(Phdr) *dynphdr = NULL;
   for (cnt = 0; cnt < phnum; ++cnt)
-    if (phdr[cnt].p_type == PT_DYNAMIC)
-      break;
+    if (SWAP (phdr[cnt].p_type) == PT_DYNAMIC)
+      dynphdr = &phdr[cnt];
+    else if (SWAP (phdr[cnt].p_type) == PT_LOAD
+            && (SWAP (phdr[cnt].p_flags) & (PF_X | PF_W)) == (PF_X | PF_W))
+      {
+       printf ("%s: segment %zu is executable and writable\n",
+               fname, cnt);
+#if !defined __sparc__ \
+    && !defined __alpha__ \
+    && (!defined __powerpc__ || defined __powerpc64__ || defined HAVE_PPC_SECURE_PLT)
+       /* sparc, sparc64, alpha and powerpc32 (the last one only when using
+          -mbss-plt) are expected to have PF_X | PF_W segment containing .plt
+          section, it is part of their ABI.  It is bad security wise, nevertheless
+          this test shouldn't fail because of this.  */
+       return 1;
+#endif
+      }
 
-  if (cnt == phnum)
+  if (dynphdr == NULL)
     {
       printf ("%s: no DYNAMIC segment found\n", fname);
       return 1;
     }
 
   /* Read the dynamic segment.  */
-  size_t pmemsz = SWAP(phdr[cnt].p_memsz);
+  size_t pmemsz = SWAP(dynphdr->p_memsz);
   E(Dyn) *dyn = alloca (pmemsz);
-  if (pread (fd, dyn, pmemsz, SWAP(phdr[cnt].p_offset)) != pmemsz)
+  if (pread (fd, dyn, pmemsz, SWAP(dynphdr->p_offset)) != pmemsz)
     goto read_error;
 
   /* Search for an DT_TEXTREL entry of DT_FLAGS with the DF_TEXTREL