dup_elf returned NULL without setting the libelf errno on several
failure paths. Set ELF_E_INVALID_FILE for the inconsistent archive
state or ELF_E_NOMEM for the copy_arhdr out of memory. The other
failure paths already set an libelf errno on failure through other
functions when they fail, like __libelf_next_arhdr_wrlock and
read_file.
* libelf/elf_begin.c (dup_elf): Set errno on the remaining
failure paths.
Signed-off-by: Mark Wielaard <[email protected]>
---
libelf/elf_begin.c | 17 +++++++++++++----
1 file changed, 13 insertions(+), 4 deletions(-)
diff --git a/libelf/elf_begin.c b/libelf/elf_begin.c
index 5a79dd8d275b..66e941329100 100644
--- a/libelf/elf_begin.c
+++ b/libelf/elf_begin.c
@@ -1109,18 +1109,27 @@ dup_elf (int fildes, Elf_Cmd cmd, Elf *ref)
/* We have all the information we need about the next archive member.
Now create a descriptor for it. Check parent size can contain member. */
if (ref->state.ar.offset < ref->start_offset)
- return NULL;
+ {
+ __libelf_seterrno (ELF_E_INVALID_FILE);
+ return NULL;
+ }
size_t max_size = ref->maximum_size;
size_t offset = (size_t) (ref->state.ar.offset - ref->start_offset);
size_t hdr_size = sizeof (struct ar_hdr);
size_t ar_size = (size_t) ref->state.ar.cur_ar_hdr.ar_size;
if (max_size < hdr_size || max_size - hdr_size < offset)
- return NULL;
+ {
+ __libelf_seterrno (ELF_E_INVALID_FILE);
+ return NULL;
+ }
Elf_Arhdr ar_hdr = {0};
if (copy_arhdr (&ar_hdr, ref) != 0)
- /* Out of memory. */
- return NULL;
+ {
+ /* Out of memory. */
+ __libelf_seterrno (ELF_E_NOMEM);
+ return NULL;
+ }
result = read_file (fildes, ref->state.ar.offset + sizeof (struct ar_hdr),
MIN (max_size - hdr_size - offset, ar_size), cmd, ref);
--
2.56.0