diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2021-06-15 15:07:57 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2021-06-15 15:14:00 +0200 |
commit | 04f052c56ded5ab6a904e3a264a73dc0412b2e78 (patch) | |
tree | 607ac1970ec5f880b317f2937f9f664e52d65c44 | |
parent | 4d4fc5ca5ee4faae5dc4237f801d9527a3fb20cc (diff) | |
download | busybox-w32-04f052c56ded5ab6a904e3a264a73dc0412b2e78.tar.gz busybox-w32-04f052c56ded5ab6a904e3a264a73dc0412b2e78.tar.bz2 busybox-w32-04f052c56ded5ab6a904e3a264a73dc0412b2e78.zip |
unlzma: fix a case where we could read before beginning of buffer
Testcase:
21 01 01 00 00 00 00 00 e7 01 01 01 ef 00 df b6
00 17 02 10 11 0f ff 00 16 00 00
Unfortunately, the bug is not reliably causing a segfault,
the behavior depends on what's in memory before the buffer.
function old new delta
unpack_lzma_stream 2762 2768 +6
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | archival/libarchive/decompress_unlzma.c | 5 | ||||
-rwxr-xr-x | testsuite/unlzma.tests | 17 | ||||
-rw-r--r-- | testsuite/unlzma_issue_3.lzma | bin | 0 -> 27 bytes |
3 files changed, 17 insertions, 5 deletions
diff --git a/archival/libarchive/decompress_unlzma.c b/archival/libarchive/decompress_unlzma.c index 0744f231a..fb5aac8fe 100644 --- a/archival/libarchive/decompress_unlzma.c +++ b/archival/libarchive/decompress_unlzma.c | |||
@@ -290,8 +290,11 @@ unpack_lzma_stream(transformer_state_t *xstate) | |||
290 | uint32_t pos; | 290 | uint32_t pos; |
291 | 291 | ||
292 | pos = buffer_pos - rep0; | 292 | pos = buffer_pos - rep0; |
293 | if ((int32_t)pos < 0) | 293 | if ((int32_t)pos < 0) { |
294 | pos += header.dict_size; | 294 | pos += header.dict_size; |
295 | if ((int32_t)pos < 0) | ||
296 | goto bad; | ||
297 | } | ||
295 | match_byte = buffer[pos]; | 298 | match_byte = buffer[pos]; |
296 | do { | 299 | do { |
297 | int bit; | 300 | int bit; |
diff --git a/testsuite/unlzma.tests b/testsuite/unlzma.tests index 0e98afe09..fcc6e9441 100755 --- a/testsuite/unlzma.tests +++ b/testsuite/unlzma.tests | |||
@@ -8,14 +8,23 @@ | |||
8 | 8 | ||
9 | # Damaged encrypted streams | 9 | # Damaged encrypted streams |
10 | testing "unlzma (bad archive 1)" \ | 10 | testing "unlzma (bad archive 1)" \ |
11 | "unlzma <unlzma_issue_1.lzma >/dev/null; echo \$?" \ | 11 | "unlzma <unlzma_issue_1.lzma 2>&1 >/dev/null; echo \$?" \ |
12 | "1 | 12 | "unlzma: corrupted data |
13 | 1 | ||
13 | " "" "" | 14 | " "" "" |
14 | 15 | ||
15 | # Damaged encrypted streams | 16 | # Damaged encrypted streams |
16 | testing "unlzma (bad archive 2)" \ | 17 | testing "unlzma (bad archive 2)" \ |
17 | "unlzma <unlzma_issue_2.lzma >/dev/null; echo \$?" \ | 18 | "unlzma <unlzma_issue_2.lzma 2>&1 >/dev/null; echo \$?" \ |
18 | "1 | 19 | "unlzma: corrupted data |
20 | 1 | ||
21 | " "" "" | ||
22 | |||
23 | # Damaged encrypted streams | ||
24 | testing "unlzma (bad archive 3)" \ | ||
25 | "unlzma <unlzma_issue_3.lzma 2>&1 >/dev/null; echo \$?" \ | ||
26 | "unlzma: corrupted data | ||
27 | 1 | ||
19 | " "" "" | 28 | " "" "" |
20 | 29 | ||
21 | exit $FAILCOUNT | 30 | exit $FAILCOUNT |
diff --git a/testsuite/unlzma_issue_3.lzma b/testsuite/unlzma_issue_3.lzma new file mode 100644 index 000000000..cc60f29e4 --- /dev/null +++ b/testsuite/unlzma_issue_3.lzma | |||
Binary files differ | |||