asan: heap buffer overflow printing ecoff debug info file name
authorAlan Modra <amodra@gmail.com>
Sun, 2 Apr 2023 22:21:28 +0000 (07:51 +0930)
committerAlan Modra <amodra@gmail.com>
Sun, 2 Apr 2023 22:21:28 +0000 (07:51 +0930)
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
bfd/elfxx-mips.c
bfd/libbfd-in.h
bfd/libbfd.h

index 1bea7005feea39bf6b0967e307e0c6dd5661dbef..fb6fcade9134e2f3dd5f849c7e0c798a02f29eb9 100644 (file)
@@ -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
 
index 35bbd86044b2fb75a96ae8cd5b5fab0d0e3b3024..d34a755807b28eb4f68bb4ec7a357451fa3da56e 100644 (file)
@@ -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;
index 1c9f34bb6d7498580d1c9697601d2f7f5f34c007..561cef1a12e64477c34ef7be98f811687ad9e7c4 100644 (file)
@@ -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);
index d1dc7b912a0a655f0e7e28395319a37851deebe5..ae17717efa366ec606110d7eab03441b70dd248d 100644 (file)
@@ -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);