Blame SOURCES/binutils-rh1162655.patch

d570a8
diff -rcp binutils-2.23.52.0.1.orig/binutils/ar.c binutils-2.23.52.0.1/binutils/ar.c
d570a8
*** binutils-2.23.52.0.1.orig/binutils/ar.c	2014-11-11 20:51:37.044244928 +0000
d570a8
--- binutils-2.23.52.0.1/binutils/ar.c	2014-11-11 20:53:41.245801920 +0000
d570a8
*************** extract_file (bfd *abfd)
d570a8
*** 1013,1018 ****
d570a8
--- 1013,1027 ----
d570a8
    bfd_size_type size;
d570a8
    struct stat buf;
d570a8
  
d570a8
+   /* PR binutils/17533: Do not allow directory traversal
d570a8
+      outside of the current directory tree.  */
d570a8
+   if (! is_valid_archive_path (bfd_get_filename (abfd)))
d570a8
+     {
d570a8
+       non_fatal (_("illegal pathname found in archive member: %s"),
d570a8
+ 		 bfd_get_filename (abfd));
d570a8
+       return;
d570a8
+     }
d570a8
+ 
d570a8
    if (bfd_stat_arch_elt (abfd, &buf) != 0)
d570a8
      /* xgettext:c-format */
d570a8
      fatal (_("internal stat error on %s"), bfd_get_filename (abfd));
d570a8
diff -rcp binutils-2.23.52.0.1.orig/binutils/bucomm.c binutils-2.23.52.0.1/binutils/bucomm.c
d570a8
*** binutils-2.23.52.0.1.orig/binutils/bucomm.c	2014-11-11 20:51:37.022244830 +0000
d570a8
--- binutils-2.23.52.0.1/binutils/bucomm.c	2014-11-11 20:52:45.452550953 +0000
d570a8
*************** bfd_get_archive_filename (const bfd *abf
d570a8
*** 624,626 ****
d570a8
--- 624,652 ----
d570a8
  	   bfd_get_filename (abfd));
d570a8
    return buf;
d570a8
  }
