d8307d
Short description: Work ld.so --verify crash on debuginfo files.
d8307d
Author(s): Fedora glibc team <glibc@lists.fedoraproject.org>
d8307d
Origin: PATCH
d8307d
Bug-RHEL: #741105, #767146
d8307d
Upstream status: not-needed
d8307d
d8307d
This change is designed to work around running ld.so on a debuginfo
d8307d
file. This is the wrong fix for this problem and should be dropped.
d8307d
The correct solution is to mark debuginfo files as new types of
d8307d
ELF files.
d8307d
d8307d
Index: glibc-2.22-386-g95e8397/elf/dl-load.c
d8307d
===================================================================
d8307d
--- glibc-2.22-386-g95e8397.orig/elf/dl-load.c
d8307d
+++ glibc-2.22-386-g95e8397/elf/dl-load.c
d8307d
@@ -881,7 +881,8 @@ _dl_map_object_from_fd (const char *name
d8307d
 
d8307d
   /* Get file information.  */
d8307d
   struct r_file_id id;
d8307d
-  if (__glibc_unlikely (!_dl_get_file_id (fd, &id)))
d8307d
+  struct stat64 st;
d8307d
+  if (__glibc_unlikely (!_dl_get_file_id (fd, &id, &st)))
d8307d
     {
d8307d
       errstring = N_("cannot stat shared object");
d8307d
     call_lose_errno:
d8307d
@@ -1076,6 +1077,16 @@ _dl_map_object_from_fd (const char *name
d8307d
 		= N_("ELF load command address/offset not properly aligned");
d8307d
 	      goto call_lose;
d8307d
 	    }
d8307d
+	  if (__glibc_unlikely (ph->p_offset + ph->p_filesz > st.st_size))
d8307d
+	    {
d8307d
+	      /* If the segment requires zeroing of part of its last
d8307d
+		 page, we'll crash when accessing the unmapped page.
d8307d
+		 There's still a possibility of a race, if the shared
d8307d
+		 object is truncated between the fxstat above and the
d8307d
+		 memset below.  */
d8307d
+	      errstring = N_("ELF load command past end of file");
d8307d
+	      goto call_lose;
d8307d
+	    }
d8307d
 
d8307d
 	  struct loadcmd *c = &loadcmds[nloadcmds++];
d8307d
 	  c->mapstart = ALIGN_DOWN (ph->p_vaddr, GLRO(dl_pagesize));
d8307d
Index: glibc-2.22-386-g95e8397/sysdeps/generic/dl-fileid.h
d8307d
===================================================================
d8307d
--- glibc-2.22-386-g95e8397.orig/sysdeps/generic/dl-fileid.h
d8307d
+++ glibc-2.22-386-g95e8397/sysdeps/generic/dl-fileid.h
d8307d
@@ -29,7 +29,8 @@ struct r_file_id
d8307d
    On error, returns false, with errno set.  */
d8307d
 static inline bool
d8307d
 _dl_get_file_id (int fd __attribute__ ((unused)),
d8307d
-		 struct r_file_id *id __attribute__ ((unused)))
d8307d
+		 struct r_file_id *id __attribute__ ((unused)),
d8307d
+		 struct stat64_t *st __attribute__((unused)))
d8307d
 {
d8307d
   return true;
d8307d
 }
d8307d
Index: glibc-2.22-386-g95e8397/sysdeps/posix/dl-fileid.h
d8307d
===================================================================
d8307d
--- glibc-2.22-386-g95e8397.orig/sysdeps/posix/dl-fileid.h
d8307d
+++ glibc-2.22-386-g95e8397/sysdeps/posix/dl-fileid.h
d8307d
@@ -27,18 +27,16 @@ struct r_file_id
d8307d
     ino64_t ino;
d8307d
   };
d8307d
 
d8307d
-/* Sample FD to fill in *ID.  Returns true on success.
d8307d
+/* Sample FD to fill in *ID and *ST.  Returns true on success.
d8307d
    On error, returns false, with errno set.  */
d8307d
 static inline bool
d8307d
-_dl_get_file_id (int fd, struct r_file_id *id)
d8307d
+_dl_get_file_id (int fd, struct r_file_id *id, struct stat64 *st)
d8307d
 {
d8307d
-  struct stat64 st;
d8307d
-
d8307d
-  if (__glibc_unlikely (__fxstat64 (_STAT_VER, fd, &st) < 0))
d8307d
+  if (__glibc_unlikely (__fxstat64 (_STAT_VER, fd, st) < 0))
d8307d
     return false;
d8307d
 
d8307d
-  id->dev = st.st_dev;
d8307d
-  id->ino = st.st_ino;
d8307d
+  id->dev = st->st_dev;
d8307d
+  id->ino = st->st_ino;
d8307d
   return true;
d8307d
 }
d8307d