From 7a6efab20b469e620198d8d6a27e56d5714a0ef4 Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Mon, 3 Apr 2023 07:51:28 +0930 Subject: [PATCH] asan: heap buffer overflow printing ecoff debug info file name A case of a string section ending with an unterminated string. Fix it by allocating one more byte and making it zero. Also make functions reading the data return void* so that casts are not needed. * ecoff.c (READ): Delete type param. Allocate one extra byte to terminate string sections with a NUL. Adjust invocation. * elfxx-mips.c (READ): Likewise. * libbfd-in.h (_bfd_alloc_and_read): Return a void*. (_bfd_malloc_and_read): Likewise. * libbfd.h: Regenerate. --- bfd/ecoff.c | 25 ++++++++++++------------- bfd/elfxx-mips.c | 28 ++++++++++++++-------------- bfd/libbfd-in.h | 8 ++++---- bfd/libbfd.h | 8 ++++---- 4 files changed, 34 insertions(+), 35 deletions(-) diff --git a/bfd/ecoff.c b/bfd/ecoff.c index 1bea7005fee..fb6fcade913 100644 --- a/bfd/ecoff.c +++ b/bfd/ecoff.c @@ -3749,7 +3749,7 @@ ecoff_final_link_debug_accumulate (bfd *output_bfd, HDRR *symhdr = &debug->symbolic_header; bool ret; -#define READ(ptr, offset, count, size, type) \ +#define READ(ptr, offset, count, size) \ do \ { \ size_t amt; \ @@ -3767,29 +3767,28 @@ ecoff_final_link_debug_accumulate (bfd *output_bfd, ret = false; \ goto return_something; \ } \ - debug->ptr = (type) _bfd_malloc_and_read (input_bfd, amt, amt); \ + debug->ptr = _bfd_malloc_and_read (input_bfd, amt + 1, amt); \ if (debug->ptr == NULL) \ { \ ret = false; \ goto return_something; \ } \ + ((char *) debug->ptr)[amt] = 0; \ } while (0) /* If raw_syments is not NULL, then the data was already by read by _bfd_ecoff_slurp_symbolic_info. */ if (ecoff_data (input_bfd)->raw_syments == NULL) { - READ (line, cbLineOffset, cbLine, sizeof (unsigned char), - unsigned char *); - READ (external_dnr, cbDnOffset, idnMax, swap->external_dnr_size, void *); - READ (external_pdr, cbPdOffset, ipdMax, swap->external_pdr_size, void *); - READ (external_sym, cbSymOffset, isymMax, swap->external_sym_size, void *); - READ (external_opt, cbOptOffset, ioptMax, swap->external_opt_size, void *); - READ (external_aux, cbAuxOffset, iauxMax, sizeof (union aux_ext), - union aux_ext *); - READ (ss, cbSsOffset, issMax, sizeof (char), char *); - READ (external_fdr, cbFdOffset, ifdMax, swap->external_fdr_size, void *); - READ (external_rfd, cbRfdOffset, crfd, swap->external_rfd_size, void *); + READ (line, cbLineOffset, cbLine, sizeof (unsigned char)); + READ (external_dnr, cbDnOffset, idnMax, swap->external_dnr_size); + READ (external_pdr, cbPdOffset, ipdMax, swap->external_pdr_size); + READ (external_sym, cbSymOffset, isymMax, swap->external_sym_size); + READ (external_opt, cbOptOffset, ioptMax, swap->external_opt_size); + READ (external_aux, cbAuxOffset, iauxMax, sizeof (union aux_ext)); + READ (ss, cbSsOffset, issMax, sizeof (char)); + READ (external_fdr, cbFdOffset, ifdMax, swap->external_fdr_size); + READ (external_rfd, cbRfdOffset, crfd, swap->external_rfd_size); } #undef READ diff --git a/bfd/elfxx-mips.c b/bfd/elfxx-mips.c index 35bbd86044b..d34a755807b 100644 --- a/bfd/elfxx-mips.c +++ b/bfd/elfxx-mips.c @@ -1486,7 +1486,7 @@ _bfd_mips_elf_read_ecoff_info (bfd *abfd, asection *section, /* The symbolic header contains absolute file offsets and sizes to read. */ -#define READ(ptr, offset, count, size, type) \ +#define READ(ptr, offset, count, size) \ do \ { \ size_t amt; \ @@ -1500,23 +1500,23 @@ _bfd_mips_elf_read_ecoff_info (bfd *abfd, asection *section, } \ if (bfd_seek (abfd, symhdr->offset, SEEK_SET) != 0) \ goto error_return; \ - debug->ptr = (type) _bfd_malloc_and_read (abfd, amt, amt); \ + debug->ptr = _bfd_malloc_and_read (abfd, amt + 1, amt); \ if (debug->ptr == NULL) \ goto error_return; \ + ((char *) debug->ptr)[amt] = 0; \ } while (0) - READ (line, cbLineOffset, cbLine, sizeof (unsigned char), unsigned char *); - READ (external_dnr, cbDnOffset, idnMax, swap->external_dnr_size, void *); - READ (external_pdr, cbPdOffset, ipdMax, swap->external_pdr_size, void *); - READ (external_sym, cbSymOffset, isymMax, swap->external_sym_size, void *); - READ (external_opt, cbOptOffset, ioptMax, swap->external_opt_size, void *); - READ (external_aux, cbAuxOffset, iauxMax, sizeof (union aux_ext), - union aux_ext *); - READ (ss, cbSsOffset, issMax, sizeof (char), char *); - READ (ssext, cbSsExtOffset, issExtMax, sizeof (char), char *); - READ (external_fdr, cbFdOffset, ifdMax, swap->external_fdr_size, void *); - READ (external_rfd, cbRfdOffset, crfd, swap->external_rfd_size, void *); - READ (external_ext, cbExtOffset, iextMax, swap->external_ext_size, void *); + READ (line, cbLineOffset, cbLine, sizeof (unsigned char)); + READ (external_dnr, cbDnOffset, idnMax, swap->external_dnr_size); + READ (external_pdr, cbPdOffset, ipdMax, swap->external_pdr_size); + READ (external_sym, cbSymOffset, isymMax, swap->external_sym_size); + READ (external_opt, cbOptOffset, ioptMax, swap->external_opt_size); + READ (external_aux, cbAuxOffset, iauxMax, sizeof (union aux_ext)); + READ (ss, cbSsOffset, issMax, sizeof (char)); + READ (ssext, cbSsExtOffset, issExtMax, sizeof (char)); + READ (external_fdr, cbFdOffset, ifdMax, swap->external_fdr_size); + READ (external_rfd, cbRfdOffset, crfd, swap->external_rfd_size); + READ (external_ext, cbExtOffset, iextMax, swap->external_ext_size); #undef READ return true; diff --git a/bfd/libbfd-in.h b/bfd/libbfd-in.h index 1c9f34bb6d7..561cef1a12e 100644 --- a/bfd/libbfd-in.h +++ b/bfd/libbfd-in.h @@ -929,10 +929,10 @@ extern bool _bfd_link_keep_memory (struct bfd_link_info *) #define _bfd_constant_p(v) 0 #endif -static inline bfd_byte * +static inline void * _bfd_alloc_and_read (bfd *abfd, bfd_size_type asize, bfd_size_type rsize) { - bfd_byte *mem; + void *mem; if (!_bfd_constant_p (rsize)) { ufile_ptr filesize = bfd_get_file_size (abfd); @@ -952,10 +952,10 @@ _bfd_alloc_and_read (bfd *abfd, bfd_size_type asize, bfd_size_type rsize) return NULL; } -static inline bfd_byte * +static inline void * _bfd_malloc_and_read (bfd *abfd, bfd_size_type asize, bfd_size_type rsize) { - bfd_byte *mem; + void *mem; if (!_bfd_constant_p (rsize)) { ufile_ptr filesize = bfd_get_file_size (abfd); diff --git a/bfd/libbfd.h b/bfd/libbfd.h index d1dc7b912a0..ae17717efa3 100644 --- a/bfd/libbfd.h +++ b/bfd/libbfd.h @@ -935,10 +935,10 @@ extern bool _bfd_link_keep_memory (struct bfd_link_info *) #define _bfd_constant_p(v) 0 #endif -static inline bfd_byte * +static inline void * _bfd_alloc_and_read (bfd *abfd, bfd_size_type asize, bfd_size_type rsize) { - bfd_byte *mem; + void *mem; if (!_bfd_constant_p (rsize)) { ufile_ptr filesize = bfd_get_file_size (abfd); @@ -958,10 +958,10 @@ _bfd_alloc_and_read (bfd *abfd, bfd_size_type asize, bfd_size_type rsize) return NULL; } -static inline bfd_byte * +static inline void * _bfd_malloc_and_read (bfd *abfd, bfd_size_type asize, bfd_size_type rsize) { - bfd_byte *mem; + void *mem; if (!_bfd_constant_p (rsize)) { ufile_ptr filesize = bfd_get_file_size (abfd); -- 2.30.2