about summary refs log tree commit diff
path: root/elf
diff options
context:
space:
mode:
authorSiddhesh Poyarekar <siddhesh@redhat.com>2012-10-20 08:00:58 +0530
committerSiddhesh Poyarekar <siddhesh@redhat.com>2012-10-20 08:03:54 +0530
commit88481c163885767a6617823314802aa772271804 (patch)
treee8fe6cc0c520703aefabe5238f5278776c75e2bc /elf
parent89f1c38881d566bb731711632ac84ee1e3d883ee (diff)
downloadglibc-88481c163885767a6617823314802aa772271804.tar.gz
glibc-88481c163885767a6617823314802aa772271804.tar.xz
glibc-88481c163885767a6617823314802aa772271804.zip
Retry read in ld.so if the entire ELF header is not read in
[BZ #13601]

A read operation could return less than requested data for a number of
reasons.
Diffstat (limited to 'elf')
-rw-r--r--elf/dl-load.c14
1 files changed, 12 insertions, 2 deletions
diff --git a/elf/dl-load.c b/elf/dl-load.c
index 0bfa74a25e..4b57879b9d 100644
--- a/elf/dl-load.c
+++ b/elf/dl-load.c
@@ -1722,10 +1722,20 @@ open_verify (const char *name, struct filebuf *fbp, struct link_map *loader,
       /* We successfully openened the file.  Now verify it is a file
 	 we can use.  */
       __set_errno (0);
-      fbp->len = __libc_read (fd, fbp->buf, sizeof (fbp->buf));
+      fbp->len = 0;
+      assert (sizeof (fbp->buf) > sizeof (ElfW(Ehdr)));
+      /* Read in the header.  */
+      do
+        {
+          ssize_t retlen = __libc_read (fd, fbp->buf + fbp->len,
+					sizeof (fbp->buf) - fbp->len);
+	  if (retlen <= 0)
+	    break;
+	  fbp->len += retlen;
+	}
+      while (__builtin_expect (fbp->len < sizeof (ElfW(Ehdr)), 0));
 
       /* This is where the ELF header is loaded.  */
-      assert (sizeof (fbp->buf) > sizeof (ElfW(Ehdr)));
       ehdr = (ElfW(Ehdr) *) fbp->buf;
 
       /* Now run the tests.  */