diff options
author | Nick Clifton <nickc@redhat.com> | 2024-12-17 09:16:53 +0000 |
---|---|---|
committer | Nick Clifton <nickc@redhat.com> | 2024-12-17 09:18:21 +0000 |
commit | c2d41e8a42f1d4c6450feb9c2b7c79afa3f67f4a (patch) | |
tree | ce12d3926df4db30bf4da8b44a07198c44237d9a /binutils | |
parent | 975318ed49fd5725cf10f6c52fe14605e5cbea6a (diff) | |
download | binutils-c2d41e8a42f1d4c6450feb9c2b7c79afa3f67f4a.zip binutils-c2d41e8a42f1d4c6450feb9c2b7c79afa3f67f4a.tar.gz binutils-c2d41e8a42f1d4c6450feb9c2b7c79afa3f67f4a.tar.bz2 |
nm: Avoid potential segmentation fault when displaying symbols without version info.
PR 32467
Diffstat (limited to 'binutils')
-rw-r--r-- | binutils/nm.c | 24 |
1 files changed, 16 insertions, 8 deletions
diff --git a/binutils/nm.c b/binutils/nm.c index aabaea4..58e5fbb 100644 --- a/binutils/nm.c +++ b/binutils/nm.c @@ -676,7 +676,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; @@ -684,9 +684,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) @@ -697,9 +707,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) { @@ -720,8 +728,8 @@ print_symname (const char *form, struct extended_symbol_info *info, } } printf (form, name); - if (atver) - *atver = '@'; + + free (atname); free (alloc); } |