Bug 10436 (CVE-2017-15874)

Summary: LZMA decompression crash
Product: Busybox Reporter: Ariel Zelivansky <ariel>
Component: OtherAssignee: unassigned
Status: RESOLVED DUPLICATE    
Severity: normal CC: busybox-cvs
Priority: P5    
Version: 1.27.x   
Target Milestone: ---   
Hardware: All   
OS: Linux   
Host: Target:
Build:
Attachments: Crash file
afl readme

Description Ariel Zelivansky 2017-10-22 13:17:20 UTC
Created attachment 7306 [details]
Crash file

I found a vulnerability in the unlzma code (archival/libarchive/decompress_unlzma.c line 455) while fuzzing the unzip applet. The crash is a read access violation.

Attached is one of the crash files and the fuzzer info. Tested with 1.27.2.
Comment 1 Ariel Zelivansky 2017-10-22 13:17:39 UTC
Created attachment 7311 [details]
afl readme
Comment 2 Ariel Zelivansky 2017-10-24 10:54:22 UTC
Could be an integer underflow in line 452.

uint32_t pos = buffer_pos - rep0;

I'm not sure what's going on there (next line checks if pos is negative...?).
Comment 3 Christoph Biedl 2017-10-25 17:48:03 UTC
This is actually a regression, introduced with

commit 3989e5adf454a3ab98412b249c2c9bd2a3175ae0 (refs/bisect/bad)
Author: Denys Vlasenko <vda.linux@googlemail.com>
Date:   Mon Jan 9 13:55:11 2017 +0100

    unlzma: fix erroneous "while" instead of "if". Closes 4682

Looking at the last hunk I wild-guessed the patch below. Check
throroughly, I might be horribly wrong.

    Christoph

--- a/archival/libarchive/decompress_unlzma.c
+++ b/archival/libarchive/decompress_unlzma.c
@@ -450,8 +450,11 @@ unpack_lzma_stream(transformer_state_t *xstate)
  IF_NOT_FEATURE_LZMA_FAST(string:)
                        do {
                                uint32_t pos = buffer_pos - rep0;
-                               if ((int32_t)pos < 0)
+                               if ((int32_t)pos < 0) {
                                        pos += header.dict_size;
+                                       if ((int32_t)pos < 0)
+                                               goto bad;
+                               }
                                previous_byte = buffer[pos];
  IF_NOT_FEATURE_LZMA_FAST(one_byte2:)
                                buffer[buffer_pos++] = previous_byte;
Comment 4 Denys Vlasenko 2017-10-27 13:39:00 UTC
Fixed in git, thanks!
Comment 5 Andrej Valek 2018-03-23 09:21:00 UTC
New problem founded in [Bug 10871].
Comment 6 Denys Vlasenko 2018-04-09 12:27:25 UTC

*** This bug has been marked as a duplicate of bug 10871 ***
Comment 7 Jhon Merced 2018-05-15 13:57:41 UTC
Seems really fixed in Git! But thanks for some related solutions.

Jhon
https://amsterdamdiary.com/