From 5f8987d3999edb26e757115fe87be55787d510b9 Mon Sep 17 00:00:00 2001 From: Nick Clifton <nickc@redhat.com> Date: Tue, 17 Dec 2024 09:18:57 +0000 Subject: [PATCH] nm: Avoid potential segmentation fault when displaying symbols without version info. PR 32467 --- binutils/nm.c | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/binutils/nm.c b/binutils/nm.c index faf27c59b4d..0ba7604d34f 100644 --- a/binutils/nm.c +++ b/binutils/nm.c @@ -682,7 +682,7 @@ print_symname (const char *form, struct extended_symbol_info *info, const char *name, bfd *abfd) { char *alloc = NULL; - char *atver = NULL; + char *atname = NULL; if (name == NULL) name = info->sinfo->name; @@ -690,9 +690,19 @@ print_symname (const char *form, struct extended_symbol_info *info, if (!with_symbol_versions && bfd_get_flavour (abfd) == bfd_target_elf_flavour) { - atver = strchr (name, '@'); + char *atver = strchr (name, '@'); + if (atver) - *atver = 0; + { + /* PR 32467 - Corrupt binaries might include an @ character in a + symbol name. Since non-versioned symbol names can be in + read-only memory (via memory mapping of a file's contents) we + cannot just replace the @ character with a NUL. Instead we + create a truncated copy of the name. */ + atname = xstrdup (name); + atname [atver - name] = 0; + name = atname; + } } if (do_demangle && *name) @@ -703,9 +713,7 @@ print_symname (const char *form, struct extended_symbol_info *info, } if (unicode_display != unicode_default) - { - name = convert_utf8 (name); - } + name = convert_utf8 (name); if (info != NULL && info->elfinfo && with_symbol_versions) { @@ -726,8 +734,8 @@ print_symname (const char *form, struct extended_symbol_info *info, } } printf (form, name); - if (atver) - *atver = '@'; + + free (atname); free (alloc); } -- 2.43.5