summaryrefslogtreecommitdiffstats
path: root/external/poky/meta/recipes-devtools/elfutils/files/CVE-2019-7149.patch
blob: 215a1715bfb8263bbaef64f5fb6ccd1f4aa667b9 (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
From 2562759d6fe5b364fe224852e64e8bda39eb2e35 Mon Sep 17 00:00:00 2001
From: Mark Wielaard <mark@klomp.org>
Date: Sun, 20 Jan 2019 22:10:18 +0100
Subject: [PATCH] libdw: Check terminating NUL byte in dwarf_getsrclines for
 dir/file table.

For DWARF version < 5 the .debug_line directory and file tables consist
of a terminating NUL byte after all strings. The code used to just skip
this without checking it actually existed. This could case a spurious
read past the end of data.

Fix the same issue in readelf.

https://sourceware.org/bugzilla/show_bug.cgi?id=24102

Signed-off-by: Mark Wielaard <mark@klomp.org>

Upstream-Status: Backport
CVE: CVE-2019-7149
Signed-off-by: Armin Kuster <akuster@mvista.com>

---
 libdw/ChangeLog           |  5 +++++
 libdw/dwarf_getsrclines.c | 11 ++++++++---
 src/ChangeLog             |  5 +++++
 src/readelf.c             |  8 ++++++--
 4 files changed, 24 insertions(+), 5 deletions(-)

Index: elfutils-0.175/libdw/dwarf_getsrclines.c
===================================================================
--- elfutils-0.175.orig/libdw/dwarf_getsrclines.c
+++ elfutils-0.175/libdw/dwarf_getsrclines.c
@@ -315,7 +315,7 @@ read_srclines (Dwarf *dbg,
   if (version < 5)
     {
       const unsigned char *dirp = linep;
-      while (*dirp != 0)
+      while (dirp < lineendp && *dirp != 0)
 	{
 	  uint8_t *endp = memchr (dirp, '\0', lineendp - dirp);
 	  if (endp == NULL)
@@ -323,6 +323,8 @@ read_srclines (Dwarf *dbg,
 	  ++ndirs;
 	  dirp = endp + 1;
 	}
+      if (dirp >= lineendp || *dirp != '\0')
+	goto invalid_data;
       ndirs = ndirs + 1; /* There is always the "unknown" dir.  */
     }
   else
@@ -392,11 +394,12 @@ read_srclines (Dwarf *dbg,
 	{
 	  dirarray[n].dir = (char *) linep;
 	  uint8_t *endp = memchr (linep, '\0', lineendp - linep);
-	  assert (endp != NULL);
+	  assert (endp != NULL); // Checked above when calculating ndirlist.
 	  dirarray[n].len = endp - linep;
 	  linep = endp + 1;
 	}
       /* Skip the final NUL byte.  */
+      assert (*linep == '\0'); // Checked above when calculating ndirlist.
       ++linep;
     }
   else
@@ -471,7 +474,7 @@ read_srclines (Dwarf *dbg,
     {
       if (unlikely (linep >= lineendp))
 	goto invalid_data;
-      while (*linep != 0)
+      while (linep < lineendp && *linep != '\0')
 	{
 	  struct filelist *new_file = NEW_FILE ();
 
@@ -527,6 +530,8 @@ read_srclines (Dwarf *dbg,
 	    goto invalid_data;
 	  get_uleb128 (new_file->info.length, linep, lineendp);
 	}
+      if (linep >= lineendp || *linep != '\0')
+	goto invalid_data;
       /* Skip the final NUL byte.  */
       ++linep;
     }
Index: elfutils-0.175/src/readelf.c
===================================================================
--- elfutils-0.175.orig/src/readelf.c
+++ elfutils-0.175/src/readelf.c
@@ -8444,7 +8444,7 @@ print_debug_line_section (Dwfl_Module *d
 	}
       else
 	{
-	  while (*linep != 0)
+	  while (linep < lineendp && *linep != 0)
 	    {
 	      unsigned char *endp = memchr (linep, '\0', lineendp - linep);
 	      if (unlikely (endp == NULL))
@@ -8454,6 +8454,8 @@ print_debug_line_section (Dwfl_Module *d
 
 	      linep = endp + 1;
 	    }
+	  if (linep >= lineendp || *linep != 0)
+	    goto invalid_unit;
 	  /* Skip the final NUL byte.  */
 	  ++linep;
 	}
@@ -8523,7 +8525,7 @@ print_debug_line_section (Dwfl_Module *d
       else
 	{
 	  puts (gettext (" Entry Dir   Time      Size      Name"));
-	  for (unsigned int cnt = 1; *linep != 0; ++cnt)
+	  for (unsigned int cnt = 1; linep < lineendp && *linep != 0; ++cnt)
 	    {
 	      /* First comes the file name.  */
 	      char *fname = (char *) linep;
@@ -8553,6 +8555,8 @@ print_debug_line_section (Dwfl_Module *d
 	      printf (" %-5u %-5u %-9u %-9u %s\n",
 		      cnt, diridx, mtime, fsize, fname);
 	    }
+	  if (linep >= lineendp || *linep != '\0')
+	    goto invalid_unit;
 	  /* Skip the final NUL byte.  */
 	  ++linep;
 	}
Index: elfutils-0.175/libdw/ChangeLog
===================================================================
--- elfutils-0.175.orig/libdw/ChangeLog
+++ elfutils-0.175/libdw/ChangeLog
@@ -1,3 +1,8 @@
+2019-01-20  Mark Wielaard  <mark@klomp.org>
+
+       * dwarf_getsrclines.c (read_srclines): Check terminating NUL byte
+       for dir and file lists.
+
 2018-10-20  Mark Wielaard  <mark@klomp.org>
 
 	* libdw.map (ELFUTILS_0.175): New section. Add dwelf_elf_begin.
Index: elfutils-0.175/src/ChangeLog
===================================================================
--- elfutils-0.175.orig/src/ChangeLog
+++ elfutils-0.175/src/ChangeLog
@@ -1,3 +1,8 @@
+2019-01-20  Mark Wielaard  <mark@klomp.org>
+
+       * readelf.c (print_debug_line_section): Check terminating NUL byte
+       for dir and file tables.
+
 2018-11-10  Mark Wielaard  <mark@klomp.org>
 
 	* elflint.c (check_program_header): Allow PT_GNU_EH_FRAME segment