diff options
author | Siddhesh Poyarekar <siddhesh@redhat.com> | 2012-10-20 08:00:58 +0530 |
---|---|---|
committer | Siddhesh Poyarekar <siddhesh@redhat.com> | 2012-10-20 08:03:54 +0530 |
commit | 88481c163885767a6617823314802aa772271804 (patch) | |
tree | e8fe6cc0c520703aefabe5238f5278776c75e2bc /elf/dl-load.c | |
parent | 89f1c38881d566bb731711632ac84ee1e3d883ee (diff) | |
download | glibc-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/dl-load.c')
-rw-r--r-- | elf/dl-load.c | 14 |
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. */ |