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