|
| 1 | +From 7be4186c22f89a87fff048c28910f5d26a0f61ce Mon Sep 17 00:00:00 2001 |
| 2 | +From: Dmitry Klochkov <dmitry.klochkov@bell-sw.com> |
| 3 | +Date: Tue, 9 Sep 2025 12:06:25 +0200 |
| 4 | +Subject: [PATCH] nm: fix treating an ifunc symbol as a stab if |
| 5 | + '--ifunc-chars=--' is given |
| 6 | + |
| 7 | +If an ifunc symbol is processed in print_symbol(), a 'type' field of a |
| 8 | +'syminfo' structure is set to any character specified by a user with an |
| 9 | +'--ifunc-chars' option. But afterwards the 'type' field is used to |
| 10 | +check whether a symbol is a stab in print_symbol_info_{bsd,sysv}() |
| 11 | +functions in order to print additional stab related data. If the 'type' |
| 12 | +field equals '-', a symbol is treated as a stab. If '--ifunc-chars=--' |
| 13 | +is given, all ifunc symbols will be treated as stab symbols and |
| 14 | +uninitialized stab related fields of the 'syminfo' structure will be |
| 15 | +printed which can lead to segmentation fault. |
| 16 | + |
| 17 | +To fix this, check if a symbol is a stab before override the 'type' |
| 18 | +field. Also, add a test case for this fix. |
| 19 | + |
| 20 | + PR binutils/32556 |
| 21 | + * nm.c (extended_symbol_info): Add is_stab. |
| 22 | + (print_symbol): Check if a symbol is a stab. |
| 23 | + (print_symbol_info_bsd): Use info->is_stab. |
| 24 | + (print_symbol_info_sysv): Use info->is_stab. |
| 25 | + * testsuite/binutils-all/nm.exp: Test nm --ifunc-chars=--. |
| 26 | + |
| 27 | +Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32556 |
| 28 | +Fixes: e6f6aa8d184 ("Add option to nm to change the characters displayed for ifunc symbols") |
| 29 | +Signed-off-by: Dmitry Klochkov <dmitry.klochkov@bell-sw.com> |
| 30 | + |
| 31 | +Upstream Patch Reference: https://git.launchpad.net/ubuntu/+source/binutils/tree/debian/patches/CVE-2025-1147.patch?id=2938c598064e4b8513e1d0614a522732e8401080 |
| 32 | +--- |
| 33 | + binutils/nm.c | 10 +++++++--- |
| 34 | + binutils/testsuite/binutils-all/nm.exp | 17 +++++++++++++++++ |
| 35 | + 2 files changed, 24 insertions(+), 3 deletions(-) |
| 36 | + |
| 37 | +diff --git a/binutils/nm.c b/binutils/nm.c |
| 38 | +index 82ccec68..ad4d2afb 100644 |
| 39 | +--- a/binutils/nm.c |
| 40 | ++++ b/binutils/nm.c |
| 41 | +@@ -65,6 +65,7 @@ struct extended_symbol_info |
| 42 | + bfd_vma ssize; |
| 43 | + elf_symbol_type *elfinfo; |
| 44 | + coff_symbol_type *coffinfo; |
| 45 | ++ bool is_stab; |
| 46 | + /* FIXME: We should add more fields for Type, Line, Section. */ |
| 47 | + }; |
| 48 | + #define SYM_VALUE(sym) (sym->sinfo->value) |
| 49 | +@@ -938,8 +939,11 @@ print_symbol (bfd * abfd, |
| 50 | + |
| 51 | + bfd_get_symbol_info (abfd, sym, &syminfo); |
| 52 | + |
| 53 | ++ info.is_stab = false; |
| 54 | ++ if (syminfo.type == '-') |
| 55 | ++ info.is_stab = true; |
| 56 | + /* PR 22967 - Distinguish between local and global ifunc symbols. */ |
| 57 | +- if (syminfo.type == 'i' |
| 58 | ++ else if (syminfo.type == 'i' |
| 59 | + && sym->flags & BSF_GNU_INDIRECT_FUNCTION) |
| 60 | + { |
| 61 | + if (ifunc_type_chars == NULL || ifunc_type_chars[0] == 0) |
| 62 | +@@ -1688,7 +1692,7 @@ print_symbol_info_bsd (struct extended_symbol_info *info, bfd *abfd) |
| 63 | + |
| 64 | + printf (" %c", SYM_TYPE (info)); |
| 65 | + |
| 66 | +- if (SYM_TYPE (info) == '-') |
| 67 | ++ if (info->is_stab) |
| 68 | + { |
| 69 | + /* A stab. */ |
| 70 | + printf (" "); |
| 71 | +@@ -1717,7 +1721,7 @@ print_symbol_info_sysv (struct extended_symbol_info *info, bfd *abfd) |
| 72 | + |
| 73 | + printf ("| %c |", SYM_TYPE (info)); |
| 74 | + |
| 75 | +- if (SYM_TYPE (info) == '-') |
| 76 | ++ if (info->is_stab) |
| 77 | + { |
| 78 | + /* A stab. */ |
| 79 | + printf ("%18s| ", SYM_STAB_NAME (info)); /* (C) Type. */ |
| 80 | +diff --git a/binutils/testsuite/binutils-all/nm.exp b/binutils/testsuite/binutils-all/nm.exp |
| 81 | +index 93753199..beb10dd8 100644 |
| 82 | +--- a/binutils/testsuite/binutils-all/nm.exp |
| 83 | ++++ b/binutils/testsuite/binutils-all/nm.exp |
| 84 | +@@ -335,6 +335,23 @@ if [is_elf_format] { |
| 85 | + fail "$testname (local ifunc)" |
| 86 | + } |
| 87 | + |
| 88 | ++ # PR 32556 |
| 89 | ++ # Test nm --ifunc-chars=-- |
| 90 | ++ |
| 91 | ++ set got [binutils_run $NM "$NMFLAGS --ifunc-chars=-- $tmpfile"] |
| 92 | ++ |
| 93 | ++ if [regexp -line "^\\S+ - global_foo$" $got] then { |
| 94 | ++ pass "$testname=-- (global ifunc)" |
| 95 | ++ } else { |
| 96 | ++ fail "$testname=-- (global ifunc)" |
| 97 | ++ } |
| 98 | ++ |
| 99 | ++ if [regexp -line "^\\S+ - local_foo$" $got] then { |
| 100 | ++ pass "$testname=-- (local ifunc)" |
| 101 | ++ } else { |
| 102 | ++ fail "$testname=-- (local ifunc)" |
| 103 | ++ } |
| 104 | ++ |
| 105 | + if { $verbose < 1 } { |
| 106 | + remote_file host delete "tmpdir/ifunc.o" |
| 107 | + } |
| 108 | +-- |
| 109 | +2.45.4 |
| 110 | + |
0 commit comments