blob: 935f2661fecfcb3c4838a9cc319e5974a08dbd34 [file] [log] [blame]
Brad Bishopc342db32019-05-15 21:57:59 -04001From a608b79f30ab3f670095e14ba3d3b5b24a19fe68 Mon Sep 17 00:00:00 2001
2From: Sandra Loosemore <sandra@codesourcery.com>
3Date: Thu, 25 Apr 2019 07:27:02 -0700
4Subject: [PATCH] Detect invalid length field in debug frame FDE header.
5
6GDB was failing to catch cases where a corrupt ELF or core file
7contained an invalid length value in a Dwarf debug frame FDE header.
8It was checking for buffer overflow but not cases where the length was
9negative or caused pointer wrap-around.
10
11In addition to the additional validity check, this patch cleans up the
12multiple signed/unsigned conversions on the length field so that an
13unsigned representation is used consistently throughout.
14
15This patch fixes CVE-2017-9778 and PR gdb/21600.
16
172019-04-25 Sandra Loosemore <sandra@codesourcery.com>
18 Kang Li <kanglictf@gmail.com>
19
20 PR gdb/21600
21
22 * dwarf2-frame.c (read_initial_length): Be consistent about using
23 unsigned representation of length.
24 (decode_frame_entry_1): Likewise. Check for wraparound of
25 end pointer as well as buffer overflow.
26
27Upstream-Status: Backport [https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=723adb650a31859d7cc45832cb8adca0206455ed]
28CVE: CVE-2017-9778
29Signed-off-by: Anuj Mittal <anuj.mittal@intel.com>
30---
31 gdb/ChangeLog | 11 +++++++++++
32 gdb/dwarf2-frame.c | 14 +++++++-------
33 2 files changed, 18 insertions(+), 7 deletions(-)
34
35diff --git a/gdb/ChangeLog b/gdb/ChangeLog
36index 3711dc7..0a9720b 100644
37--- a/gdb/ChangeLog
38+++ b/gdb/ChangeLog
39@@ -1,3 +1,14 @@
40+2019-04-25 Sandra Loosemore <sandra@codesourcery.com>
41+ Kang Li <kanglictf@gmail.com>
42+
43+ PR gdb/21600
44+
45+ * dwarf2-frame.c (read_initial_length): Be consistent about using
46+ unsigned representation of length.
47+ (decode_frame_entry_1): Likewise. Check for wraparound of
48+ end pointer as well as buffer overflow.
49+
50+
51 2018-12-23 Joel Brobecker <brobecker@adacore.com>
52
53 * version.in: Set GDB version number to 8.2.1.
54diff --git a/gdb/dwarf2-frame.c b/gdb/dwarf2-frame.c
55index 91e16cf..a7b99fd 100644
56--- a/gdb/dwarf2-frame.c
57+++ b/gdb/dwarf2-frame.c
58@@ -1477,7 +1477,7 @@ static ULONGEST
59 read_initial_length (bfd *abfd, const gdb_byte *buf,
60 unsigned int *bytes_read_ptr)
61 {
62- LONGEST result;
63+ ULONGEST result;
64
65 result = bfd_get_32 (abfd, buf);
66 if (result == 0xffffffff)
67@@ -1780,7 +1780,7 @@ decode_frame_entry_1 (struct comp_unit *unit, const gdb_byte *start,
68 {
69 struct gdbarch *gdbarch = get_objfile_arch (unit->objfile);
70 const gdb_byte *buf, *end;
71- LONGEST length;
72+ ULONGEST length;
73 unsigned int bytes_read;
74 int dwarf64_p;
75 ULONGEST cie_id;
76@@ -1791,15 +1791,15 @@ decode_frame_entry_1 (struct comp_unit *unit, const gdb_byte *start,
77 buf = start;
78 length = read_initial_length (unit->abfd, buf, &bytes_read);
79 buf += bytes_read;
80- end = buf + length;
81-
82- /* Are we still within the section? */
83- if (end > unit->dwarf_frame_buffer + unit->dwarf_frame_size)
84- return NULL;
85+ end = buf + (size_t) length;
86
87 if (length == 0)
88 return end;
89
90+ /* Are we still within the section? */
91+ if (end <= buf || end > unit->dwarf_frame_buffer + unit->dwarf_frame_size)
92+ return NULL;
93+
94 /* Distinguish between 32 and 64-bit encoded frame info. */
95 dwarf64_p = (bytes_read == 12);
96
97--
982.7.4
99