summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2011-08-18 12:29:41 (GMT)
committer Denys Vlasenko <vda.linux@googlemail.com>2011-08-18 12:29:41 (GMT)
commit251fc70e9722f931eec23a34030d05ba5f747b0e (patch)
treef35f23afd72b5d527f6c011745981c9bdd9ec3a6
parentb1611d9a4693f1dc8296ef44f7e0f6044032ce15 (diff)
downloadbusybox-251fc70e9722f931eec23a34030d05ba5f747b0e.tar.gz
busybox-251fc70e9722f931eec23a34030d05ba5f747b0e.tar.bz2
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 44d8942..329894b 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)
if (insize < (int) (IBUFSIZ + 64) - IBUFSIZ) {
rsize = safe_read(fd_in, inbuf + insize, IBUFSIZ);
-//error check??
+ if (rsize < 0)
+ bb_error_msg(bb_msg_read_error);
insize += rsize;
}
@@ -195,6 +196,8 @@ unpack_Z_stream(int fd_in, int fd_out)
if (oldcode == -1) {
+ if (code >= 256)
+ bb_error_msg_and_die("corrupted data"); /* %ld", code); */
oldcode = code;
finchar = (int) oldcode;
outbuf[outpos++] = (unsigned char) finchar;
@@ -239,6 +242,8 @@ unpack_Z_stream(int fd_in, int fd_out)
/* Generate output characters in reverse order */
while ((long) code >= (long) 256) {
+ if (stackp <= &htabof(0))
+ bb_error_msg_and_die("corrupted data");
*--stackp = tab_suffixof(code);
code = tab_prefixof(code);
}
@@ -263,8 +268,7 @@ unpack_Z_stream(int fd_in, int fd_out)
}
if (outpos >= OBUFSIZ) {
- full_write(fd_out, outbuf, outpos);
-//error check??
+ xwrite(fd_out, outbuf, outpos);
IF_DESKTOP(total_written += outpos;)
outpos = 0;
}
@@ -292,8 +296,7 @@ unpack_Z_stream(int fd_in, int fd_out)
} while (rsize > 0);
if (outpos > 0) {
- full_write(fd_out, outbuf, outpos);
-//error check??
+ xwrite(fd_out, outbuf, outpos);
IF_DESKTOP(total_written += outpos;)
}
diff --git a/testsuite/uncompress.tests b/testsuite/uncompress.tests
new file mode 100755
index 0000000..51a2334
--- /dev/null
+++ b/testsuite/uncompress.tests
@@ -0,0 +1,20 @@
+#!/bin/sh
+# Copyright 2011 by Denys Vlasenko
+# Licensed under GPLv2, see file LICENSE in this source tree.
+
+. ./testing.sh
+
+# testing "test name" "commands" "expected result" "file input" "stdin"
+
+testing "uncompress < \x1f\x9d\x90 \x01 x N" \
+'uncompress 2>&1 1>/dev/null; echo $?' \
+"\
+uncompress: corrupted data
+1
+" \
+"" "\
+\x1f\x9d\x90\
+\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\
+"
+
+exit $FAILCOUNT