summaryrefslogtreecommitdiffstats
path: root/meta/recipes-devtools/binutils/binutils/CVE-2017-17125.patch
blob: 30dc6d5727a69e2f70f0d4244b6faff41d4369e2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
From 160b1a618ad94988410dc81fce9189fcda5b7ff4 Mon Sep 17 00:00:00 2001
From: Alan Modra <amodra@gmail.com>
Date: Sat, 18 Nov 2017 23:18:22 +1030
Subject: [PATCH] PR22443, Global buffer overflow in
 _bfd_elf_get_symbol_version_string

Symbols like *ABS* defined in bfd/section.c:global_syms are not
elf_symbol_type.  They can appear on relocs and perhaps other places
in an ELF bfd, so a number of places in nm.c and objdump.c are wrong
to cast an asymbol based on the bfd being ELF.  I think we lose
nothing by excluding all section symbols, not just the global_syms.

	PR 22443
	* nm.c (sort_symbols_by_size): Don't attempt to access
	section symbol internal_elf_sym.
	(print_symbol): Likewise.  Don't call bfd_get_symbol_version_string
	for section symbols.
	* objdump.c (compare_symbols): Don't attempt to access
	section symbol internal_elf_sym.
	(objdump_print_symname): Don't call bfd_get_symbol_version_string
	for section symbols.

Upstream-Status: Backport
Affects: <= 2.29.1
CVE:  CVE-2017-17125
Signed-off-by: Armin Kuster <akuster@mvista.com>

---
 binutils/ChangeLog | 12 ++++++++++++
 binutils/nm.c      | 17 ++++++++++-------
 binutils/objdump.c |  6 +++---
 3 files changed, 25 insertions(+), 10 deletions(-)

Index: git/binutils/nm.c
===================================================================
--- git.orig/binutils/nm.c
+++ git/binutils/nm.c
@@ -765,7 +765,6 @@ sort_symbols_by_size (bfd *abfd, bfd_boo
       asection *sec;
       bfd_vma sz;
       asymbol *temp;
-      int synthetic = (sym->flags & BSF_SYNTHETIC);
 
       if (from + size < fromend)
 	{
@@ -782,10 +781,13 @@ sort_symbols_by_size (bfd *abfd, bfd_boo
       sec = bfd_get_section (sym);
 
       /* Synthetic symbols don't have a full type set of data available, thus
-	 we can't rely on that information for the symbol size.  */
-      if (!synthetic && bfd_get_flavour (abfd) == bfd_target_elf_flavour)
+	 we can't rely on that information for the symbol size.  Ditto for
+	 bfd/section.c:global_syms like *ABS*.  */
+      if ((sym->flags & (BSF_SECTION_SYM | BSF_SYNTHETIC)) == 0
+	  && bfd_get_flavour (abfd) == bfd_target_elf_flavour)
 	sz = ((elf_symbol_type *) sym)->internal_elf_sym.st_size;
-      else if (!synthetic && bfd_is_com_section (sec))
+      else if ((sym->flags & (BSF_SECTION_SYM | BSF_SYNTHETIC)) == 0
+	       && bfd_is_com_section (sec))
 	sz = sym->value;
       else
 	{
@@ -874,8 +876,9 @@ print_symbol (bfd *        abfd,
 
   info.sinfo = &syminfo;
   info.ssize = ssize;
-  /* Synthetic symbols do not have a full symbol type set of data available.  */
-  if ((sym->flags & BSF_SYNTHETIC) != 0)
+  /* Synthetic symbols do not have a full symbol type set of data available.
+     Nor do bfd/section.c:global_syms like *ABS*.  */
+  if ((sym->flags & (BSF_SECTION_SYM | BSF_SYNTHETIC)) != 0)
     {
       info.elfinfo = NULL;
       info.coffinfo = NULL;
@@ -893,7 +896,7 @@ print_symbol (bfd *        abfd,
       const char *  version_string = NULL;
       bfd_boolean   hidden = FALSE;
 
-      if ((sym->flags & BSF_SYNTHETIC) == 0)
+      if ((sym->flags & (BSF_SECTION_SYM | BSF_SYNTHETIC)) == 0)
 	version_string = bfd_get_symbol_version_string (abfd, sym, &hidden);
 
       if (bfd_is_und_section (bfd_get_section (sym)))
Index: git/binutils/objdump.c
===================================================================
--- git.orig/binutils/objdump.c
+++ git/binutils/objdump.c
@@ -799,10 +799,10 @@ compare_symbols (const void *ap, const v
       bfd_vma asz, bsz;
 
       asz = 0;
-      if ((a->flags & BSF_SYNTHETIC) == 0)
+      if ((a->flags & (BSF_SECTION_SYM | BSF_SYNTHETIC)) == 0)
 	asz = ((elf_symbol_type *) a)->internal_elf_sym.st_size;
       bsz = 0;
-      if ((b->flags & BSF_SYNTHETIC) == 0)
+      if ((b->flags & (BSF_SECTION_SYM | BSF_SYNTHETIC)) == 0)
 	bsz = ((elf_symbol_type *) b)->internal_elf_sym.st_size;
       if (asz != bsz)
 	return asz > bsz ? -1 : 1;
@@ -888,7 +888,7 @@ objdump_print_symname (bfd *abfd, struct
 	name = alloc;
     }
 
-  if ((sym->flags & BSF_SYNTHETIC) == 0)
+  if ((sym->flags & (BSF_SECTION_SYM | BSF_SYNTHETIC)) == 0)
     version_string = bfd_get_symbol_version_string (abfd, sym, &hidden);
 
   if (bfd_is_und_section (bfd_get_section (sym)))
Index: git/binutils/ChangeLog
===================================================================
--- git.orig/binutils/ChangeLog
+++ git/binutils/ChangeLog
@@ -1,3 +1,15 @@
+2017-11-18  Alan Modra  <amodra@gmail.com>
+
+       PR 22443
+       * nm.c (sort_symbols_by_size): Don't attempt to access
+       section symbol internal_elf_sym.
+       (print_symbol): Likewise.  Don't call bfd_get_symbol_version_string
+       for section symbols.
+       * objdump.c (compare_symbols): Don't attempt to access
+       section symbol internal_elf_sym.
+       (objdump_print_symname): Don't call bfd_get_symbol_version_string
+       for section symbols.
+
 2017-11-29  Nick Clifton  <nickc@redhat.com>
 
        PR 22508