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