1 |
jpp |
1.1 |
diff -up libarchive-2.8.3/libarchive/archive_read_support_format_tar.c.CVE-2011-1778 libarchive-2.8.3/libarchive/archive_read_support_format_tar.c |
2 |
|
|
--- libarchive-2.8.3/libarchive/archive_read_support_format_tar.c.CVE-2011-1778 2010-01-17 01:21:10.000000000 +0100 |
3 |
|
|
+++ libarchive-2.8.3/libarchive/archive_read_support_format_tar.c 2011-10-03 13:07:42.000000000 +0200 |
4 |
|
|
@@ -175,14 +175,15 @@ struct tar { |
5 |
|
|
static ssize_t UTF8_mbrtowc(wchar_t *pwc, const char *s, size_t n); |
6 |
|
|
static int archive_block_is_null(const unsigned char *p); |
7 |
|
|
static char *base64_decode(const char *, size_t, size_t *); |
8 |
|
|
-static void gnu_add_sparse_entry(struct tar *, |
9 |
|
|
+static int gnu_add_sparse_entry(struct archive_read *, struct tar *, |
10 |
|
|
off_t offset, off_t remaining); |
11 |
|
|
static void gnu_clear_sparse_list(struct tar *); |
12 |
|
|
static int gnu_sparse_old_read(struct archive_read *, struct tar *, |
13 |
|
|
const struct archive_entry_header_gnutar *header); |
14 |
|
|
-static void gnu_sparse_old_parse(struct tar *, |
15 |
|
|
+static int gnu_sparse_old_parse(struct archive_read *a, struct tar *, |
16 |
|
|
const struct gnu_sparse *sparse, int length); |
17 |
|
|
-static int gnu_sparse_01_parse(struct tar *, const char *); |
18 |
|
|
+static int gnu_sparse_01_parse(struct archive_read *, struct tar *, |
19 |
|
|
+ const char *); |
20 |
|
|
static ssize_t gnu_sparse_10_read(struct archive_read *, struct tar *); |
21 |
|
|
static int header_Solaris_ACL(struct archive_read *, struct tar *, |
22 |
|
|
struct archive_entry *, const void *); |
23 |
|
|
@@ -212,8 +213,8 @@ static int archive_read_format_tar_skip( |
24 |
|
|
static int archive_read_format_tar_read_header(struct archive_read *, |
25 |
|
|
struct archive_entry *); |
26 |
|
|
static int checksum(struct archive_read *, const void *); |
27 |
|
|
-static int pax_attribute(struct tar *, struct archive_entry *, |
28 |
|
|
- char *key, char *value); |
29 |
|
|
+static int pax_attribute(struct archive_read *, struct tar *, |
30 |
|
|
+ struct archive_entry *, char *key, char *value); |
31 |
|
|
static int pax_header(struct archive_read *, struct tar *, |
32 |
|
|
struct archive_entry *, char *attr); |
33 |
|
|
static void pax_time(const char *, int64_t *sec, long *nanos); |
34 |
|
|
@@ -419,7 +420,9 @@ archive_read_format_tar_read_header(stru |
35 |
|
|
* a single block. |
36 |
|
|
*/ |
37 |
|
|
if (tar->sparse_list == NULL) |
38 |
|
|
- gnu_add_sparse_entry(tar, 0, tar->entry_bytes_remaining); |
39 |
|
|
+ if (gnu_add_sparse_entry(a, tar, 0, tar->entry_bytes_remaining) |
40 |
|
|
+ != ARCHIVE_OK) |
41 |
|
|
+ return (ARCHIVE_FATAL); |
42 |
|
|
|
43 |
|
|
if (r == ARCHIVE_OK) { |
44 |
|
|
/* |
45 |
|
|
@@ -1269,7 +1272,7 @@ pax_header(struct archive_read *a, struc |
46 |
|
|
value = p + 1; |
47 |
|
|
|
48 |
|
|
/* Identify this attribute and set it in the entry. */ |
49 |
|
|
- err2 = pax_attribute(tar, entry, key, value); |
50 |
|
|
+ err2 = pax_attribute(a, tar, entry, key, value); |
51 |
|
|
err = err_combine(err, err2); |
52 |
|
|
|
53 |
|
|
/* Skip to next line */ |
54 |
|
|
@@ -1395,8 +1398,8 @@ pax_attribute_xattr(struct archive_entry |
55 |
|
|
* any of them look useful. |
56 |
|
|
*/ |
57 |
|
|
static int |
58 |
|
|
-pax_attribute(struct tar *tar, struct archive_entry *entry, |
59 |
|
|
- char *key, char *value) |
60 |
|
|
+pax_attribute(struct archive_read *a, struct tar *tar, |
61 |
|
|
+ struct archive_entry *entry, char *key, char *value) |
62 |
|
|
{ |
63 |
|
|
int64_t s; |
64 |
|
|
long n; |
65 |
|
|
@@ -1414,8 +1417,10 @@ pax_attribute(struct tar *tar, struct ar |
66 |
|
|
if (strcmp(key, "GNU.sparse.offset") == 0) { |
67 |
|
|
tar->sparse_offset = tar_atol10(value, strlen(value)); |
68 |
|
|
if (tar->sparse_numbytes != -1) { |
69 |
|
|
- gnu_add_sparse_entry(tar, |
70 |
|
|
- tar->sparse_offset, tar->sparse_numbytes); |
71 |
|
|
+ if (gnu_add_sparse_entry(a, tar, |
72 |
|
|
+ tar->sparse_offset, tar->sparse_numbytes) |
73 |
|
|
+ != ARCHIVE_OK) |
74 |
|
|
+ return(ARCHIVE_FATAL); |
75 |
|
|
tar->sparse_offset = -1; |
76 |
|
|
tar->sparse_numbytes = -1; |
77 |
|
|
} |
78 |
|
|
@@ -1423,8 +1428,10 @@ pax_attribute(struct tar *tar, struct ar |
79 |
|
|
if (strcmp(key, "GNU.sparse.numbytes") == 0) { |
80 |
|
|
tar->sparse_numbytes = tar_atol10(value, strlen(value)); |
81 |
|
|
if (tar->sparse_numbytes != -1) { |
82 |
|
|
- gnu_add_sparse_entry(tar, |
83 |
|
|
- tar->sparse_offset, tar->sparse_numbytes); |
84 |
|
|
+ if (gnu_add_sparse_entry(a, tar, |
85 |
|
|
+ tar->sparse_offset, tar->sparse_numbytes) |
86 |
|
|
+ != ARCHIVE_OK) |
87 |
|
|
+ return (ARCHIVE_FATAL); |
88 |
|
|
tar->sparse_offset = -1; |
89 |
|
|
tar->sparse_numbytes = -1; |
90 |
|
|
} |
91 |
|
|
@@ -1438,7 +1445,7 @@ pax_attribute(struct tar *tar, struct ar |
92 |
|
|
if (strcmp(key, "GNU.sparse.map") == 0) { |
93 |
|
|
tar->sparse_gnu_major = 0; |
94 |
|
|
tar->sparse_gnu_minor = 1; |
95 |
|
|
- if (gnu_sparse_01_parse(tar, value) != ARCHIVE_OK) |
96 |
|
|
+ if (gnu_sparse_01_parse(a, tar, value) != ARCHIVE_OK) |
97 |
|
|
return (ARCHIVE_WARN); |
98 |
|
|
} |
99 |
|
|
|
100 |
|
|
@@ -1716,7 +1723,8 @@ header_gnutar(struct archive_read *a, st |
101 |
|
|
} |
102 |
|
|
|
103 |
|
|
if (header->sparse[0].offset[0] != 0) { |
104 |
|
|
- gnu_sparse_old_read(a, tar, header); |
105 |
|
|
+ if (gnu_sparse_old_read(a, tar, header) != ARCHIVE_OK) |
106 |
|
|
+ return (ARCHIVE_FATAL); |
107 |
|
|
} else { |
108 |
|
|
if (header->isextended[0] != 0) { |
109 |
|
|
/* XXX WTF? XXX */ |
110 |
|
|
@@ -1726,14 +1734,17 @@ header_gnutar(struct archive_read *a, st |
111 |
|
|
return (0); |
112 |
|
|
} |
113 |
|
|
|
114 |
|
|
-static void |
115 |
|
|
-gnu_add_sparse_entry(struct tar *tar, off_t offset, off_t remaining) |
116 |
|
|
+static int |
117 |
|
|
+gnu_add_sparse_entry(struct archive_read *a, struct tar *tar, off_t offset, |
118 |
|
|
+ off_t remaining) |
119 |
|
|
{ |
120 |
|
|
struct sparse_block *p; |
121 |
|
|
|
122 |
|
|
p = (struct sparse_block *)malloc(sizeof(*p)); |
123 |
|
|
- if (p == NULL) |
124 |
|
|
- __archive_errx(1, "Out of memory"); |
125 |
|
|
+ if (p == NULL) { |
126 |
|
|
+ archive_set_error(&a->archive, ENOMEM, "Out of memory"); |
127 |
|
|
+ return (ARCHIVE_FATAL); |
128 |
|
|
+ } |
129 |
|
|
memset(p, 0, sizeof(*p)); |
130 |
|
|
if (tar->sparse_last != NULL) |
131 |
|
|
tar->sparse_last->next = p; |
132 |
|
|
@@ -1742,6 +1753,7 @@ gnu_add_sparse_entry(struct tar *tar, of |
133 |
|
|
tar->sparse_last = p; |
134 |
|
|
p->offset = offset; |
135 |
|
|
p->remaining = remaining; |
136 |
|
|
+ return (ARCHIVE_OK); |
137 |
|
|
} |
138 |
|
|
|
139 |
|
|
static void |
140 |
|
|
@@ -1782,7 +1794,8 @@ gnu_sparse_old_read(struct archive_read |
141 |
|
|
}; |
142 |
|
|
const struct extended *ext; |
143 |
|
|
|
144 |
|
|
- gnu_sparse_old_parse(tar, header->sparse, 4); |
145 |
|
|
+ if (gnu_sparse_old_parse(a, tar, header->sparse, 4) != ARCHIVE_OK) |
146 |
|
|
+ return (ARCHIVE_FATAL); |
147 |
|
|
if (header->isextended[0] == 0) |
148 |
|
|
return (ARCHIVE_OK); |
149 |
|
|
|
150 |
|
|
@@ -1798,24 +1811,28 @@ gnu_sparse_old_read(struct archive_read |
151 |
|
|
} |
152 |
|
|
__archive_read_consume(a, 512); |
153 |
|
|
ext = (const struct extended *)data; |
154 |
|
|
- gnu_sparse_old_parse(tar, ext->sparse, 21); |
155 |
|
|
+ if (gnu_sparse_old_parse(a, tar, ext->sparse, 21) != ARCHIVE_OK) |
156 |
|
|
+ return (ARCHIVE_FATAL); |
157 |
|
|
} while (ext->isextended[0] != 0); |
158 |
|
|
if (tar->sparse_list != NULL) |
159 |
|
|
tar->entry_offset = tar->sparse_list->offset; |
160 |
|
|
return (ARCHIVE_OK); |
161 |
|
|
} |
162 |
|
|
|
163 |
|
|
-static void |
164 |
|
|
-gnu_sparse_old_parse(struct tar *tar, |
165 |
|
|
+static int |
166 |
|
|
+gnu_sparse_old_parse(struct archive_read *a, struct tar *tar, |
167 |
|
|
const struct gnu_sparse *sparse, int length) |
168 |
|
|
{ |
169 |
|
|
while (length > 0 && sparse->offset[0] != 0) { |
170 |
|
|
- gnu_add_sparse_entry(tar, |
171 |
|
|
+ if (gnu_add_sparse_entry(a, tar, |
172 |
|
|
tar_atol(sparse->offset, sizeof(sparse->offset)), |
173 |
|
|
- tar_atol(sparse->numbytes, sizeof(sparse->numbytes))); |
174 |
|
|
+ tar_atol(sparse->numbytes, sizeof(sparse->numbytes))) |
175 |
|
|
+ != ARCHIVE_OK) |
176 |
|
|
+ return (ARCHIVE_FATAL); |
177 |
|
|
sparse++; |
178 |
|
|
length--; |
179 |
|
|
} |
180 |
|
|
+ return (ARCHIVE_OK); |
181 |
|
|
} |
182 |
|
|
|
183 |
|
|
/* |
184 |
|
|
@@ -1845,7 +1862,7 @@ gnu_sparse_old_parse(struct tar *tar, |
185 |
|
|
*/ |
186 |
|
|
|
187 |
|
|
static int |
188 |
|
|
-gnu_sparse_01_parse(struct tar *tar, const char *p) |
189 |
|
|
+gnu_sparse_01_parse(struct archive_read *a, struct tar *tar, const char *p) |
190 |
|
|
{ |
191 |
|
|
const char *e; |
192 |
|
|
off_t offset = -1, size = -1; |
193 |
|
|
@@ -1865,7 +1882,9 @@ gnu_sparse_01_parse(struct tar *tar, con |
194 |
|
|
size = tar_atol10(p, e - p); |
195 |
|
|
if (size < 0) |
196 |
|
|
return (ARCHIVE_WARN); |
197 |
|
|
- gnu_add_sparse_entry(tar, offset, size); |
198 |
|
|
+ if (gnu_add_sparse_entry(a, tar, offset, size) |
199 |
|
|
+ != ARCHIVE_OK) |
200 |
|
|
+ return (ARCHIVE_FATAL); |
201 |
|
|
offset = -1; |
202 |
|
|
} |
203 |
|
|
if (*e == '\0') |
204 |
|
|
@@ -1969,7 +1988,8 @@ gnu_sparse_10_read(struct archive_read * |
205 |
|
|
if (size < 0) |
206 |
|
|
return (ARCHIVE_FATAL); |
207 |
|
|
/* Add a new sparse entry. */ |
208 |
|
|
- gnu_add_sparse_entry(tar, offset, size); |
209 |
|
|
+ if (gnu_add_sparse_entry(a, tar, offset, size) != ARCHIVE_OK) |
210 |
|
|
+ return (ARCHIVE_FATAL); |
211 |
|
|
} |
212 |
|
|
/* Skip rest of block... */ |
213 |
|
|
bytes_read = tar->entry_bytes_remaining - remaining; |