aboutsummaryrefslogtreecommitdiffstats
path: root/meta/recipes-devtools/binutils/binutils/binutils_CVE-2014-8737.patch
blob: 4a84562201d8836427f9e59c53e39b57057d92f1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
Upstream-Status: Backport

CVE-2014-8737 fix.

[YOCTO #7084]

Signed-off-by: Armin Kuster <akuster808@gmail.com>

From dd9b91de2149ee81d47f708e7b0bbf57da10ad42 Mon Sep 17 00:00:00 2001
From: Nick Clifton <nickc@redhat.com>
Date: Thu, 6 Nov 2014 14:49:10 +0000
Subject: [PATCH] Prevent archive memebers with illegal pathnames from being
 extracted from an archive.

	PR binutils/17552, binutils/17533
	* bucomm.c (is_valid_archive_path): New function.  Returns false
	for absolute pathnames and pathnames that include /../.
	* bucomm.h (is_valid_archive_path): Add prototype.
	* ar.c (extract_file): Use new function to check for valid
	pathnames when extracting files from an archive.
	* objcopy.c (copy_archive): Likewise.
	* doc/binutils.texi: Update documentation to mention the
	limitation on pathname of archive members.
---
 binutils/ChangeLog         | 16 ++++++++++++++--
 binutils/ar.c              |  9 +++++++++
 binutils/bucomm.c          | 26 ++++++++++++++++++++++++++
 binutils/bucomm.h          | 12 ++++++++----
 binutils/doc/binutils.texi |  3 ++-
 binutils/objcopy.c         |  6 ++++++
 6 files changed, 65 insertions(+), 7 deletions(-)

Index: binutils-2.24/binutils/ar.c
===================================================================
--- binutils-2.24.orig/binutils/ar.c
+++ binutils-2.24/binutils/ar.c
@@ -1031,6 +1031,15 @@ extract_file (bfd *abfd)
   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));
Index: binutils-2.24/binutils/bucomm.c
===================================================================
--- binutils-2.24.orig/binutils/bucomm.c
+++ binutils-2.24/binutils/bucomm.c
@@ -624,3 +624,29 @@ bfd_get_archive_filename (const bfd *abf
 	   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;
+}
Index: binutils-2.24/binutils/bucomm.h
===================================================================
--- binutils-2.24.orig/binutils/bucomm.h
+++ binutils-2.24/binutils/bucomm.h
@@ -23,6 +23,8 @@
 #ifndef _BUCOMM_H
 #define _BUCOMM_H
 
+/* In bucomm.c.  */
+
 /* Return the filename in a static buffer.  */
 const char *bfd_get_archive_filename (const bfd *);
 
@@ -58,20 +60,22 @@ bfd_vma parse_vma (const char *, const c
 
 off_t get_file_size (const char *);
 
+bfd_boolean is_valid_archive_path (char const *);
+
 extern char *program_name;
 
-/* filemode.c */
+/* In filemode.c.  */
 void mode_string (unsigned long, char *);
 
-/* version.c */
+/* In version.c.  */
 extern void print_version (const char *);
 
-/* rename.c */
+/* In rename.c.  */
 extern void set_times (const char *, const struct stat *);
 
 extern int smart_rename (const char *, const char *, int);
 
-/* libiberty.  */
+/* In libiberty.  */
 void *xmalloc (size_t);
 
 void *xrealloc (void *, size_t);
Index: binutils-2.24/binutils/doc/binutils.texi
===================================================================
--- binutils-2.24.orig/binutils/doc/binutils.texi
+++ binutils-2.24/binutils/doc/binutils.texi
@@ -234,7 +234,8 @@ a normal archive.  Instead the elements
 individually to the second archive.
 
 The paths to the elements of the archive are stored relative to the
-archive itself.
+archive itself.  For security reasons absolute paths and paths with a
+@code{/../} component are not allowed.
 
 @cindex compatibility, @command{ar}
 @cindex @command{ar} compatibility
Index: binutils-2.24/binutils/objcopy.c
===================================================================
--- binutils-2.24.orig/binutils/objcopy.c
+++ binutils-2.24/binutils/objcopy.c
@@ -2206,6 +2206,12 @@ copy_archive (bfd *ibfd, bfd *obfd, cons
       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)))
+	fatal (_("illegal pathname found in archive member: %s"),
+	       bfd_get_filename (this_element));
+
       /* Create an output file for this member.  */
       output_name = concat (dir, "/",
 			    bfd_get_filename (this_element), (char *) 0);
Index: binutils-2.24/binutils/ChangeLog
===================================================================
--- binutils-2.24.orig/binutils/ChangeLog
+++ binutils-2.24/binutils/ChangeLog
@@ -1,3 +1,15 @@
+2014-11-06  Nick Clifton  <nickc@redhat.com>
+
+       PR binutils/17552, binutils/17533
+       * bucomm.c (is_valid_archive_path): New function.  Returns false
+       for absolute pathnames and pathnames that include /../.
+       * bucomm.h (is_valid_archive_path): Add prototype.
+       * ar.c (extract_file): Use new function to check for valid
+       pathnames when extracting files from an archive.
+       * objcopy.c (copy_archive): Likewise.
+       * doc/binutils.texi: Update documentation to mention the
+       limitation on pathname of archive members.
+
 2013-11-22  Cory Fields  <cory@coryfields.com>
 
 	* windres.c (define_resource): Use zero for timestamp, making