This is for the release branch. Should we also use a graft for the master branch? It would be even better if we could add a binutils-next package that users could install, in my opinion. * gnu/packages/patches/binutils-CVE-2021-45078.patch: New file. * gnu/local.mk (dist_patch_DATA): Add it. * gnu/packages/base.scm (binutils)[source]: Use it. Signed-off-by: Maxim Cournoyer <maxim.cournoyer@gmail.com>
		
			
				
	
	
		
			257 lines
		
	
	
	
		
			7.1 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
			
		
		
	
	
			257 lines
		
	
	
	
		
			7.1 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
Fix CVE-2021-45078 (incomplete fix for CVE-2018-12699):
 | 
						|
 | 
						|
https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-45078
 | 
						|
https://sourceware.org/bugzilla/show_bug.cgi?id=28694
 | 
						|
 | 
						|
Patch copied from upstream source repository:
 | 
						|
 | 
						|
https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=161e87d12167b1e36193385485c1f6ce92f74f02
 | 
						|
 | 
						|
From 161e87d12167b1e36193385485c1f6ce92f74f02 Mon Sep 17 00:00:00 2001
 | 
						|
From: Alan Modra <amodra@gmail.com>
 | 
						|
Date: Wed, 15 Dec 2021 11:48:42 +1030
 | 
						|
Subject: [PATCH] PR28694, Out-of-bounds write in stab_xcoff_builtin_type
 | 
						|
 | 
						|
	PR 28694
 | 
						|
	* stabs.c (stab_xcoff_builtin_type): Make typenum unsigned.
 | 
						|
	Negate typenum earlier, simplifying bounds checking.  Correct
 | 
						|
	off-by-one indexing.  Adjust switch cases.
 | 
						|
---
 | 
						|
 binutils/stabs.c | 87 ++++++++++++++++++++++++------------------------
 | 
						|
 1 file changed, 43 insertions(+), 44 deletions(-)
 | 
						|
 | 
						|
diff --git a/binutils/stabs.c b/binutils/stabs.c
 | 
						|
index 274bfb0e7fa..83ee3ea5fa4 100644
 | 
						|
--- a/binutils/stabs.c
 | 
						|
+++ b/binutils/stabs.c
 | 
						|
@@ -202,7 +202,7 @@ static debug_type stab_find_type (void *, struct stab_handle *, const int *);
 | 
						|
 static bool stab_record_type
 | 
						|
   (void *, struct stab_handle *, const int *, debug_type);
 | 
						|
 static debug_type stab_xcoff_builtin_type
 | 
						|
-  (void *, struct stab_handle *, int);
 | 
						|
+  (void *, struct stab_handle *, unsigned int);
 | 
						|
 static debug_type stab_find_tagged_type
 | 
						|
   (void *, struct stab_handle *, const char *, int, enum debug_type_kind);
 | 
						|
 static debug_type *stab_demangle_argtypes
 | 
						|
