Toggle diff (291 lines)
diff --git a/gnu/local.mk b/gnu/local.mk
index aa0117a3f5..546b940eb6 100644
--- a/gnu/local.mk
+++ b/gnu/local.mk
@@ -906,6 +906,7 @@ dist_patch_DATA = \
%D%/packages/patches/binutils-loongson-workaround.patch \
%D%/packages/patches/binutils-mingw-w64-timestamp.patch \
%D%/packages/patches/binutils-mingw-w64-deterministic.patch \
+ %D%/packages/patches/binutils-CVE-2021-45078.patch \
%D%/packages/patches/blender-2.79-gcc8.patch \
%D%/packages/patches/blender-2.79-gcc9.patch \
%D%/packages/patches/blender-2.79-newer-ffmpeg.patch \
diff --git a/gnu/packages/base.scm b/gnu/packages/base.scm
index 12e4de52d4..be6fbf608d 100644
--- a/gnu/packages/base.scm
+++ b/gnu/packages/base.scm
@@ -521,7 +521,8 @@ (define-public binutils
(sha256
(base32 "1m3b2rdfv1dmdpd0bzg1hy7i8a2qng53szc6livyi3nh6101mz37"))
(patches (search-patches "binutils-loongson-workaround.patch"
- "binutils-2.37-file-descriptor-leak.patch"))))
+ "binutils-2.37-file-descriptor-leak.patch"
+ "binutils-CVE-2021-45078.patch"))))
(build-system gnu-build-system)
(arguments
`(#:configure-flags '(;; Add `-static-libgcc' to not retain a dependency
diff --git a/gnu/packages/patches/binutils-CVE-2021-45078.patch b/gnu/packages/patches/binutils-CVE-2021-45078.patch
new file mode 100644
index 0000000000..fca692bdb5
--- /dev/null
+++ b/gnu/packages/patches/binutils-CVE-2021-45078.patch
@@ -0,0 +1,257 @@
+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
+
--
2.34.0