unlzma: fix segfault on bad archive
authorDenys Vlasenko <vda.linux@googlemail.com>
Sun, 8 Apr 2018 18:45:16 +0000 (20:45 +0200)
committerDenys Vlasenko <vda.linux@googlemail.com>
Sun, 8 Apr 2018 18:45:16 +0000 (20:45 +0200)
function                                             old     new   delta
unpack_lzma_stream                                  2647    2653      +6

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
archival/libarchive/decompress_unlzma.c
testsuite/unlzma.tests [new file with mode: 0755]
testsuite/unlzma_issue_1.lzma [new file with mode: 0644]
testsuite/unlzma_issue_2.lzma [new file with mode: 0644]

index be43424144355978af29d610c297350637ffafc0..80a453806cf2529c4f204d0326b87ebb3974276f 100644 (file)
 #include "libbb.h"
 #include "bb_archive.h"
 
+#if 0
+# define dbg(...) bb_error_msg(__VA_ARGS__)
+#else
+# define dbg(...) ((void)0)
+#endif
+
+
 #if ENABLE_FEATURE_LZMA_FAST
 #  define speed_inline ALWAYS_INLINE
 #  define size_inline
@@ -417,6 +424,10 @@ unpack_lzma_stream(transformer_state_t *xstate)
                                                for (; num_bits2 != LZMA_NUM_ALIGN_BITS; num_bits2--)
                                                        rep0 = (rep0 << 1) | rc_direct_bit(rc);
                                                rep0 <<= LZMA_NUM_ALIGN_BITS;
+                                               if ((int32_t)rep0 < 0) {
+                                                       dbg("%d rep0:%d", __LINE__, rep0);
+                                                       goto bad;
+                                               }
                                                prob3 = p + LZMA_ALIGN;
                                        }
                                        i2 = 1;
diff --git a/testsuite/unlzma.tests b/testsuite/unlzma.tests
new file mode 100755 (executable)
index 0000000..0e98afe
--- /dev/null
@@ -0,0 +1,21 @@
+#!/bin/sh
+
+. ./testing.sh
+
+# testing "test name" "commands" "expected result" "file input" "stdin"
+#   file input will be file called "input"
+#   test can create a file "actual" instead of writing to stdout
+
+# Damaged encrypted streams
+testing "unlzma (bad archive 1)" \
+       "unlzma <unlzma_issue_1.lzma >/dev/null; echo \$?" \
+"1
+" "" ""
+
+# Damaged encrypted streams
+testing "unlzma (bad archive 2)" \
+       "unlzma <unlzma_issue_2.lzma >/dev/null; echo \$?" \
+"1
+" "" ""
+
+exit $FAILCOUNT
diff --git a/testsuite/unlzma_issue_1.lzma b/testsuite/unlzma_issue_1.lzma
new file mode 100644 (file)
index 0000000..fb70104
Binary files /dev/null and b/testsuite/unlzma_issue_1.lzma differ
diff --git a/testsuite/unlzma_issue_2.lzma b/testsuite/unlzma_issue_2.lzma
new file mode 100644 (file)
index 0000000..853f0fc
Binary files /dev/null and b/testsuite/unlzma_issue_2.lzma differ