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