d570a8
+ 
d570a8
+ /* Returns TRUE iff PATHNAME, a filename of an archive member,
d570a8
+    is valid for writing.  For security reasons absolute paths
d570a8
+    and paths containing /../ are not allowed.  See PR 17533.  */
d570a8
+ 
d570a8
+ bfd_boolean
d570a8
+ is_valid_archive_path (char const * pathname)
d570a8
+ {
d570a8
+   const char * n = pathname;
d570a8
+ 
d570a8
+   if (IS_ABSOLUTE_PATH (n))
d570a8
+     return FALSE;
d570a8
+ 
d570a8
+   while (*n)
d570a8
+     {
d570a8
+       if (*n == '.' && *++n == '.' && ( ! *++n || IS_DIR_SEPARATOR (*n)))
d570a8
+ 	return FALSE;
d570a8
+ 
d570a8
+       while (*n && ! IS_DIR_SEPARATOR (*n))
d570a8
+ 	n++;
d570a8
+       while (IS_DIR_SEPARATOR (*n))
d570a8
+ 	n++;
d570a8
+     }
d570a8
+ 
d570a8
+   return TRUE;
d570a8
+ }
d570a8
diff -rcp binutils-2.23.52.0.1.orig/binutils/bucomm.h binutils-2.23.52.0.1/binutils/bucomm.h
d570a8
*** binutils-2.23.52.0.1.orig/binutils/bucomm.h	2014-11-11 20:51:37.030244866 +0000
d570a8
--- binutils-2.23.52.0.1/binutils/bucomm.h	2014-11-11 20:53:03.228630913 +0000
d570a8
*************** bfd_vma parse_vma (const char *, const c
d570a8
*** 58,63 ****
d570a8
--- 58,65 ----
d570a8
  
d570a8
  off_t get_file_size (const char *);
d570a8
  
d570a8
+ bfd_boolean is_valid_archive_path (char const *);
d570a8
+ 
d570a8
  extern char *program_name;
d570a8
  
d570a8
  /* filemode.c */
d570a8
diff -rcp binutils-2.23.52.0.1.orig/binutils/doc/binutils.texi binutils-2.23.52.0.1/binutils/doc/binutils.texi
d570a8
*** binutils-2.23.52.0.1.orig/binutils/doc/binutils.texi	2014-11-11 20:51:37.052244964 +0000
d570a8
--- binutils-2.23.52.0.1/binutils/doc/binutils.texi	2014-11-11 20:56:13.759503335 +0000
d570a8
*************** a normal archive.  Instead the elements
d570a8
*** 234,240 ****
d570a8
  individually to the second archive.
d570a8
  
d570a8
  The paths to the elements of the archive are stored relative to the
d570a8
! archive itself.
d570a8
  
d570a8
  @cindex compatibility, @command{ar}
d570a8
  @cindex @command{ar} compatibility
d570a8
--- 234,241 ----
d570a8
  individually to the second archive.
d570a8
  
d570a8
  The paths to the elements of the archive are stored relative to the
d570a8
! archive itself.  For security reasons absolute paths and paths with a
d570a8
! @code{/../} component are not allowed.
d570a8
  
d570a8
  @cindex compatibility, @command{ar}
d570a8
  @cindex @command{ar} compatibility
d570a8
diff -rcp binutils-2.23.52.0.1.orig/binutils/objcopy.c binutils-2.23.52.0.1/binutils/objcopy.c
d570a8
*** binutils-2.23.52.0.1.orig/binutils/objcopy.c	2014-11-11 20:51:37.030244866 +0000
d570a8
--- binutils-2.23.52.0.1/binutils/objcopy.c	2014-11-11 20:55:30.431307076 +0000
d570a8
*************** copy_archive (bfd *ibfd, bfd *obfd, cons
d570a8
*** 2182,2187 ****
d570a8
--- 2182,2197 ----
d570a8
        bfd_boolean del = TRUE;
d570a8
        bfd_boolean ok_object;
d570a8
  
d570a8
+       /* PR binutils/17533: Do not allow directory traversal
d570a8
+ 	 outside of the current directory tree by archive members.  */
d570a8
+       if (! is_valid_archive_path (bfd_get_filename (this_element)))
d570a8
+ 	{
d570a8
+ 	  non_fatal (_("illegal pathname found in archive member: %s"),
d570a8
+ 		     bfd_get_filename (this_element));
d570a8
+ 	  status = 1;
d570a8
+ 	  goto cleanup_and_exit;
d570a8
+ 	}
d570a8
+ 
d570a8
        /* Create an output file for this member.  */
d570a8
        output_name = concat (dir, "/",
d570a8
  			    bfd_get_filename (this_element), (char *) 0);
d570a8
*************** copy_archive (bfd *ibfd, bfd *obfd, cons
d570a8
*** 2191,2198 ****
d570a8
  	{
d570a8
  	  output_name = make_tempdir (output_name);
d570a8
  	  if (output_name == NULL)
d570a8
! 	    fatal (_("cannot create tempdir for archive copying (error: %s)"),
d570a8
! 		   strerror (errno));
d570a8
  
d570a8
  	  l = (struct name_list *) xmalloc (sizeof (struct name_list));
d570a8
  	  l->name = output_name;
d570a8
--- 2201,2212 ----
d570a8
  	{
d570a8
  	  output_name = make_tempdir (output_name);
d570a8
  	  if (output_name == NULL)
d570a8
! 	    {
d570a8
! 	      non_fatal (_("cannot create tempdir for archive copying (error: %s)"),
d570a8
! 			 strerror (errno));
d570a8
! 	      status = 1;
d570a8
! 	      goto cleanup_and_exit;
d570a8
! 	    }
d570a8
  
d570a8
  	  l = (struct name_list *) xmalloc (sizeof (struct name_list));
d570a8
  	  l->name = output_name;
d570a8
*************** copy_archive (bfd *ibfd, bfd *obfd, cons
d570a8
*** 2234,2240 ****
d570a8
  	{
d570a8
  	  bfd_nonfatal_message (output_name, NULL, NULL, NULL);
d570a8
  	  status = 1;
d570a8
! 	  return;
d570a8
  	}
d570a8
  
d570a8
        if (ok_object)
d570a8
--- 2248,2254 ----
d570a8
  	{
d570a8
  	  bfd_nonfatal_message (output_name, NULL, NULL, NULL);
d570a8
  	  status = 1;
d570a8
! 	  goto cleanup_and_exit;
d570a8
  	}
d570a8
  
d570a8
        if (ok_object)
d570a8
*************** copy_archive (bfd *ibfd, bfd *obfd, cons
d570a8
*** 2295,2301 ****
d570a8
      {
d570a8
        status = 1;
d570a8
        bfd_nonfatal_message (filename, NULL, NULL, NULL);
d570a8
-       return;
d570a8
      }
d570a8
  
d570a8
    filename = bfd_get_filename (ibfd);
d570a8
--- 2309,2314 ----
d570a8
*************** copy_archive (bfd *ibfd, bfd *obfd, cons
d570a8
*** 2303,2311 ****
d570a8
      {
d570a8
        status = 1;
d570a8
        bfd_nonfatal_message (filename, NULL, NULL, NULL);
d570a8
-       return;
d570a8
      }
d570a8
  
d570a8
    /* Delete all the files that we opened.  */
d570a8
    for (l = list; l != NULL; l = l->next)
d570a8
      {
d570a8
--- 2316,2324 ----
d570a8
      {
d570a8
        status = 1;
d570a8
        bfd_nonfatal_message (filename, NULL, NULL, NULL);
d570a8
      }
d570a8
  
d570a8
+  cleanup_and_exit:
d570a8
    /* Delete all the files that we opened.  */
d570a8
    for (l = list; l != NULL; l = l->next)
d570a8
      {