[binutils-gdb] aarch64 core: use of uninitialised value
Alan Modra via Binutils-cvs <[email protected]>
| Newsgroups | gmane.comp.gnu.binutils.cvs |
|---|---|
| Message-ID | <[email protected]> |
https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=3ec37a1948196800af10018b8b11b9da4abc886d commit 3ec37a1948196800af10018b8b11b9da4abc886d Author: Alan Modra <[email protected]> Date: Tue May 26 17:10:34 2026 +0930 aarch64 core: use of uninitialised value Commit d0ff5ca959df adding PT_AARCH64_MEMTAG_MTE support, creates a section that stores "p_memsz" from the program header in "rawsize" and "p_filesz" in "size". p_memsz is the memory range, usually 32 times p_filesz. This can be a problem when bfd reads the section, for example to display it with objdump -s, as the usual (linker) meaning for input section "rawsize" is the original size on disk. Memory is allocated to read the larger of "size" and "rawsize". So 32 times the memory is allocated than what is really needed. With fuzzed input "rawsize" can be smaller than "size" since the header values are not sanity checked. This results in section contents with only the first "rawsize" bytes read from disk, the rest being uninitialised. Of course fuzzed input can also have very large "rawsize" which might result in OOM. One way of fixing this is to move the p_memsz value somewhere else (output_offset would work, I think). Another might be to qualify use of rawsize by is_linker_input, but I haven't checked over all the bfd code using rawsize. And then there is this approach: * bfd.c (bfd_get_section_limit_octets), (bfd_get_section_alloc_size): Ignore rawsize in bfd_core. * bfd-in32.h: Regenerate. Diff: --- bfd/bfd-in2.h | 6 ++++-- bfd/bfd.c | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h index 4d157611217..7f91c11ce0d 100644 --- a/bfd/bfd-in2.h +++ b/bfd/bfd-in2.h @@ -2496,7 +2496,8 @@ bfd_set_asymbol_name (asymbol *sy, const char *name) static inline bfd_size_type bfd_get_section_limit_octets (const bfd *abfd, const asection *sec) { - if (abfd->direction != write_direction && sec->rawsize != 0) + if (abfd->format != bfd_core && abfd->direction != write_direction + && sec->rawsize != 0) return sec->rawsize; return sec->size; } @@ -2515,7 +2516,8 @@ bfd_get_section_limit (const bfd *abfd, const asection *sec) static inline bfd_size_type bfd_get_section_alloc_size (const bfd *abfd, const asection *sec) { - if (abfd->direction != write_direction && sec->rawsize > sec->size) + if (abfd->format != bfd_core && abfd->direction != write_direction + && sec->rawsize > sec->size) return sec->rawsize; return sec->size; } diff --git a/bfd/bfd.c b/bfd/bfd.c index 31c70890ad9..cbeaeb6f269 100644 --- a/bfd/bfd.c +++ b/bfd/bfd.c @@ -624,7 +624,8 @@ EXTERNAL .static inline bfd_size_type .bfd_get_section_limit_octets (const bfd *abfd, const asection *sec) .{ -. if (abfd->direction != write_direction && sec->rawsize != 0) +. if (abfd->format != bfd_core && abfd->direction != write_direction +. && sec->rawsize != 0) . return sec->rawsize; . return sec->size; .} @@ -643,7 +644,8 @@ EXTERNAL .static inline bfd_size_type .bfd_get_section_alloc_size (const bfd *abfd, const asection *sec) .{ -. if (abfd->direction != write_direction && sec->rawsize > sec->size) +. if (abfd->format != bfd_core && abfd->direction != write_direction +. && sec->rawsize > sec->size) . return sec->rawsize; . return sec->size; .}