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) |
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) 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 000000000..51a233493 --- /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 |