From e38a1643f10dc33ea33bf488002801050721904b Mon Sep 17 00:00:00 2001 From: Nick Clifton Date: Mon, 20 Dec 2021 14:58:26 +0000 Subject: [PATCH] Fix a potential illegal memory access parsing a COFF format file. (#2033716) --- binutils-CVE-2021-45078.patch | 230 ++++++++++++++++++++++++++++++++++ binutils.spec | 9 +- 2 files changed, 238 insertions(+), 1 deletion(-) create mode 100644 binutils-CVE-2021-45078.patch diff --git a/binutils-CVE-2021-45078.patch b/binutils-CVE-2021-45078.patch new file mode 100644 index 0000000..3ce3bcc --- /dev/null +++ b/binutils-CVE-2021-45078.patch @@ -0,0 +1,230 @@ +--- binutils.orig/binutils/stabs.c 2021-12-20 12:51:40.953113439 +0000 ++++ binutils-2.37/binutils/stabs.c 2021-12-20 12:56:07.607348945 +0000 +@@ -202,7 +202,7 @@ static debug_type stab_find_type (void * + 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 ATTRIBUT + + 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, + } + + rettype = debug_name_type (dhandle, name, rettype); +- +- info->xcoff_types[-typenum] = rettype; +- ++ info->xcoff_types[typenum] = rettype; + return rettype; + } + diff --git a/binutils.spec b/binutils.spec index 29c90ec..3579aea 100644 --- a/binutils.spec +++ b/binutils.spec @@ -39,7 +39,7 @@ Summary: A GNU collection of binary utilities Name: binutils%{?name_cross}%{?_with_debug:-debug} Version: 2.37 -Release: 14%{?dist} +Release: 15%{?dist} License: GPLv3+ URL: https://sourceware.org/binutils @@ -303,6 +303,10 @@ Patch23: binutils-gas-multibyte-warnings.patch # Lifetime: Fixed in 2.38. Patch24: binutils-AArch64-EFI.patch +# Purpose: Fix a potential illegal memory access parsing a corrupt COFF file. +# Lifetime: Fixed in 2.38. +Patch25: binutils-CVE-2021-45078.patch + #---------------------------------------------------------------------------- Provides: bundled(libiberty) @@ -920,6 +924,9 @@ exit 0 #---------------------------------------------------------------------------- %changelog +* Mon Dec 20 2021 Nick Clifton - 2.37-15 +- Fix a potential illegal memory access parsing a COFF format file. (#2033716) + * Wed Dec 01 2021 Nick Clifton - 2.37-14 - Add support for the EFI format to the AArch64 target. (#2027515)