From 38486b2c07e5d925b0a8351972ccd5f02a3f748b Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Mon, 26 Apr 2021 16:59:34 +0100 Subject: [PATCH] Add fix for broken CVE-2021-20197 fix related: rhbz#1951278 --- ...480d7ce1bcd57669a62867efc68418d0de7c.patch | 163 ++++++++++++++++++ mingw-binutils.spec | 10 +- 2 files changed, 172 insertions(+), 1 deletion(-) create mode 100644 binutils-gdb.git-6184480d7ce1bcd57669a62867efc68418d0de7c.patch diff --git a/binutils-gdb.git-6184480d7ce1bcd57669a62867efc68418d0de7c.patch b/binutils-gdb.git-6184480d7ce1bcd57669a62867efc68418d0de7c.patch new file mode 100644 index 0000000..87f66e3 --- /dev/null +++ b/binutils-gdb.git-6184480d7ce1bcd57669a62867efc68418d0de7c.patch @@ -0,0 +1,163 @@ +diff -ur binutils-2.34.old/binutils/ar.c binutils-2.34.new/binutils/ar.c +--- binutils-2.34.old/binutils/ar.c 2021-04-26 17:02:01.517211609 +0100 ++++ binutils-2.34.new/binutils/ar.c 2021-04-26 17:03:25.895213701 +0100 +@@ -25,7 +25,6 @@ + + #include "sysdep.h" + #include "bfd.h" +-#include "libbfd.h" + #include "libiberty.h" + #include "progress.h" + #include "getopt.h" +@@ -1198,10 +1197,8 @@ + bfd *contents_head = iarch->archive_next; + int ofd = -1; + struct stat target_stat; +- bfd_boolean skip_stat = FALSE; + +- old_name = (char *) xmalloc (strlen (bfd_get_filename (iarch)) + 1); +- strcpy (old_name, bfd_get_filename (iarch)); ++ old_name = xstrdup (bfd_get_filename (iarch)); + new_name = make_tempname (old_name, &ofd); + + if (new_name == NULL) +@@ -1246,11 +1243,9 @@ + + #if !defined (_WIN32) || defined (__CYGWIN32__) + ofd = dup (ofd); +- if (iarch == NULL || iarch->iostream == NULL) +- skip_stat = TRUE; +- else if (ofd == -1 || fstat (fileno (iarch->iostream), &target_stat) != 0) +- bfd_fatal (old_name); + #endif ++ if (ofd == -1 || bfd_stat (iarch, &target_stat) != 0) ++ bfd_fatal (old_name); + + if (!bfd_close (obfd)) + bfd_fatal (old_name); +@@ -1261,7 +1256,7 @@ + /* We don't care if this fails; we might be creating the archive. */ + bfd_close (iarch); + +- if (smart_rename (new_name, old_name, ofd, skip_stat ? NULL : &target_stat, 0) != 0) ++ if (smart_rename (new_name, old_name, ofd, &target_stat, 0) != 0) + xexit (1); + free (old_name); + free (new_name); +diff -ur binutils-2.34.old/binutils/arsup.c binutils-2.34.new/binutils/arsup.c +--- binutils-2.34.old/binutils/arsup.c 2021-04-26 17:02:01.517211609 +0100 ++++ binutils-2.34.new/binutils/arsup.c 2021-04-26 17:04:43.271215620 +0100 +@@ -42,6 +42,8 @@ + + static bfd *obfd; + static char *real_name; ++static char *temp_name; ++static int real_ofd; + static FILE *outfile; + + static void +@@ -149,27 +151,24 @@ + void + ar_open (char *name, int t) + { +- char *tname; +- const char *bname = lbasename (name); +- real_name = name; +- +- /* Prepend tmp- to the beginning, to avoid file-name clashes after +- truncation on filesystems with limited namespaces (DOS). */ +- if (asprintf (&tname, "%.*stmp-%s", (int) (bname - name), name, bname) == -1) ++ real_name = xstrdup (name); ++ temp_name = make_tempname (real_name, &real_ofd); ++ ++ if (temp_name == NULL) + { +- fprintf (stderr, _("%s: Can't allocate memory for temp name (%s)\n"), ++ fprintf (stderr, _("%s: Can't open temporary file (%s)\n"), + program_name, strerror(errno)); + maybequit (); + return; + } + +- obfd = bfd_openw (tname, NULL); ++ obfd = bfd_fdopenw (temp_name, NULL, real_ofd); + + if (!obfd) + { + fprintf (stderr, + _("%s: Can't open output archive %s\n"), +- program_name, tname); ++ program_name, temp_name); + + maybequit (); + } +@@ -344,10 +343,9 @@ + } + else + { +- char *ofilename = xstrdup (bfd_get_filename (obfd)); + bfd_boolean skip_stat = FALSE; + struct stat target_stat; +- int ofd = -1; ++ int ofd = real_ofd; + + if (deterministic > 0) + obfd->flags |= BFD_DETERMINISTIC_OUTPUT; +@@ -355,17 +353,32 @@ + #if !defined (_WIN32) || defined (__CYGWIN32__) + /* It's OK to fail; at worst it will result in SMART_RENAME using a slow + copy fallback to write the output. */ +- ofd = dup (fileno (obfd->iostream)); +- if (lstat (real_name, &target_stat) != 0) +- skip_stat = TRUE; ++ ofd = dup (ofd); + #endif + + bfd_close (obfd); + +- smart_rename (ofilename, real_name, ofd, ++ if (lstat (real_name, &target_stat) != 0) ++ { ++ /* The temp file created in ar_open has mode 0600 as per mkstemp. ++ Create the real empty output file here so smart_rename will ++ update the mode according to the process umask. */ ++ obfd = bfd_openw (real_name, NULL); ++ if (obfd == NULL ++ || bfd_stat (obfd, &target_stat) != 0) ++ skip_stat = TRUE; ++ if (obfd != NULL) ++ { ++ bfd_set_format (obfd, bfd_archive); ++ bfd_close (obfd); ++ } ++ } ++ ++ smart_rename (temp_name, real_name, ofd, + skip_stat ? NULL : &target_stat, 0); + obfd = 0; +- free (ofilename); ++ free (temp_name); ++ free (real_name); + } + } + +diff -ur binutils-2.34.old/binutils/objcopy.c binutils-2.34.new/binutils/objcopy.c +--- binutils-2.34.old/binutils/objcopy.c 2021-04-26 17:02:01.517211609 +0100 ++++ binutils-2.34.new/binutils/objcopy.c 2021-04-26 17:05:17.876216478 +0100 +@@ -20,7 +20,6 @@ + + #include "sysdep.h" + #include "bfd.h" +-#include "libbfd.h" + #include "progress.h" + #include "getopt.h" + #include "libiberty.h" +@@ -3704,7 +3703,7 @@ + /* To allow us to do "strip *" without dying on the first + non-object file, failures are nonfatal. */ + ibfd = bfd_openr (input_filename, input_target); +- if (ibfd == NULL || fstat (fileno (ibfd->iostream), in_stat) != 0) ++ if (ibfd == NULL || bfd_stat (ibfd, in_stat) != 0) + { + bfd_nonfatal_message (input_filename, NULL, NULL, NULL); + status = 1; diff --git a/mingw-binutils.spec b/mingw-binutils.spec index 1fd022f..a8f5c24 100644 --- a/mingw-binutils.spec +++ b/mingw-binutils.spec @@ -2,7 +2,7 @@ Name: mingw-binutils Version: 2.34 -Release: 8%{?dist} +Release: 9%{?dist} Summary: Cross-compiled version of binutils for Win32 and Win64 environments License: GPLv2+ and LGPLv2+ and GPLv3+ and LGPLv3+ @@ -104,6 +104,10 @@ Patch19: binutils-gdb.git-365f5fb6d0f0da83817431a275e99e6f6babbe04.patch Patch20: binutils-gdb.git-1a1c3b4cc17687091cff5a368bd6f13742bcfdf8.patch Patch21: binutils-gdb.git-014cc7f849e8209623fc99264814bce7b3b6faf2.patch +# This fixes CVE-2021-20197 patches above. See: +# https://sourceware.org/bugzilla/show_bug.cgi?id=27270 +Patch22: binutils-gdb.git-6184480d7ce1bcd57669a62867efc68418d0de7c.patch + ### MINGW specific patches Patch102: binutils-config.patch @@ -369,6 +373,10 @@ rm -rf %{buildroot}/multilib %changelog +* Mon Apr 26 2021 Richard W.M. Jones - 2.34-9 +- Add fix for broken CVE-2021-20197 fix + related: rhbz#1951278 + * Fri Apr 16 2021 Mohan Boddu - 2.34-8 - Rebuilt for RHEL 9 BETA on Apr 15th 2021. Related: rhbz#1947937