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