aboutsummaryrefslogtreecommitdiff
path: root/elf/dl-load.c
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/dl-load.c
parent89f1c38881d566bb731711632ac84ee1e3d883ee (diff)
downloadglibc-88481c163885767a6617823314802aa772271804.zip
glibc-88481c163885767a6617823314802aa772271804.tar.gz
glibc-88481c163885767a6617823314802aa772271804.tar.bz2
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/dl-load.c')
-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 0bfa74a..4b57879 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. */