unlzma: fix another SEGV case
authorDenys Vlasenko <vda.linux@googlemail.com>
Thu, 19 Apr 2018 17:29:49 +0000 (19:29 +0200)
committerDenys Vlasenko <vda.linux@googlemail.com>
Thu, 19 Apr 2018 17:30:51 +0000 (19:30 +0200)
function                                             old     new   delta
unpack_lzma_stream                                  1705    1717     +12

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
archival/libarchive/decompress_unlzma.c
testsuite/unzip.tests
testsuite/unzip_bad_lzma_1.zip [new file with mode: 0644]

index 80a453806cf2529c4f204d0326b87ebb3974276f..42efd5aa7f0a20108af183012954a6e03df9f3ca 100644 (file)
@@ -224,6 +224,7 @@ unpack_lzma_stream(transformer_state_t *xstate)
        rc_t *rc;
        int i;
        uint8_t *buffer;
+       uint32_t buffer_size;
        uint8_t previous_byte = 0;
        size_t buffer_pos = 0, global_pos = 0;
        int len = 0;
@@ -253,7 +254,8 @@ unpack_lzma_stream(transformer_state_t *xstate)
        if (header.dict_size == 0)
                header.dict_size++;
 
-       buffer = xmalloc(MIN(header.dst_size, header.dict_size));
+       buffer_size = MIN(header.dst_size, header.dict_size);
+       buffer = xmalloc(buffer_size);
 
        {
                int num_probs;
@@ -464,7 +466,10 @@ unpack_lzma_stream(transformer_state_t *xstate)
                                if ((int32_t)pos < 0) {
                                        pos += header.dict_size;
                                        /* bug 10436 has an example file where this triggers: */
-                                       if ((int32_t)pos < 0)
+                                       //if ((int32_t)pos < 0)
+                                       //      goto bad;
+                                       /* more stringent test (see unzip_bad_lzma_1.zip): */
+                                       if (pos >= buffer_size)
                                                goto bad;
                                }
                                previous_byte = buffer[pos];
index 2e4becdb88ccf658945fc5f7ee7343ec0a8196cb..6bcb6b3a234383babaa5c29da0a36a493f01040f 100755 (executable)
@@ -14,7 +14,7 @@
 # Create a scratch directory
 
 mkdir temp
-cd temp
+cd temp || exit 90
 
 # Create test file to work with.
 
@@ -52,7 +52,18 @@ NzITNFBLBQUKAC4JAA04Cw0EOhZQSwUGAQAABAIAAgCZAAAAeQAAAAIALhM=
 "
 SKIP=
 
-rm *
+rm -f *
+
+optional CONFIG_FEATURE_UNZIP_LZMA
+testing "unzip (archive with corrupted lzma)" "unzip -p ../unzip_bad_lzma_1.zip 2>&1; echo \$?" \
+"unzip: removing leading '/' from member names
+unzip: inflate error
+1
+" \
+"" ""
+SKIP=
+
+rm -f *
 
 # Clean up scratch directory.
 
diff --git a/testsuite/unzip_bad_lzma_1.zip b/testsuite/unzip_bad_lzma_1.zip
new file mode 100644 (file)
index 0000000..1335c96
Binary files /dev/null and b/testsuite/unzip_bad_lzma_1.zip differ