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