Fix potential buffer overruns when creating DLLs.
PR 29006
* pe-dll.c (make_head): Use asprintf to allocate and populate a
buffer containing the temporary name.
(make_tail, make_one, make_singleton_name_thunk): Likewise.
(make_import_fixup_mark, make_import_fixup_entry): Likewise.
(make_runtime_pseudo_reloc): Likewise.
(pe_create_runtime_relocator_reference): Likewise.
diff --git a/ld/ChangeLog b/ld/ChangeLog
index 456c118..a094af9 100644
--- a/ld/ChangeLog
+++ b/ld/ChangeLog
@@ -1,3 +1,13 @@
+2022-04-27 Nick Clifton <nickc@redhat.com>
+
+ PR 29006
+ * pe-dll.c (make_head): Use asprintf to allocate and populate a
+ buffer containing the temporary name.
+ (make_tail, make_one, make_singleton_name_thunk): Likewise.
+ (make_import_fixup_mark, make_import_fixup_entry): Likewise.
+ (make_runtime_pseudo_reloc): Likewise.
+ (pe_create_runtime_relocator_reference): Likewise.
+
2022-04-25 Nick Clifton <nickc@redhat.com>
PR 29072
diff --git a/ld/pe-dll.c b/ld/pe-dll.c
index 95de94b..ed68f66 100644
--- a/ld/pe-dll.c
+++ b/ld/pe-dll.c
@@ -2084,8 +2084,12 @@
char *oname;
bfd *abfd;
- oname = xmalloc (20 + dll_symname_len);
- sprintf (oname, "%s_d%06d.o", dll_symname, tmp_seq);
+ if (asprintf (&oname, "%s_d%06d.o", dll_symname, tmp_seq) < 4)
+ /* In theory we should return NULL here at let our caller decide what to
+ do. But currently the return value is not checked, just used, and
+ besides, this condition only happens when the system has run out of
+ memory. So just give up. */
+ exit (EXIT_FAILURE);
tmp_seq++;
abfd = bfd_create (oname, parent);
@@ -2173,8 +2177,12 @@
char *oname;
bfd *abfd;
- oname = xmalloc (20 + dll_symname_len);
- sprintf (oname, "%s_d%06d.o", dll_symname, tmp_seq);
+ if (asprintf (&oname, "%s_d%06d.o", dll_symname, tmp_seq) < 4)
+ /* In theory we should return NULL here at let our caller decide what to
+ do. But currently the return value is not checked, just used, and
+ besides, this condition only happens when the system has run out of
+ memory. So just give up. */
+ exit (EXIT_FAILURE);
tmp_seq++;
abfd = bfd_create (oname, parent);
@@ -2324,8 +2332,12 @@
}
}
- oname = xmalloc (20 + dll_symname_len);
- sprintf (oname, "%s_d%06d.o", dll_symname, tmp_seq);
+ if (asprintf (&oname, "%s_d%06d.o", dll_symname, tmp_seq) < 4)
+ /* In theory we should return NULL here at let our caller decide what to
+ do. But currently the return value is not checked, just used, and
+ besides, this condition only happens when the system has run out of
+ memory. So just give up. */
+ exit (EXIT_FAILURE);
tmp_seq++;
abfd = bfd_create (oname, parent);
@@ -2510,8 +2522,12 @@
char *oname;
bfd *abfd;
- oname = xmalloc (20 + dll_symname_len);
- sprintf (oname, "%s_nmth%06d.o", dll_symname, tmp_seq);
+ if (asprintf (&oname, "%s_nmth%06d.o", dll_symname, tmp_seq) < 4)
+ /* In theory we should return NULL here at let our caller decide what to
+ do. But currently the return value is not checked, just used, and
+ besides, this condition only happens when the system has run out of
+ memory. So just give up. */
+ exit (EXIT_FAILURE);
tmp_seq++;
abfd = bfd_create (oname, parent);
@@ -2551,7 +2567,7 @@
struct bfd_symbol *sym = *rel->sym_ptr_ptr;
bfd *abfd = bfd_asymbol_bfd (sym);
struct bfd_link_hash_entry *bh;
- char *fixup_name, buf[26];
+ char *fixup_name, buf[256];
size_t prefix_len;
/* "name" buffer has space before the symbol name for prefixes. */
@@ -2586,8 +2602,12 @@
char *oname;
bfd *abfd;
- oname = xmalloc (20 + dll_symname_len);
- sprintf (oname, "%s_fu%06d.o", dll_symname, tmp_seq);
+ if (asprintf (&oname, "%s_fu%06d.o", dll_symname, tmp_seq) < 4)
+ /* In theory we should return NULL here at let our caller decide what to
+ do. But currently the return value is not checked, just used, and
+ besides, this condition only happens when the system has run out of
+ memory. So just give up. */
+ exit (EXIT_FAILURE);
tmp_seq++;
abfd = bfd_create (oname, parent);
@@ -2640,8 +2660,12 @@
bfd *abfd;
bfd_size_type size;
- oname = xmalloc (20 + dll_symname_len);
- sprintf (oname, "%s_rtr%06d.o", dll_symname, tmp_seq);
+ if (asprintf (&oname, "%s_rtr%06d.o", dll_symname, tmp_seq) < 4)
+ /* In theory we should return NULL here at let our caller decide what to
+ do. But currently the return value is not checked, just used, and
+ besides, this condition only happens when the system has run out of
+ memory. So just give up. */
+ exit (EXIT_FAILURE);
tmp_seq++;
abfd = bfd_create (oname, parent);
@@ -2727,8 +2751,12 @@
char *oname;
bfd *abfd;
- oname = xmalloc (20 + dll_symname_len);
- sprintf (oname, "%s_ertr%06d.o", dll_symname, tmp_seq);
+ if (asprintf (&oname, "%s_ertr%06d.o", dll_symname, tmp_seq) < 4)
+ /* In theory we should return NULL here at let our caller decide what to
+ do. But currently the return value is not checked, just used, and
+ besides, this condition only happens when the system has run out of
+ memory. So just give up. */
+ exit (EXIT_FAILURE);
tmp_seq++;
abfd = bfd_create (oname, parent);