about summary refs log tree commit diff
path: root/sysdeps/generic/readelflib.c
diff options
context:
space:
mode:
authorAndreas Jaeger <aj@suse.de>2000-05-26 10:23:45 +0000
committerAndreas Jaeger <aj@suse.de>2000-05-26 10:23:45 +0000
commitdc95d1588775854fd5f7e617bfcb6f362bf3a923 (patch)
treee504b5ae583c53fb4eacf9dd3ef21ef5b6b46724 /sysdeps/generic/readelflib.c
parent446e763b48ca29dafd14cb4c65212ac81786b4f0 (diff)
downloadglibc-dc95d1588775854fd5f7e617bfcb6f362bf3a923.tar.gz
glibc-dc95d1588775854fd5f7e617bfcb6f362bf3a923.tar.xz
glibc-dc95d1588775854fd5f7e617bfcb6f362bf3a923.zip
Update.
2000-05-26  Andreas Jaeger  <aj@suse.de>

	* elf/ldconfig.h: Update parameter list for process_elf_file.

	* sysdeps/unix/sysv/linux/sparc/readelflib.c (process_elf_file):
	Add parameter file_length and pass it ot process_elf*file.

	* sysdeps/generic/readelflib.c (check_ptr): New.
	(process_elf_file): Use check_ptr to check all accesses to the
	mmapped file. Add parameter file_length.

	* elf/readlib.c (known_libs): Use <gnu/lib-names.h> to specify
	library names.

	* sunrpc/xdr_intXX_t.c (xdr_uint8_t): Fix conversion.
	Closes PR libc/1573, reported by Bradley White
	<bww@laurelnetworks.com>.
Diffstat (limited to 'sysdeps/generic/readelflib.c')
-rw-r--r--sysdeps/generic/readelflib.c26
1 files changed, 24 insertions, 2 deletions
diff --git a/sysdeps/generic/readelflib.c b/sysdeps/generic/readelflib.c
index 645c9124a9..270c9b00a5 100644
--- a/sysdeps/generic/readelflib.c
+++ b/sysdeps/generic/readelflib.c
@@ -23,10 +23,24 @@
    which need to handle both 32bit and 64bit ELF libraries,  this file is
    included twice for each arch size.  */
 
+/* check_ptr checks that a pointer is in the mmaped file and doesn't
+   point outside it.  */
+#define check_ptr(ptr)						\
+do								\
+  {								\
+    if ((void *)(ptr) < file_contents				\
+	|| (void *)(ptr) > (file_contents+file_length))		\
+      {								\
+	error (0, 0, _("file %s is truncated\n"), file_name);	\
+	return 1;						\
+      }								\
+  }								\
+ while (0);
+ 
 /* Returns 0 if everything is ok, != 0 in case of error.  */
 int
-process_elf_file (const char *file_name, const char *lib, int *flag, char **soname,
-		  void *file_contents)
+process_elf_file (const char *file_name, const char *lib, int *flag,
+		  char **soname, void *file_contents, size_t file_length)
 {
   int i;
   unsigned int j;
@@ -65,6 +79,7 @@ process_elf_file (const char *file_name, const char *lib, int *flag, char **sona
   
   /* Get information from elf program header.  */
   elf_pheader = (ElfW(Phdr) *) (elf_header->e_phoff + file_contents);
+  check_ptr (elf_pheader);
 
   /* The library is an elf library, now search for soname and
      libc5/libc6.  */
@@ -77,6 +92,8 @@ process_elf_file (const char *file_name, const char *lib, int *flag, char **sona
   for (i = 0, segment = elf_pheader;
        i < elf_header->e_phnum; i++, segment++)
     {
+      check_ptr (segment);
+
       switch (segment->p_type)
 	{
 	case PT_LOAD:
@@ -94,6 +111,7 @@ process_elf_file (const char *file_name, const char *lib, int *flag, char **sona
 	  break;
 	case PT_INTERP:
 	  program_interpreter = (char *) (file_contents + segment->p_offset);
+	  check_ptr (program_interpreter);
 
 	  /* Check if this is enough to classify the binary.  */
 	  for (j = 0; j < sizeof (interpreters) / sizeof (interpreters [0]);
@@ -120,15 +138,18 @@ process_elf_file (const char *file_name, const char *lib, int *flag, char **sona
     return 1;
   
   dynamic_segment = (ElfW(Dyn) *) (file_contents + dynamic_addr);
+  check_ptr (dynamic_segment);
 
   /* Find the string table.  */
   dynamic_strings = NULL;
   for (dyn_entry = dynamic_segment; dyn_entry->d_tag != DT_NULL;
        ++dyn_entry)
     {
+      check_ptr (dyn_entry);
       if (dyn_entry->d_tag == DT_STRTAB)
 	{
 	  dynamic_strings = (char *) (file_contents + dyn_entry->d_un.d_val - loadaddr);
+	  check_ptr (dynamic_strings);
 	  break;
 	}
     }
@@ -143,6 +164,7 @@ process_elf_file (const char *file_name, const char *lib, int *flag, char **sona
       if (dyn_entry->d_tag == DT_NEEDED || dyn_entry->d_tag == DT_SONAME)
 	{
 	  char *name = dynamic_strings + dyn_entry->d_un.d_val;
+	  check_ptr (name);
 
 	  if (dyn_entry->d_tag == DT_NEEDED)
 	    {