mirror of
https://github.com/freebsd/freebsd-src.git
synced 2026-10-28 11:25:21 +01:00
rtld: more caution when parsing in digest_notes()
Incorrect ELF might have PT_NOTE slightly larger than the needed to contain all notes, and the PT_NOTE size could be larger than one page. Then rtld mmaps just the notes bytes to parse. After the last note, we iterate past the mapped region trying to read the Elf_Note header. This was found in wild. Require full elf note to fit into the [start_note, end_note) region to continue the parsing. Check it in stages, first verifying the Elf_Note header structure fits, to be able to read the name and data length. After that, check the whole note against limit. Reported and tested by: makc Reviewed by: emaste Sponsored by: The FreeBSD Foundation MFC after: 1 week Differential revision: https://reviews.freebsd.org/D59635
This commit is contained in:
1 parent
2ef97312d5
commit
fa848d4d0c
1 file changed
+9
-4
@@ -1785,14 +1785,19 @@ digest_phdr(const Elf_Phdr *phdr, int phnum, caddr_t entry, const char *path)
|
||||
void
|
||||
digest_notes(Obj_Entry *obj, Elf_Addr note_start, Elf_Addr note_end)
|
||||
{
|
||||
const Elf_Note *note;
|
||||
const Elf_Note *note, *next_note;
|
||||
const char *note_name;
|
||||
uintptr_t p;
|
||||
|
||||
for (note = (const Elf_Note *)note_start; (Elf_Addr)note < note_end;
|
||||
note = (const Elf_Note *)((const char *)(note + 1) +
|
||||
for (note = (const Elf_Note *)note_start;; note = next_note) {
|
||||
if ((Elf_Addr)note + sizeof(Elf_Note) > note_end)
|
||||
break;
|
||||
next_note = (const Elf_Note *)((const char *)(note + 1) +
|
||||
roundup2(note->n_namesz, sizeof(Elf32_Addr)) +
|
||||
roundup2(note->n_descsz, sizeof(Elf32_Addr)))) {
|
||||
roundup2(note->n_descsz, sizeof(Elf32_Addr)));
|
||||
if ((Elf_Addr)next_note > note_end)
|
||||
break;
|
||||
|
||||
if (arch_digest_note(obj, note))
|
||||
continue;
|
||||
|
||||
|
||||
Reference in new issue
Block a user