aboutsummaryrefslogtreecommitdiff
path: root/binutils
diff options
context:
space:
mode:
authorNick Clifton <nickc@redhat.com>2024-12-17 09:16:53 +0000
committerNick Clifton <nickc@redhat.com>2024-12-17 09:18:21 +0000
commitc2d41e8a42f1d4c6450feb9c2b7c79afa3f67f4a (patch)
treece12d3926df4db30bf4da8b44a07198c44237d9a /binutils
parent975318ed49fd5725cf10f6c52fe14605e5cbea6a (diff)
downloadbinutils-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.c24
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);
}