diff options
author | Mark Wielaard <mark@klomp.org> | 2021-12-16 00:29:22 +0100 |
---|---|---|
committer | Mark Wielaard <mark@klomp.org> | 2021-12-16 19:50:38 +0100 |
commit | 3c9b69161b842708b4ef2f4e0f0b3ad1812798c2 (patch) | |
tree | f09dca9a1dd00f26dab14e6f5fdb0f161cb0fc96 /libdwfl | |
parent | 8303a9cf380a57d035557a157fe0e4d58e2b3090 (diff) | |
download | elfutils-3c9b69161b842708b4ef2f4e0f0b3ad1812798c2.tar.gz |
libdwfl: Make sure phent is sane and there is at least one phdr
dwfl_link_map_report can only handle program headers that are the
correct (32 or 64 bit) size. The buffer read in needs to contain room
for at least one Phdr.
https://sourceware.org/bugzilla/show_bug.cgi?id=28660
Signed-off-by: Mark Wielaard <mark@klomp.org>
Diffstat (limited to 'libdwfl')
-rw-r--r-- | libdwfl/ChangeLog | 6 | ||||
-rw-r--r-- | libdwfl/link_map.c | 16 |
2 files changed, 20 insertions, 2 deletions
diff --git a/libdwfl/ChangeLog b/libdwfl/ChangeLog index aaea164c..7bf789e0 100644 --- a/libdwfl/ChangeLog +++ b/libdwfl/ChangeLog @@ -1,3 +1,9 @@ +2021-12-15 Mark Wielaard <mark@klomp.org> + + * link_map.c (dwfl_link_map_report): Make sure phent is either sizeof + Elf32_Phdr or sizeof Elf64_Phdr. Check in.d_size can hold at least one + Phdr. + 2021-12-12 Mark Wielaard <mark@klomp.org> * dwfl_segment_report_module.c (dwfl_segment_report_module): Don't diff --git a/libdwfl/link_map.c b/libdwfl/link_map.c index ad93501e..82df7b69 100644 --- a/libdwfl/link_map.c +++ b/libdwfl/link_map.c @@ -1,5 +1,6 @@ /* Report modules by examining dynamic linker data structures. Copyright (C) 2008-2016 Red Hat, Inc. + Copyright (C) 2021 Mark J. Wielaard <mark@klomp.org> This file is part of elfutils. This file is free software; you can redistribute it and/or modify @@ -784,7 +785,9 @@ dwfl_link_map_report (Dwfl *dwfl, const void *auxv, size_t auxv_size, GElf_Xword dyn_filesz = 0; GElf_Addr dyn_bias = (GElf_Addr) -1; - if (phdr != 0 && phnum != 0 && phent != 0) + if (phdr != 0 && phnum != 0 + && ((elfclass == ELFCLASS32 && phent == sizeof (Elf32_Phdr)) + || (elfclass == ELFCLASS64 && phent == sizeof (Elf64_Phdr)))) { Dwfl_Module *phdr_mod; int phdr_segndx = INTUSE(dwfl_addrsegment) (dwfl, phdr, &phdr_mod); @@ -904,7 +907,16 @@ dwfl_link_map_report (Dwfl *dwfl, const void *auxv, size_t auxv_size, .d_buf = buf }; if (in.d_size > out.d_size) - in.d_size = out.d_size; + { + in.d_size = out.d_size; + phnum = in.d_size / phent; + if (phnum == 0) + { + free (buf); + __libdwfl_seterrno (DWFL_E_BADELF); + return false; + } + } if (likely ((elfclass == ELFCLASS32 ? elf32_xlatetom : elf64_xlatetom) (&out, &in, elfdata) != NULL)) |