From 4718b277e53566e44a8f3ed5272f7e05648ab46e Mon Sep 17 00:00:00 2001 From: Nick Clifton Date: Nov 13 2014 14:20:29 +0000 Subject: Fix problems with the ar program reported in FSF PR 17533. Resolves: BZ #1162666, #1162655 --- diff --git a/binutils-2.24-corrupt-ar.patch b/binutils-2.24-corrupt-ar.patch new file mode 100644 index 0000000..8c2f77c --- /dev/null +++ b/binutils-2.24-corrupt-ar.patch @@ -0,0 +1,199 @@ +diff -cpr ../binutils-2.24.orig/bfd/archive.c ./bfd/archive.c +*** ../binutils-2.24.orig/bfd/archive.c 2014-11-13 11:08:46.720741346 +0000 +--- ./bfd/archive.c 2014-11-13 11:12:38.908876606 +0000 +*************** _bfd_slurp_extended_name_table (bfd *abf +*** 1299,1304 **** +--- 1299,1306 ---- + { + byebye: + free (namedata); ++ bfd_ardata (abfd)->extended_names = NULL; ++ bfd_ardata (abfd)->extended_names_size = 0; + return FALSE; + } + +diff -cpr ../binutils-2.24.orig/binutils/ar.c ./binutils/ar.c +*** ../binutils-2.24.orig/binutils/ar.c 2014-11-13 11:08:46.808741776 +0000 +--- ./binutils/ar.c 2014-11-13 11:10:10.510151199 +0000 +*************** extract_file (bfd *abfd) +*** 1031,1036 **** +--- 1031,1045 ---- + bfd_size_type size; + struct stat buf; + ++ /* PR binutils/17533: Do not allow directory traversal ++ outside of the current directory tree. */ ++ if (! is_valid_archive_path (bfd_get_filename (abfd))) ++ { ++ non_fatal (_("illegal pathname found in archive member: %s"), ++ bfd_get_filename (abfd)); ++ return; ++ } ++ + if (bfd_stat_arch_elt (abfd, &buf) != 0) + /* xgettext:c-format */ + fatal (_("internal stat error on %s"), bfd_get_filename (abfd)); +Only in ./binutils: ar.c.orig +diff -cpr ../binutils-2.24.orig/binutils/bucomm.c ./binutils/bucomm.c +*** ../binutils-2.24.orig/binutils/bucomm.c 2014-11-13 11:08:46.791741693 +0000 +--- ./binutils/bucomm.c 2014-11-13 11:10:10.511151188 +0000 +*************** bfd_get_archive_filename (const bfd *abf +*** 624,626 **** +--- 624,652 ---- + bfd_get_filename (abfd)); + return buf; + } ++ ++ /* Returns TRUE iff PATHNAME, a filename of an archive member, ++ is valid for writing. For security reasons absolute paths ++ and paths containing /../ are not allowed. See PR 17533. */ ++ ++ bfd_boolean ++ is_valid_archive_path (char const * pathname) ++ { ++ const char * n = pathname; ++ ++ if (IS_ABSOLUTE_PATH (n)) ++ return FALSE; ++ ++ while (*n) ++ { ++ if (*n == '.' && *++n == '.' && ( ! *++n || IS_DIR_SEPARATOR (*n))) ++ return FALSE; ++ ++ while (*n && ! IS_DIR_SEPARATOR (*n)) ++ n++; ++ while (IS_DIR_SEPARATOR (*n)) ++ n++; ++ } ++ ++ return TRUE; ++ } +diff -cpr ../binutils-2.24.orig/binutils/bucomm.h ./binutils/bucomm.h +*** ../binutils-2.24.orig/binutils/bucomm.h 2014-11-13 11:08:46.798741727 +0000 +--- ./binutils/bucomm.h 2014-11-13 11:10:10.511151188 +0000 +*************** bfd_vma parse_vma (const char *, const c +*** 58,63 **** +--- 58,65 ---- + + off_t get_file_size (const char *); + ++ bfd_boolean is_valid_archive_path (char const *); ++ + extern char *program_name; + + /* filemode.c */ +diff -cpr ../binutils-2.24.orig/binutils/doc/binutils.texi ./binutils/doc/binutils.texi +*** ../binutils-2.24.orig/binutils/doc/binutils.texi 2014-11-13 11:08:46.955742495 +0000 +--- ./binutils/doc/binutils.texi 2014-11-13 11:10:10.513151165 +0000 +*************** a normal archive. Instead the elements +*** 234,240 **** + individually to the second archive. + + The paths to the elements of the archive are stored relative to the +! archive itself. + + @cindex compatibility, @command{ar} + @cindex @command{ar} compatibility +--- 234,241 ---- + individually to the second archive. + + The paths to the elements of the archive are stored relative to the +! archive itself. For security reasons absolute paths and paths with a +! @code{/../} component are not allowed. + + @cindex compatibility, @command{ar} + @cindex @command{ar} compatibility +diff -cpr ../binutils-2.24.orig/binutils/objcopy.c ./binutils/objcopy.c +*** ../binutils-2.24.orig/binutils/objcopy.c 2014-11-13 11:08:46.798741727 +0000 +--- ./binutils/objcopy.c 2014-11-13 11:10:10.514151156 +0000 +*************** copy_archive (bfd *ibfd, bfd *obfd, cons +*** 2182,2187 **** +--- 2182,2197 ---- + bfd_boolean del = TRUE; + bfd_boolean ok_object; + ++ /* PR binutils/17533: Do not allow directory traversal ++ outside of the current directory tree by archive members. */ ++ if (! is_valid_archive_path (bfd_get_filename (this_element))) ++ { ++ non_fatal (_("illegal pathname found in archive member: %s"), ++ bfd_get_filename (this_element)); ++ status = 1; ++ goto cleanup_and_exit; ++ } ++ + /* Create an output file for this member. */ + output_name = concat (dir, "/", + bfd_get_filename (this_element), (char *) 0); +*************** copy_archive (bfd *ibfd, bfd *obfd, cons +*** 2191,2198 **** + { + output_name = make_tempdir (output_name); + if (output_name == NULL) +! fatal (_("cannot create tempdir for archive copying (error: %s)"), +! strerror (errno)); + + l = (struct name_list *) xmalloc (sizeof (struct name_list)); + l->name = output_name; +--- 2201,2212 ---- + { + output_name = make_tempdir (output_name); + if (output_name == NULL) +! { +! non_fatal (_("cannot create tempdir for archive copying (error: %s)"), +! strerror (errno)); +! status = 1; +! goto cleanup_and_exit; +! } + + l = (struct name_list *) xmalloc (sizeof (struct name_list)); + l->name = output_name; +*************** copy_archive (bfd *ibfd, bfd *obfd, cons +*** 2234,2240 **** + { + bfd_nonfatal_message (output_name, NULL, NULL, NULL); + status = 1; +! return; + } + + if (ok_object) +--- 2248,2254 ---- + { + bfd_nonfatal_message (output_name, NULL, NULL, NULL); + status = 1; +! goto cleanup_and_exit; + } + + if (ok_object) +*************** copy_archive (bfd *ibfd, bfd *obfd, cons +*** 2295,2301 **** + { + status = 1; + bfd_nonfatal_message (filename, NULL, NULL, NULL); +- return; + } + + filename = bfd_get_filename (ibfd); +--- 2309,2314 ---- +*************** copy_archive (bfd *ibfd, bfd *obfd, cons +*** 2303,2311 **** + { + status = 1; + bfd_nonfatal_message (filename, NULL, NULL, NULL); +- return; + } + + /* Delete all the files that we opened. */ + for (l = list; l != NULL; l = l->next) + { +--- 2316,2324 ---- + { + status = 1; + bfd_nonfatal_message (filename, NULL, NULL, NULL); + } + ++ cleanup_and_exit: + /* Delete all the files that we opened. */ + for (l = list; l != NULL; l = l->next) + { diff --git a/binutils.spec b/binutils.spec index e491a3f..9636894 100644 --- a/binutils.spec +++ b/binutils.spec @@ -17,7 +17,7 @@ Summary: A GNU collection of binary utilities Name: %{?cross}binutils%{?_with_debug:-debug} Version: 2.24 -Release: 29%{?dist} +Release: 30%{?dist} License: GPLv3+ Group: Development/Tools URL: http://sources.redhat.com/binutils @@ -73,6 +73,7 @@ Patch30: binutils-HEAD-change-ld-notice-interface.patch Patch31: binutils-2.24-corrupt-binaries.patch Patch32: binutils-2.24-strings-default-all.patch Patch33: binutils-2.24-plugin-sym-add.patch +Patch34: binutils-2.24-corrupt-ar.patch Provides: bundled(libiberty) @@ -521,11 +522,15 @@ exit 0 %endif # %{isnative} %changelog -* Thu Nov 06 2014 Nick Clifton - 2.22-29 +* Thu Nov 13 2014 Nick Clifton - 2.24-30 +- Fix problems with the ar program reported in FSF PR 17533. + Resolves: BZ #1162666, #1162655 + +* Thu Nov 06 2014 Nick Clifton - 2.24-29 - Fix seg-fault when adding symbols via a plugin. Resovles: BZ #1149660 -* Fri Oct 31 2014 Nick Clifton - 2.22-28 +* Fri Oct 31 2014 Nick Clifton - 2.24-28 - Remove bogus part of addr2line-dynsymtab.patch. Resovles: BZ #1157706