summaryrefslogtreecommitdiffstats
path: root/meta/recipes-devtools/binutils/binutils/CVE-2017-16828_p2.patch
blob: 5073d31ce08332446e57cc06a8f61a66d6c12afe (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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
From bf59c5d5f4f5b8b4da1f5f605cfa546f8029b43d Mon Sep 17 00:00:00 2001
From: Nick Clifton <nickc@redhat.com>
Date: Fri, 3 Nov 2017 13:57:15 +0000
Subject: [PATCH] Fix integer overflow problems when reading an ELF binary with
 corrupt augmentation data.

	PR 22386
	* dwarf.c (read_cie): Use bfd_size_type for
	augmentation_data_len.
	(display_augmentation_data): New function.
	(display_debug_frames): Use it.
	Check for integer overflow when testing augmentation_data_len.

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

---
 binutils/ChangeLog | 10 +++++++++
 binutils/dwarf.c   | 65 +++++++++++++++++++++++++++++++++---------------------
 2 files changed, 50 insertions(+), 25 deletions(-)

Index: git/binutils/dwarf.c
===================================================================
--- git.orig/binutils/dwarf.c
+++ git/binutils/dwarf.c
@@ -6577,13 +6577,13 @@ frame_display_row (Frame_Chunk *fc, int
 static unsigned char *
 read_cie (unsigned char *start, unsigned char *end,
 	  Frame_Chunk **p_cie, int *p_version,
-	  unsigned long *p_aug_len, unsigned char **p_aug)
+	  bfd_size_type *p_aug_len, unsigned char **p_aug)
 {
   int version;
   Frame_Chunk *fc;
   unsigned int length_return;
   unsigned char *augmentation_data = NULL;
-  unsigned long augmentation_data_len = 0;
+  bfd_size_type augmentation_data_len = 0;
 
   * p_cie = NULL;
   /* PR 17512: file: 001-228113-0.004.  */
@@ -6653,10 +6653,11 @@ read_cie (unsigned char *start, unsigned
       READ_ULEB (augmentation_data_len);
       augmentation_data = start;
       /* PR 17512: file: 11042-2589-0.004.  */
-      if (augmentation_data_len > (size_t) (end - start))
+      if (augmentation_data_len > (bfd_size_type) (end - start))
 	{
-	  warn (_("Augmentation data too long: %#lx, expected at most %#lx\n"),
-		augmentation_data_len, (unsigned long) (end - start));
+	  warn (_("Augmentation data too long: 0x%s, expected at most %#lx\n"),
+		dwarf_vmatoa ("x", augmentation_data_len),
+		(unsigned long) (end - start));
 	  return end;
 	}
       start += augmentation_data_len;
@@ -6701,6 +6702,31 @@ read_cie (unsigned char *start, unsigned
   return start;
 }
 
+/* Prints out the contents on the augmentation data array.
+   If do_wide is not enabled, then formats the output to fit into 80 columns.  */
+
+static void
+display_augmentation_data (const unsigned char * data, const bfd_size_type len)
+{
+  bfd_size_type i;
+
+  i = printf (_("  Augmentation data:    "));
+
+  if (do_wide || len < ((80 - i) / 3))
+    for (i = 0; i < len; ++i)
+      printf (" %02x", data[i]);
+  else
+    {
+      for (i = 0; i < len; ++i)
+	{
+	  if (i % (80 / 3) == 0)
+	    putchar ('\n');
+	  printf (" %02x", data[i]);
+	}
+    }
+  putchar ('\n');
+}
+
 static int
 display_debug_frames (struct dwarf_section *section,
 		      void *file ATTRIBUTE_UNUSED)
@@ -6729,7 +6755,7 @@ display_debug_frames (struct dwarf_secti
       Frame_Chunk *cie;
       int need_col_headers = 1;
       unsigned char *augmentation_data = NULL;
-      unsigned long augmentation_data_len = 0;
+      bfd_size_type augmentation_data_len = 0;
       unsigned int encoded_ptr_size = saved_eh_addr_size;
       unsigned int offset_size;
       unsigned int initial_length_size;
@@ -6823,16 +6849,8 @@ display_debug_frames (struct dwarf_secti
 	      printf ("  Return address column: %d\n", fc->ra);
 
 	      if (augmentation_data_len)
-		{
-		  unsigned long i;
+		display_augmentation_data (augmentation_data, augmentation_data_len);
 
-		  printf ("  Augmentation data:    ");
-		  for (i = 0; i < augmentation_data_len; ++i)
-		    /* FIXME: If do_wide is FALSE, then we should
-		       add carriage returns at 80 columns...  */
-		    printf (" %02x", augmentation_data[i]);
-		  putchar ('\n');
-		}
 	      putchar ('\n');
 	    }
 	}
@@ -6988,11 +7006,13 @@ display_debug_frames (struct dwarf_secti
 	      READ_ULEB (augmentation_data_len);
 	      augmentation_data = start;
 	      start += augmentation_data_len;
-	      /* PR 17512: file: 722-8446-0.004.  */
-	      if (start >= end || ((signed long) augmentation_data_len) < 0)
+	      /* PR 17512 file: 722-8446-0.004 and PR 22386.  */
+	      if (start >= end
+		  || ((bfd_signed_vma) augmentation_data_len) < 0
+		  || augmentation_data > start)
 		{
-		  warn (_("Corrupt augmentation data length: %lx\n"),
-			augmentation_data_len);
+		  warn (_("Corrupt augmentation data length: 0x%s\n"),
+			dwarf_vmatoa ("x", augmentation_data_len));
 		  start = end;
 		  augmentation_data = NULL;
 		  augmentation_data_len = 0;
@@ -7014,12 +7034,7 @@ display_debug_frames (struct dwarf_secti
 
 	  if (! do_debug_frames_interp && augmentation_data_len)
 	    {
-	      unsigned long i;
-
-	      printf ("  Augmentation data:    ");
-	      for (i = 0; i < augmentation_data_len; ++i)
-		printf (" %02x", augmentation_data[i]);
-	      putchar ('\n');
+	      display_augmentation_data (augmentation_data, augmentation_data_len);
 	      putchar ('\n');
 	    }
 	}