diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2011-08-18 14:29:41 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2011-08-18 14:29:41 +0200 |
commit | 251fc70e9722f931eec23a34030d05ba5f747b0e (patch) | |
tree | f35f23afd72b5d527f6c011745981c9bdd9ec3a6 | |
parent | b1611d9a4693f1dc8296ef44f7e0f6044032ce15 (diff) | |
download | busybox-w32-251fc70e9722f931eec23a34030d05ba5f747b0e.tar.gz busybox-w32-251fc70e9722f931eec23a34030d05ba5f747b0e.tar.bz2 busybox-w32-251fc70e9722f931eec23a34030d05ba5f747b0e.zip |
uncompress: fix buffer underrun by corrupted input
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | archival/libarchive/decompress_uncompress.c | 13 | ||||
-rwxr-xr-x | testsuite/uncompress.tests | 20 |
2 files changed, 28 insertions, 5 deletions
diff --git a/archival/libarchive/decompress_uncompress.c b/archival/libarchive/decompress_uncompress.c index 44d894244..329894be1 100644 --- a/archival/libarchive/decompress_uncompress.c +++ b/archival/libarchive/decompress_uncompress.c | |||
@@ -163,7 +163,8 @@ unpack_Z_stream(int fd_in, int fd_out) | |||
163 | 163 | ||
164 | if (insize < (int) (IBUFSIZ + 64) - IBUFSIZ) { | 164 | if (insize < (int) (IBUFSIZ + 64) - IBUFSIZ) { |
165 | rsize = safe_read(fd_in, inbuf + insize, IBUFSIZ); | 165 | rsize = safe_read(fd_in, inbuf + insize, IBUFSIZ); |
166 | //error check?? | 166 | if (rsize < 0) |
167 | bb_error_msg(bb_msg_read_error); | ||
167 | insize += rsize; | 168 | insize += rsize; |
168 | } | 169 | } |
169 | 170 | ||
@@ -195,6 +196,8 @@ unpack_Z_stream(int fd_in, int fd_out) | |||
195 | 196 | ||
196 | 197 | ||
197 | if (oldcode == -1) { | 198 | if (oldcode == -1) { |
199 | if (code >= 256) | ||
200 | bb_error_msg_and_die("corrupted data"); /* %ld", code); */ | ||
198 | oldcode = code; | 201 | oldcode = code; |
199 | finchar = (int) oldcode; | 202 | finchar = (int) oldcode; |
200 | outbuf[outpos++] = (unsigned char) finchar; | 203 | outbuf[outpos++] = (unsigned char) finchar; |
@@ -239,6 +242,8 @@ unpack_Z_stream(int fd_in, int fd_out) | |||
239 | 242 | ||
240 | /* Generate output characters in reverse order */ | 243 | /* Generate output characters in reverse order */ |
241 | while ((long) code >= (long) 256) { | 244 | while ((long) code >= (long) 256) { |
245 | if (stackp <= &htabof(0)) | ||
246 | bb_error_msg_and_die("corrupted data"); | ||
242 | *--stackp = tab_suffixof(code); | 247 | *--stackp = tab_suffixof(code); |
243 | code = tab_prefixof(code); | 248 | code = tab_prefixof(code); |
244 | } | 249 | } |
@@ -263,8 +268,7 @@ unpack_Z_stream(int fd_in, int fd_out) | |||
263 | } | 268 | } |
264 | 269 | ||
265 | if (outpos >= OBUFSIZ) { | 270 | if (outpos >= OBUFSIZ) { |
266 | full_write(fd_out, outbuf, outpos); | 271 | xwrite(fd_out, outbuf, outpos); |
267 | //error check?? | ||
268 | IF_DESKTOP(total_written += outpos;) | 272 | IF_DESKTOP(total_written += outpos;) |
269 | outpos = 0; | 273 | outpos = 0; |
270 | } | 274 | } |
@@ -292,8 +296,7 @@ unpack_Z_stream(int fd_in, int fd_out) | |||
292 | } while (rsize > 0); | 296 | } while (rsize > 0); |
293 | 297 | ||
294 | if (outpos > 0) { | 298 | if (outpos > 0) { |
295 | full_write(fd_out, outbuf, outpos); | 299 | xwrite(fd_out, outbuf, outpos); |
296 | //error check?? | ||
297 | IF_DESKTOP(total_written += outpos;) | 300 | IF_DESKTOP(total_written += outpos;) |
298 | } | 301 | } |
299 | 302 | ||
diff --git a/testsuite/uncompress.tests b/testsuite/uncompress.tests new file mode 100755 index 000000000..51a233493 --- /dev/null +++ b/testsuite/uncompress.tests | |||
@@ -0,0 +1,20 @@ | |||
1 | #!/bin/sh | ||
2 | # Copyright 2011 by Denys Vlasenko | ||
3 | # Licensed under GPLv2, see file LICENSE in this source tree. | ||
4 | |||
5 | . ./testing.sh | ||
6 | |||
7 | # testing "test name" "commands" "expected result" "file input" "stdin" | ||
8 | |||
9 | testing "uncompress < \x1f\x9d\x90 \x01 x N" \ | ||
10 | 'uncompress 2>&1 1>/dev/null; echo $?' \ | ||
11 | "\ | ||
12 | uncompress: corrupted data | ||
13 | 1 | ||
14 | " \ | ||
15 | "" "\ | ||
16 | \x1f\x9d\x90\ | ||
17 | \01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\ | ||
18 | " | ||
19 | |||
20 | exit $FAILCOUNT | ||