From eaf1fa5ac5972efe5041c835c3ac9fec3c6aa06c Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Thu, 3 Aug 2023 08:40:12 +0930 Subject: [PATCH] ld: sprintf sanitizer null destination pointer * configure.ac (stpcpy): AC_CHECK_DECLS. * sysdep.h (stpcpy): Add fallback declaraion. * config.in: Regenerate. * configure: Regenerate. * emultempl/pe.em (open_dynamic_archive): Use stpcpy rather than sprintf plus strlen. * emultempl/pep.em (open_dynamic_archive): Likewise. * emultempl/xtensaelf.em (elf_xtensa_before_allocation): Use auto rather than malloc'd buffer. Use sprintf count. * ldelf.c (ldelf_search_needed): Use memcpy in place of sprintf. * pe-dll.c (pe_process_import_defs): Use string already formed for alias match rather than recreating. --- ld/config.in | 4 ++++ ld/configure | 10 ++++++++++ ld/configure.ac | 2 +- ld/emultempl/pe.em | 4 ++-- ld/emultempl/pep.em | 4 ++-- ld/emultempl/xtensaelf.em | 10 ++++------ ld/ldelf.c | 11 +++++++---- ld/pe-dll.c | 18 ++++++++---------- ld/sysdep.h | 4 ++++ 9 files changed, 42 insertions(+), 25 deletions(-) diff --git a/ld/config.in b/ld/config.in index ad0dc6a106c..a453c7f7241 100644 --- a/ld/config.in +++ b/ld/config.in @@ -78,6 +78,10 @@ /* Is the prototype for getopt in in the expected format? */ #undef HAVE_DECL_GETOPT +/* Define to 1 if you have the declaration of `stpcpy', and to 0 if you don't. + */ +#undef HAVE_DECL_STPCPY + /* Define to 1 if you have the header file. */ #undef HAVE_DLFCN_H diff --git a/ld/configure b/ld/configure index 33e09fc6987..a4fcb9bf19b 100755 --- a/ld/configure +++ b/ld/configure @@ -16771,6 +16771,16 @@ fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_ENVIRON $ac_have_decl _ACEOF +ac_fn_c_check_decl "$LINENO" "stpcpy" "ac_cv_have_decl_stpcpy" "$ac_includes_default" +if test "x$ac_cv_have_decl_stpcpy" = xyes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_STPCPY $ac_have_decl +_ACEOF diff --git a/ld/configure.ac b/ld/configure.ac index 217ef7b2733..14628e5dcef 100644 --- a/ld/configure.ac +++ b/ld/configure.ac @@ -371,7 +371,7 @@ AC_CHECK_FUNCS(close glob lseek mkstemp open realpath waitpid) BFD_BINARY_FOPEN -AC_CHECK_DECLS([asprintf, environ]) +AC_CHECK_DECLS([asprintf, environ, stpcpy]) AC_FUNC_MMAP diff --git a/ld/emultempl/pe.em b/ld/emultempl/pe.em index cd2abe460b9..a583b02eeec 100644 --- a/ld/emultempl/pe.em +++ b/ld/emultempl/pe.em @@ -2464,8 +2464,8 @@ gld${EMULATION_NAME}_open_dynamic_archive search->name and the start of the format string. */ + 2); - sprintf (full_string, "%s/", search->name); - base_string = full_string + strlen (full_string); + base_string = stpcpy (full_string, search->name); + *base_string++ = '/'; for (i = 0; libname_fmt[i].format; i++) { diff --git a/ld/emultempl/pep.em b/ld/emultempl/pep.em index 28d8c8decb3..516d2afcaf0 100644 --- a/ld/emultempl/pep.em +++ b/ld/emultempl/pep.em @@ -2295,8 +2295,8 @@ gld${EMULATION_NAME}_open_dynamic_archive search->name and the start of the format string. */ + 2); - sprintf (full_string, "%s/", search->name); - base_string = full_string + strlen (full_string); + base_string = stpcpy (full_string, search->name); + *base_string++ = '/'; for (i = 0; libname_fmt[i].format; i++) { diff --git a/ld/emultempl/xtensaelf.em b/ld/emultempl/xtensaelf.em index 4cb9bda8f92..f2d10b51d13 100644 --- a/ld/emultempl/xtensaelf.em +++ b/ld/emultempl/xtensaelf.em @@ -490,15 +490,14 @@ elf_xtensa_before_allocation (void) if (info_sec) { int xtensa_info_size; - char *data; + char data[100]; info_sec->flags &= ~SEC_EXCLUDE; info_sec->flags |= SEC_IN_MEMORY; - data = xmalloc (100); - sprintf (data, "USE_ABSOLUTE_LITERALS=%d\nABI=%d\n", - XSHAL_USE_ABSOLUTE_LITERALS, xtensa_abi_choice ()); - xtensa_info_size = strlen (data) + 1; + xtensa_info_size + = 1 + sprintf (data, "USE_ABSOLUTE_LITERALS=%d\nABI=%d\n", + XSHAL_USE_ABSOLUTE_LITERALS, xtensa_abi_choice ()); /* Add enough null terminators to pad to a word boundary. */ do @@ -512,7 +511,6 @@ elf_xtensa_before_allocation (void) bfd_put_32 (info_sec->owner, XTINFO_TYPE, info_sec->contents + 8); memcpy (info_sec->contents + 12, XTINFO_NAME, XTINFO_NAMESZ); memcpy (info_sec->contents + 12 + XTINFO_NAMESZ, data, xtensa_info_size); - free (data); } /* Enable relaxation by default if the "--no-relax" option was not diff --git a/ld/ldelf.c b/ld/ldelf.c index f9a6819366f..23a014d963b 100644 --- a/ld/ldelf.c +++ b/ld/ldelf.c @@ -524,10 +524,13 @@ ldelf_search_needed (const char *path, struct dt_needed *n, int force, else { char * current_dir = getpwd (); - - freeme = xmalloc (strlen (replacement) - + strlen (current_dir) + 2); - sprintf (freeme, "%s/%s", current_dir, replacement); + size_t cdir_len = strlen (current_dir); + size_t rep_len = strlen (replacement); + freeme = xmalloc (cdir_len + rep_len + 2); + memcpy (freeme, current_dir, cdir_len); + freeme[cdir_len] = '/'; + memcpy (freeme + cdir_len + 1, + replacement, rep_len + 1); } replacement = freeme; diff --git a/ld/pe-dll.c b/ld/pe-dll.c index a95b85c60dd..b45c530d6e7 100644 --- a/ld/pe-dll.c +++ b/ld/pe-dll.c @@ -3340,6 +3340,14 @@ pe_process_import_defs (bfd *output_bfd, struct bfd_link_info *linfo) false, false, false); if (blhe) is_undef = (blhe->type == bfd_link_hash_undefined); + + if (is_cdecl && (!blhe || !is_undef)) + { + blhe = pe_find_cdecl_alias_match (linfo, name + 6); + include_jmp_stub = true; + if (blhe) + is_undef = (blhe->type == bfd_link_hash_undefined); + } } else { @@ -3347,16 +3355,6 @@ pe_process_import_defs (bfd *output_bfd, struct bfd_link_info *linfo) is_undef = (blhe->type == bfd_link_hash_undefined); } - if (is_cdecl - && (!blhe || (blhe && blhe->type != bfd_link_hash_undefined))) - { - sprintf (name, "%s%s",U (""), imp[i].internal_name); - blhe = pe_find_cdecl_alias_match (linfo, name); - include_jmp_stub = true; - if (blhe) - is_undef = (blhe->type == bfd_link_hash_undefined); - } - free (name); if (is_undef) diff --git a/ld/sysdep.h b/ld/sysdep.h index 3601a59a6ac..1573d5ed888 100644 --- a/ld/sysdep.h +++ b/ld/sysdep.h @@ -92,6 +92,10 @@ extern char **environ; #endif +#if !HAVE_DECL_STPCPY +extern char *stpcpy (char *__dest, const char *__src); +#endif + #define POISON_BFD_BOOLEAN 1 #endif /* ! defined (LD_SYSDEP_H) */ -- 2.30.2