@@ -3496,166 +3496,167 @@ stab_record_type (void *dhandle ATTRIBUTE_UNUSED, struct stab_handle *info,
 | 
						|
 
 | 
						|
 static debug_type
 | 
						|
 stab_xcoff_builtin_type (void *dhandle, struct stab_handle *info,
 | 
						|
-			 int typenum)
 | 
						|
+			 unsigned int typenum)
 | 
						|
 {
 | 
						|
   debug_type rettype;
 | 
						|
   const char *name;
 | 
						|
 
 | 
						|
-  if (typenum >= 0 || typenum < -XCOFF_TYPE_COUNT)
 | 
						|
+  typenum = -typenum - 1;
 | 
						|
+  if (typenum >= XCOFF_TYPE_COUNT)
 | 
						|
     {
 | 
						|
-      fprintf (stderr, _("Unrecognized XCOFF type %d\n"), typenum);
 | 
						|
+      fprintf (stderr, _("Unrecognized XCOFF type %d\n"), -typenum - 1);
 | 
						|
       return DEBUG_TYPE_NULL;
 | 
						|
     }
 | 
						|
-  if (info->xcoff_types[-typenum] != NULL)
 | 
						|
-    return info->xcoff_types[-typenum];
 | 
						|
+  if (info->xcoff_types[typenum] != NULL)
 | 
						|
+    return info->xcoff_types[typenum];
 | 
						|
 
 | 
						|
-  switch (-typenum)
 | 
						|
+  switch (typenum)
 | 
						|
     {
 | 
						|
-    case 1:
 | 
						|
+    case 0:
 | 
						|
       /* The size of this and all the other types are fixed, defined
 | 
						|
 	 by the debugging format.  */
 | 
						|
       name = "int";
 | 
						|
       rettype = debug_make_int_type (dhandle, 4, false);
 | 
						|
       break;
 | 
						|
-    case 2:
 | 
						|
+    case 1:
 | 
						|
       name = "char";
 | 
						|
       rettype = debug_make_int_type (dhandle, 1, false);
 | 
						|
       break;
 | 
						|
-    case 3:
 | 
						|
+    case 2:
 | 
						|
       name = "short";
 | 
						|
       rettype = debug_make_int_type (dhandle, 2, false);
 | 
						|
       break;
 | 
						|
-    case 4:
 | 
						|
+    case 3:
 | 
						|
       name = "long";
 | 
						|
       rettype = debug_make_int_type (dhandle, 4, false);
 | 
						|
       break;
 | 
						|
-    case 5:
 | 
						|
+    case 4:
 | 
						|
       name = "unsigned char";
 | 
						|
       rettype = debug_make_int_type (dhandle, 1, true);
 | 
						|
       break;
 | 
						|
-    case 6:
 | 
						|
+    case 5:
 | 
						|
       name = "signed char";
 | 
						|
       rettype = debug_make_int_type (dhandle, 1, false);
 | 
						|
       break;
 | 
						|
-    case 7:
 | 
						|
+    case 6:
 | 
						|
       name = "unsigned short";
 | 
						|
       rettype = debug_make_int_type (dhandle, 2, true);
 | 
						|
       break;
 | 
						|
-    case 8:
 | 
						|
+    case 7:
 | 
						|
       name = "unsigned int";
 | 
						|
       rettype = debug_make_int_type (dhandle, 4, true);
 | 
						|
       break;
 | 
						|
-    case 9:
 | 
						|
+    case 8:
 | 
						|
       name = "unsigned";
 | 
						|
       rettype = debug_make_int_type (dhandle, 4, true);
 | 
						|
       break;
 | 
						|
-    case 10:
 | 
						|
+    case 9:
 | 
						|
       name = "unsigned long";
 | 
						|
       rettype = debug_make_int_type (dhandle, 4, true);
 | 
						|
       break;
 | 
						|
-    case 11:
 | 
						|
+    case 10:
 | 
						|
       name = "void";
 | 
						|
       rettype = debug_make_void_type (dhandle);
 | 
						|
       break;
 | 
						|
-    case 12:
 | 
						|
+    case 11:
 | 
						|
       /* IEEE single precision (32 bit).  */
 | 
						|
       name = "float";
 | 
						|
       rettype = debug_make_float_type (dhandle, 4);
 | 
						|
       break;
 | 
						|
-    case 13:
 | 
						|
+    case 12:
 | 
						|
       /* IEEE double precision (64 bit).  */
 | 
						|
       name = "double";
 | 
						|
       rettype = debug_make_float_type (dhandle, 8);
 | 
						|
       break;
 | 
						|
-    case 14:
 | 
						|
+    case 13:
 | 
						|
       /* This is an IEEE double on the RS/6000, and different machines
 | 
						|
 	 with different sizes for "long double" should use different
 | 
						|
 	 negative type numbers.  See stabs.texinfo.  */
 | 
						|
       name = "long double";
 | 
						|
       rettype = debug_make_float_type (dhandle, 8);
 | 
						|
       break;
 | 
						|
-    case 15:
 | 
						|
+    case 14:
 | 
						|
       name = "integer";
 | 
						|
       rettype = debug_make_int_type (dhandle, 4, false);
 | 
						|
       break;
 | 
						|
-    case 16:
 | 
						|
+    case 15:
 | 
						|
       name = "boolean";
 | 
						|
       rettype = debug_make_bool_type (dhandle, 4);
 | 
						|
       break;
 | 
						|
-    case 17:
 | 
						|
+    case 16:
 | 
						|
       name = "short real";
 | 
						|
       rettype = debug_make_float_type (dhandle, 4);
 | 
						|
       break;
 | 
						|
-    case 18:
 | 
						|
+    case 17:
 | 
						|
       name = "real";
 | 
						|
       rettype = debug_make_float_type (dhandle, 8);
 | 
						|
       break;
 | 
						|
-    case 19:
 | 
						|
+    case 18:
 | 
						|
       /* FIXME */
 | 
						|
       name = "stringptr";
 | 
						|
       rettype = NULL;
 | 
						|
       break;
 | 
						|
-    case 20:
 | 
						|
+    case 19:
 | 
						|
       /* FIXME */
 | 
						|
       name = "character";
 | 
						|
       rettype = debug_make_int_type (dhandle, 1, true);
 | 
						|
       break;
 | 
						|
-    case 21:
 | 
						|
+    case 20:
 | 
						|
       name = "logical*1";
 | 
						|
       rettype = debug_make_bool_type (dhandle, 1);
 | 
						|
       break;
 | 
						|
-    case 22:
 | 
						|
+    case 21:
 | 
						|
       name = "logical*2";
 | 
						|
       rettype = debug_make_bool_type (dhandle, 2);
 | 
						|
       break;
 | 
						|
-    case 23:
 | 
						|
+    case 22:
 | 
						|
       name = "logical*4";
 | 
						|
       rettype = debug_make_bool_type (dhandle, 4);
 | 
						|
       break;
 | 
						|
-    case 24:
 | 
						|
+    case 23:
 | 
						|
       name = "logical";
 | 
						|
       rettype = debug_make_bool_type (dhandle, 4);
 | 
						|
       break;
 | 
						|
-    case 25:
 | 
						|
+    case 24:
 | 
						|
       /* Complex type consisting of two IEEE single precision values.  */
 | 
						|
       name = "complex";
 | 
						|
       rettype = debug_make_complex_type (dhandle, 8);
 | 
						|
       break;
 | 
						|
-    case 26:
 | 
						|
+    case 25:
 | 
						|
       /* Complex type consisting of two IEEE double precision values.  */
 | 
						|
       name = "double complex";
 | 
						|
       rettype = debug_make_complex_type (dhandle, 16);
 | 
						|
       break;
 | 
						|
-    case 27:
 | 
						|
+    case 26:
 | 
						|
       name = "integer*1";
 | 
						|
       rettype = debug_make_int_type (dhandle, 1, false);
 | 
						|
       break;
 | 
						|
-    case 28:
 | 
						|
+    case 27:
 | 
						|
       name = "integer*2";
 | 
						|
       rettype = debug_make_int_type (dhandle, 2, false);
 | 
						|
       break;
 | 
						|
-    case 29:
 | 
						|
+    case 28:
 | 
						|
       name = "integer*4";
 | 
						|
       rettype = debug_make_int_type (dhandle, 4, false);
 | 
						|
       break;
 | 
						|
-    case 30:
 | 
						|
+    case 29:
 | 
						|
       /* FIXME */
 | 
						|
       name = "wchar";
 | 
						|
       rettype = debug_make_int_type (dhandle, 2, false);
 | 
						|
       break;
 | 
						|
-    case 31:
 | 
						|
+    case 30:
 | 
						|
       name = "long long";
 | 
						|
       rettype = debug_make_int_type (dhandle, 8, false);
 | 
						|
       break;
 | 
						|
-    case 32:
 | 
						|
+    case 31:
 | 
						|
       name = "unsigned long long";
 | 
						|
       rettype = debug_make_int_type (dhandle, 8, true);
 | 
						|
       break;
 | 
						|
-    case 33:
 | 
						|
+    case 32:
 | 
						|
       name = "logical*8";
 | 
						|
       rettype = debug_make_bool_type (dhandle, 8);
 | 
						|
       break;
 | 
						|
-    case 34:
 | 
						|
+    case 33:
 | 
						|
       name = "integer*8";
 | 
						|
       rettype = debug_make_int_type (dhandle, 8, false);
 | 
						|
       break;
 | 
						|
@@ -3664,9 +3665,7 @@ stab_xcoff_builtin_type (void *dhandle, struct stab_handle *info,
 | 
						|
     }
 | 
						|
 
 | 
						|
   rettype = debug_name_type (dhandle, name, rettype);
 | 
						|
-
 | 
						|
-  info->xcoff_types[-typenum] = rettype;
 | 
						|
-
 | 
						|
+  info->xcoff_types[typenum] = rettype;
 | 
						|
   return rettype;
 | 
						|
 }
 | 
						|
 
 | 
						|
-- 
 | 
						|
2.27.0
 | 
						|
 |