aboutsummaryrefslogtreecommitdiffstats
path: root/main/binutils/CVE-2021-3487.patch
blob: db99ae73d971bf4b365d139b6b681f0f14b56401 (plain) (blame)
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
From 647cebce12a6b0a26960220caff96ff38978cf24 Mon Sep 17 00:00:00 2001
From: Nick Clifton <nickc@redhat.com>
Date: Thu, 26 Nov 2020 17:08:33 +0000
Subject: [PATCH] Prevent a memory allocation failure when parsing corrupt
 DWARF debug sections.

	PR 26946
	* dwarf2.c (read_section): Check for debug sections with excessive
	sizes.

diff --git a/bfd/dwarf2.c b/bfd/dwarf2.c
index 977bf43a6a1..8bbfc81d3e7 100644
--- a/bfd/dwarf2.c
+++ b/bfd/dwarf2.c
@@ -531,22 +531,24 @@ read_section (bfd *	      abfd,
 	      bfd_byte **     section_buffer,
 	      bfd_size_type * section_size)
 {
-  asection *msec;
   const char *section_name = sec->uncompressed_name;
   bfd_byte *contents = *section_buffer;
-  bfd_size_type amt;
 
   /* The section may have already been read.  */
   if (contents == NULL)
     {
+      bfd_size_type amt;
+      asection *msec;
+      ufile_ptr filesize;
+
       msec = bfd_get_section_by_name (abfd, section_name);
-      if (! msec)
+      if (msec == NULL)
 	{
 	  section_name = sec->compressed_name;
 	  if (section_name != NULL)
 	    msec = bfd_get_section_by_name (abfd, section_name);
 	}
-      if (! msec)
+      if (msec == NULL)
 	{
 	  _bfd_error_handler (_("DWARF error: can't find %s section."),
 			      sec->uncompressed_name);
@@ -554,12 +556,23 @@ read_section (bfd *	      abfd,
 	  return FALSE;
 	}
 
-      *section_size = msec->rawsize ? msec->rawsize : msec->size;
+      amt = bfd_get_section_limit_octets (abfd, msec);
+      filesize = bfd_get_file_size (abfd);
+      if (amt >= filesize)
+	{
+	  /* PR 26946 */
+	  _bfd_error_handler (_("DWARF error: section %s is larger than its filesize! (0x%lx vs 0x%lx)"),
+			      section_name, (long) amt, (long) filesize);
+	  bfd_set_error (bfd_error_bad_value);
+	  return FALSE;
+	}
+      *section_size = amt;
       /* Paranoia - alloc one extra so that we can make sure a string
 	 section is NUL terminated.  */
-      amt = *section_size + 1;
+      amt += 1;
       if (amt == 0)
 	{
+	  /* Paranoia - this should never happen.  */
 	  bfd_set_error (bfd_error_no_memory);
 	  return FALSE;
 	}
-- 
2.27.0