aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2011-08-18 14:29:41 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2011-08-18 14:29:41 +0200
commit251fc70e9722f931eec23a34030d05ba5f747b0e (patch)
treef35f23afd72b5d527f6c011745981c9bdd9ec3a6
parentb1611d9a4693f1dc8296ef44f7e0f6044032ce15 (diff)
downloadbusybox-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.c13
-rwxr-xr-xtestsuite/uncompress.tests20
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
9testing "uncompress < \x1f\x9d\x90 \x01 x N" \
10'uncompress 2>&1 1>/dev/null; echo $?' \
11"\
12uncompress: corrupted data
131
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
20exit $FAILCOUNT