CVE-2016-4302
An exploitable heap overflow vulnerability exists in the Rar decompression functionality of libarchive. A specially crafted Rar file can cause a heap corruption eventually leading to code execution. An attacker can send a malformed file to trigger this vulnerability.
libarchive git version on date 02.12.2015 Platform : x86/x64
https://github.com/libarchive/libarchive
7.8 - CVSS:3.0/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H
CVSSv3 Calculator: https://www.first.org/cvss/calculator/3.0
Here we see the execution flow leading to heap corruption:
archive_read_next_header
archive_read_format_rar_read_header
head_type : 0x72
head_type : 0x73
head_type : 0x74
read_header
rar->packed_size : 0x1
rar->dictionary_size = 0;
archive_format_name : RAR
archive_read_extract
rar->compression_method : 0x31
read_data_compressed
archive_read_format_rar_read_header
head_type : 0x7a
read_header
parse_codes
if (ppmd_flags & 0x20)
archive_read_format_rar_read_header
head_type : 0x7b
archive_read_format_rar_read_header
head_type : 0x74
read_header
rar->packed_size : 0x1
rar->dictionary_size = 0;
archive_read_format_rar_read_header
head_type : 0x7a
read_header
rar->dictionary_size : 0x10000000
archive_read_format_rar_read_header
head_type : 0x7b
archive_read_format_rar_read_header
head_type : 0x74
read_header
rar->packed_size : 0x1
rar->dictionary_size = 0;
archive_read_format_rar_read_header
archive_read_format_rar_read_header
__archive_ppmd7_functions.PpmdRAR_RangeDec_CreateVTable(&rar->range_dec);
ppmd_alloc : 0
archive_read_format_rar_read_header
archive_read_format_rar_read_header
archive_read_format_rar_read_header
archive_read_format_rar_read_header
archive_read_format_rar_read_header
archive_read_format_rar_read_header
archive_read_format_rar_read_header
archive_read_format_rar_read_header
Ppmd7_Init
RestartModel
*** Heap corruption ***
Let’s focus on extraction phase, so everyting below archive_read_extract. The key variable/field here is rar->dictionary_size.
First we see that its value is set to:
rar->dictionary_size : 0x10000000
libarchive\archive_read_support_format_rar.c
Line 2073 /* Memory is allocated in MB */
Line 2074 if (ppmd_flags & 0x20)
Line 2075 {
Line 2076 if (!rar_br_read_ahead(a, br, 8))
Line 2077 goto truncated_data;
Line 2078 rar->dictionary_size = (rar_br_bits(br, 8) + 1) << 20;
Line 2079 rar_br_consume(br, 8);
Line 2080 }
Next, because of small value of “packed_size”:
rar->packed_size : 0x1
Another portion of data is read from file and parsed like during “reading phase” in archive_read_next_header by calling archive_read_format_rar_read_header and read_header functions. During one of these calls, we see that value of dictionary_size is set to zero. Next allocation for Ppmd context depends on the value of dictionary_size:
libarchive\archive_read_support_format_rar.c
Line 2115 if ( !__archive_ppmd7_functions.Ppmd7_Alloc(&rar->ppmd7_context,rar->dictionary_size, &g_szalloc) )
libarchive\archive_ppmd7.c
Line 125 static Bool Ppmd7_Alloc(CPpmd7 *p, UInt32 size, ISzAlloc *alloc)
Line 126 {
Line 127 if (p->Base == 0 || p->Size != size)
Line 128 {
Line 129 Ppmd7_Free(p, alloc);
Line 130 p->AlignOffset =
Line 131 #ifdef PPMD_32BIT
Line 132 (4 - size) & 3;
Line 133 #else
Line 134 4 - (size & 3);
Line 135 #endif
Line 136 if ((p->Base = (Byte *)alloc->Alloc(alloc, p->AlignOffset + size
Line 137 #ifndef PPMD_32BIT
Line 138 + UNIT_SIZE
Line 139 #endif
Line 140 )) == 0)
Line 141 return False;
Line 142 p->Size = size;
Line 143 }
Line 144 return True;
Line 145 }
As we can see for dictionary_size equal 0 we will have allocation made for 0 bytes:
python import gdbheap
p p->Base
$5 = (Byte *) 0x80e2480 " \b\r\brn"
heap select size==16
Reading in symbols for malloc.c...done.
Start End Domain Kind Detail Hexdump
---------- ---------- ------------- ----------- -------- ----------------------------------------------------------------------------------
0x080d0798 0x080d07a7 uncategorized 16 bytes a8 07 0d 08 03 00 00 00 57 4d 54 00 19 00 00 00 c0 07 0d 08 |........WMT.........|
0x080d07c0 0x080d07cf uncategorized 16 bytes d0 07 0d 08 03 00 00 00 43 45 54 00 19 00 00 00 e8 07 0d 08 |........CET.........|
0x080d07e8 0x080d07f7 uncategorized 16 bytes 00 00 00 00 03 00 00 00 45 45 54 00 21 00 00 00 72 61 72 2d |........EET.!...rar-|
0x080d0818 0x080d0827 uncategorized 16 bytes 00 00 00 00 50 a4 d8 f7 00 00 00 00 11 00 00 00 50 70 6d 64 |....P...........Ppmd|
0x080d0828 0x080d0837 C string data 50 70 6d 64 37 5f 49 6e 69 74 0a 00 21 00 00 00 44 00 00 00 |Ppmd7_Init..!...D...|
0x080d0cd8 0x080d0ce7 uncategorized 16 bytes e8 0c 0d 08 00 00 00 00 00 00 00 00 f9 01 00 00 c5 b0 01 c0 |....................|
0x080e2470 0x080e247f uncategorized 16 bytes 00 69 62 61 32 2e 68 74 6d 6c c0 cc 11 00 00 00 20 08 0d 08 |.iba2.html...... ...|
0x080e2480 0x080e248f C string data 20 08 0d 08 72 6e 00 00 00 00 00 00 21 00 00 00 72 61 72 2d | ...rn......!...rar-|
Finally we land in RestartModel function:
libarchive\archive_ppmd7.c
Line 314 static void RestartModel(CPpmd7 *p)
Line 315 {
Line 316 unsigned i, k, m;
Line 317
Line 318 memset(p->FreeList, 0, sizeof(p->FreeList));
Line 319 p->Text = p->Base + p->AlignOffset;
Line 320 p->HiUnit = p->Text + p->Size;
Line 321 p->LoUnit = p->UnitsStart = p->HiUnit - p->Size / 8 / UNIT_SIZE * 7 * UNIT_SIZE;
Line 322 p->GlueCount = 0;
Line 323
Line 324 p->OrderFall = p->MaxOrder;
Line 325 p->RunLength = p->InitRL = -(Int32)((p->MaxOrder < 12) ? p->MaxOrder : 12) - 1;
Line 326 p->PrevSuccess = 0;
Line 327
Line 328 p->MinContext = p->MaxContext = (CTX_PTR)(p->HiUnit -= UNIT_SIZE); /* AllocContext(p); */
Line 329 p->MinContext->Suffix = 0;
Line 330 p->MinContext->NumStats = 256;
Line 331 p->MinContext->SummFreq = 256 + 1;
Line 332 p->FoundState = (CPpmd_State *)p->LoUnit; /* AllocUnits(p, PPMD_NUM_INDEXES - 1); */
Line 333 p->LoUnit += U2B(256 / 2);
Line 334 p->MinContext->Stats = REF(p->FoundState);
The key values here are:
p p->AlignOffset
$6 = 0
p p->Size
$7 = 0
As we can see above both equal 0 which has consequences in line 328 where UNIT_SIZE (12) is subtracted from p->HiUnit pointer and assigned to p->MinContext: When everything is correct p->HiUnit first is set at the end of allocated space for Ppmd context, but because AlignOffset and Size is equal 0 it still points to the beginning. In result of this substraction p->MinContext is set to the inside of previous heap chunk space.
p p->MinContext
$8 = (CPpmd7_Context *) 0x80e2474
heap:
0x080e2470 0x080e247f uncategorized 16 bytes 00 69 62 61 32
2e 68 74 6d 6c c0 cc 11 00 00 00 20 08 0d 08 |.iba2.html...... ...|
0x080e2480 0x080e248f C string data 20 08 0d 08 72
6e 00 00 00 00 00 00 21 00 00 00 72 61 72 2d | ...rn......!...rar-|
Further writes to this structure overwrite heap chunks:
Heap check before execution of line 329:
python from heap.glibc import *
python print MChunkPtr(gdb.Value(0x080e2480-8).cast(MChunkPtr.gdb_type()))
<MChunkPtr chunk=0x80e2478 mem=0x80e2480 PREV_INUSE inuse chunksize=16 memsize=8>
After execution:
python print MChunkPtr(gdb.Value(0x080e2480-8).cast(MChunkPtr.gdb_type()))
<MChunkPtr chunk=0x80e2478 mem=0x80e2480 prev_size=3435162733 free chunksize=0 memsize=-8>
Valgrind Output:
==13328== Memcheck, a memory error detector
==13328== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==13328== Using Valgrind-3.10.0.SVN and LibVEX; rerun with -h for copyright info
==13328== Command: libarchive-pure32/bin/ext /home/icewall/samples/rar/pmd7.rar rar
==13328==
==13328== Invalid write of size 4
==13328== at 0x809C4D4: RestartModel (archive_ppmd7.c:329)
==13328== by 0x809C693: Ppmd7_Init (archive_ppmd7.c:364)
==13328== by 0x807C20F: parse_codes (archive_read_support_format_rar.c:2128)
==13328== by 0x807B8CA: read_data_compressed (archive_read_support_format_rar.c:1919)
==13328== by 0x8079049: archive_read_format_rar_read_data (archive_read_support_format_rar.c:1025)
==13328== by 0x804ED6B: _archive_read_data_block (archive_read.c:982)
==13328== by 0x8091B3B: archive_read_data_block (archive_virtual.c:161)
==13328== by 0x805083C: copy_data (archive_read_extract2.c:139)
==13328== by 0x8050770: archive_read_extract2 (archive_read_extract2.c:101)
==13328== by 0x80505CE: archive_read_extract (archive_read_extract.c:59)
==13328== by 0x804A3E2: extract (ext.c:63)
==13328== by 0x804A45A: main (ext.c:85)
==13328== Address 0x445c06c is 4 bytes before a block of size 0 alloc'd
==13328== at 0x402A17C: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==13328== by 0x80783CC: ppmd_alloc (archive_read_support_format_rar.c:611)
==13328== by 0x809BD73: Ppmd7_Alloc (archive_ppmd7.c:136)
==13328== by 0x807C190: parse_codes (archive_read_support_format_rar.c:2115)
==13328== by 0x807B8CA: read_data_compressed (archive_read_support_format_rar.c:1919)
==13328== by 0x8079049: archive_read_format_rar_read_data (archive_read_support_format_rar.c:1025)
==13328== by 0x804ED6B: _archive_read_data_block (archive_read.c:982)
==13328== by 0x8091B3B: archive_read_data_block (archive_virtual.c:161)
==13328== by 0x805083C: copy_data (archive_read_extract2.c:139)
==13328== by 0x8050770: archive_read_extract2 (archive_read_extract2.c:101)
==13328== by 0x80505CE: archive_read_extract (archive_read_extract.c:59)
==13328== by 0x804A3E2: extract (ext.c:63)
==13328==
==13328== Invalid write of size 2
==13328== at 0x809C4E0: RestartModel (archive_ppmd7.c:330)
==13328== by 0x809C693: Ppmd7_Init (archive_ppmd7.c:364)
==13328== by 0x807C20F: parse_codes (archive_read_support_format_rar.c:2128)
==13328== by 0x807B8CA: read_data_compressed (archive_read_support_format_rar.c:1919)
==13328== by 0x8079049: archive_read_format_rar_read_data (archive_read_support_format_rar.c:1025)
==13328== by 0x804ED6B: _archive_read_data_block (archive_read.c:982)
==13328== by 0x8091B3B: archive_read_data_block (archive_virtual.c:161)
==13328== by 0x805083C: copy_data (archive_read_extract2.c:139)
==13328== by 0x8050770: archive_read_extract2 (archive_read_extract2.c:101)
==13328== by 0x80505CE: archive_read_extract (archive_read_extract.c:59)
==13328== by 0x804A3E2: extract (ext.c:63)
==13328== by 0x804A45A: main (ext.c:85)
==13328== Address 0x445c064 is 12 bytes before a block of size 0 alloc'd
==13328== at 0x402A17C: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==13328== by 0x80783CC: ppmd_alloc (archive_read_support_format_rar.c:611)
==13328== by 0x809BD73: Ppmd7_Alloc (archive_ppmd7.c:136)
==13328== by 0x807C190: parse_codes (archive_read_support_format_rar.c:2115)
==13328== by 0x807B8CA: read_data_compressed (archive_read_support_format_rar.c:1919)
==13328== by 0x8079049: archive_read_format_rar_read_data (archive_read_support_format_rar.c:1025)
==13328== by 0x804ED6B: _archive_read_data_block (archive_read.c:982)
==13328== by 0x8091B3B: archive_read_data_block (archive_virtual.c:161)
==13328== by 0x805083C: copy_data (archive_read_extract2.c:139)
==13328== by 0x8050770: archive_read_extract2 (archive_read_extract2.c:101)
==13328== by 0x80505CE: archive_read_extract (archive_read_extract.c:59)
==13328== by 0x804A3E2: extract (ext.c:63)
==13328==
==13328== Invalid write of size 2
==13328== at 0x809C4EA: RestartModel (archive_ppmd7.c:331)
==13328== by 0x809C693: Ppmd7_Init (archive_ppmd7.c:364)
==13328== by 0x807C20F: parse_codes (archive_read_support_format_rar.c:2128)
==13328== by 0x807B8CA: read_data_compressed (archive_read_support_format_rar.c:1919)
==13328== by 0x8079049: archive_read_format_rar_read_data (archive_read_support_format_rar.c:1025)
==13328== by 0x804ED6B: _archive_read_data_block (archive_read.c:982)
==13328== by 0x8091B3B: archive_read_data_block (archive_virtual.c:161)
==13328== by 0x805083C: copy_data (archive_read_extract2.c:139)
==13328== by 0x8050770: archive_read_extract2 (archive_read_extract2.c:101)
==13328== by 0x80505CE: archive_read_extract (archive_read_extract.c:59)
==13328== by 0x804A3E2: extract (ext.c:63)
==13328== by 0x804A45A: main (ext.c:85)
==13328== Address 0x445c066 is 10 bytes before a block of size 0 alloc'd
==13328== at 0x402A17C: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==13328== by 0x80783CC: ppmd_alloc (archive_read_support_format_rar.c:611)
==13328== by 0x809BD73: Ppmd7_Alloc (archive_ppmd7.c:136)
==13328== by 0x807C190: parse_codes (archive_read_support_format_rar.c:2115)
==13328== by 0x807B8CA: read_data_compressed (archive_read_support_format_rar.c:1919)
==13328== by 0x8079049: archive_read_format_rar_read_data (archive_read_support_format_rar.c:1025)
==13328== by 0x804ED6B: _archive_read_data_block (archive_read.c:982)
==13328== by 0x8091B3B: archive_read_data_block (archive_virtual.c:161)
==13328== by 0x805083C: copy_data (archive_read_extract2.c:139)
==13328== by 0x8050770: archive_read_extract2 (archive_read_extract2.c:101)
==13328== by 0x80505CE: archive_read_extract (archive_read_extract.c:59)
==13328== by 0x804A3E2: extract (ext.c:63)
==13328==
==13328== Invalid write of size 4
==13328== at 0x809C519: RestartModel (archive_ppmd7.c:334)
==13328== by 0x809C693: Ppmd7_Init (archive_ppmd7.c:364)
==13328== by 0x807C20F: parse_codes (archive_read_support_format_rar.c:2128)
==13328== by 0x807B8CA: read_data_compressed (archive_read_support_format_rar.c:1919)
==13328== by 0x8079049: archive_read_format_rar_read_data (archive_read_support_format_rar.c:1025)
==13328== by 0x804ED6B: _archive_read_data_block (archive_read.c:982)
==13328== by 0x8091B3B: archive_read_data_block (archive_virtual.c:161)
==13328== by 0x805083C: copy_data (archive_read_extract2.c:139)
==13328== by 0x8050770: archive_read_extract2 (archive_read_extract2.c:101)
==13328== by 0x80505CE: archive_read_extract (archive_read_extract.c:59)
==13328== by 0x804A3E2: extract (ext.c:63)
==13328== by 0x804A45A: main (ext.c:85)
==13328== Address 0x445c068 is 8 bytes before a block of size 0 alloc'd
==13328== at 0x402A17C: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==13328== by 0x80783CC: ppmd_alloc (archive_read_support_format_rar.c:611)
==13328== by 0x809BD73: Ppmd7_Alloc (archive_ppmd7.c:136)
==13328== by 0x807C190: parse_codes (archive_read_support_format_rar.c:2115)
==13328== by 0x807B8CA: read_data_compressed (archive_read_support_format_rar.c:1919)
==13328== by 0x8079049: archive_read_format_rar_read_data (archive_read_support_format_rar.c:1025)
==13328== by 0x804ED6B: _archive_read_data_block (archive_read.c:982)
==13328== by 0x8091B3B: archive_read_data_block (archive_virtual.c:161)
==13328== by 0x805083C: copy_data (archive_read_extract2.c:139)
==13328== by 0x8050770: archive_read_extract2 (archive_read_extract2.c:101)
==13328== by 0x80505CE: archive_read_extract (archive_read_extract.c:59)
==13328== by 0x804A3E2: extract (ext.c:63)
==13328==
==13328== Invalid write of size 1
==13328== at 0x809C543: RestartModel (archive_ppmd7.c:338)
==13328== by 0x809C693: Ppmd7_Init (archive_ppmd7.c:364)
==13328== by 0x807C20F: parse_codes (archive_read_support_format_rar.c:2128)
==13328== by 0x807B8CA: read_data_compressed (archive_read_support_format_rar.c:1919)
==13328== by 0x8079049: archive_read_format_rar_read_data (archive_read_support_format_rar.c:1025)
==13328== by 0x804ED6B: _archive_read_data_block (archive_read.c:982)
==13328== by 0x8091B3B: archive_read_data_block (archive_virtual.c:161)
==13328== by 0x805083C: copy_data (archive_read_extract2.c:139)
==13328== by 0x8050770: archive_read_extract2 (archive_read_extract2.c:101)
==13328== by 0x80505CE: archive_read_extract (archive_read_extract.c:59)
==13328== by 0x804A3E2: extract (ext.c:63)
==13328== by 0x804A45A: main (ext.c:85)
==13328== Address 0x445c070 is 0 bytes after a block of size 0 alloc'd
==13328== at 0x402A17C: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==13328== by 0x80783CC: ppmd_alloc (archive_read_support_format_rar.c:611)
==13328== by 0x809BD73: Ppmd7_Alloc (archive_ppmd7.c:136)
==13328== by 0x807C190: parse_codes (archive_read_support_format_rar.c:2115)
==13328== by 0x807B8CA: read_data_compressed (archive_read_support_format_rar.c:1919)
==13328== by 0x8079049: archive_read_format_rar_read_data (archive_read_support_format_rar.c:1025)
==13328== by 0x804ED6B: _archive_read_data_block (archive_read.c:982)
==13328== by 0x8091B3B: archive_read_data_block (archive_virtual.c:161)
==13328== by 0x805083C: copy_data (archive_read_extract2.c:139)
==13328== by 0x8050770: archive_read_extract2 (archive_read_extract2.c:101)
==13328== by 0x80505CE: archive_read_extract (archive_read_extract.c:59)
==13328== by 0x804A3E2: extract (ext.c:63)
==13328==
==13328== Invalid write of size 1
==13328== at 0x809C548: RestartModel (archive_ppmd7.c:339)
==13328== by 0x809C693: Ppmd7_Init (archive_ppmd7.c:364)
==13328== by 0x807C20F: parse_codes (archive_read_support_format_rar.c:2128)
==13328== by 0x807B8CA: read_data_compressed (archive_read_support_format_rar.c:1919)
==13328== by 0x8079049: archive_read_format_rar_read_data (archive_read_support_format_rar.c:1025)
==13328== by 0x804ED6B: _archive_read_data_block (archive_read.c:982)
==13328== by 0x8091B3B: archive_read_data_block (archive_virtual.c:161)
==13328== by 0x805083C: copy_data (archive_read_extract2.c:139)
==13328== by 0x8050770: archive_read_extract2 (archive_read_extract2.c:101)
==13328== by 0x80505CE: archive_read_extract (archive_read_extract.c:59)
==13328== by 0x804A3E2: extract (ext.c:63)
==13328== by 0x804A45A: main (ext.c:85)
==13328== Address 0x445c071 is 1 bytes after a block of size 0 alloc'd
==13328== at 0x402A17C: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==13328== by 0x80783CC: ppmd_alloc (archive_read_support_format_rar.c:611)
==13328== by 0x809BD73: Ppmd7_Alloc (archive_ppmd7.c:136)
==13328== by 0x807C190: parse_codes (archive_read_support_format_rar.c:2115)
==13328== by 0x807B8CA: read_data_compressed (archive_read_support_format_rar.c:1919)
==13328== by 0x8079049: archive_read_format_rar_read_data (archive_read_support_format_rar.c:1025)
==13328== by 0x804ED6B: _archive_read_data_block (archive_read.c:982)
==13328== by 0x8091B3B: archive_read_data_block (archive_virtual.c:161)
==13328== by 0x805083C: copy_data (archive_read_extract2.c:139)
==13328== by 0x8050770: archive_read_extract2 (archive_read_extract2.c:101)
==13328== by 0x80505CE: archive_read_extract (archive_read_extract.c:59)
==13328== by 0x804A3E2: extract (ext.c:63)
==13328==
==13328== Invalid write of size 2
==13328== at 0x809C3CC: SetSuccessor (archive_ppmd7.c:310)
==13328== by 0x809C55E: RestartModel (archive_ppmd7.c:340)
==13328== by 0x809C693: Ppmd7_Init (archive_ppmd7.c:364)
==13328== by 0x807C20F: parse_codes (archive_read_support_format_rar.c:2128)
==13328== by 0x807B8CA: read_data_compressed (archive_read_support_format_rar.c:1919)
==13328== by 0x8079049: archive_read_format_rar_read_data (archive_read_support_format_rar.c:1025)
==13328== by 0x804ED6B: _archive_read_data_block (archive_read.c:982)
==13328== by 0x8091B3B: archive_read_data_block (archive_virtual.c:161)
==13328== by 0x805083C: copy_data (archive_read_extract2.c:139)
==13328== by 0x8050770: archive_read_extract2 (archive_read_extract2.c:101)
==13328== by 0x80505CE: archive_read_extract (archive_read_extract.c:59)
==13328== by 0x804A3E2: extract (ext.c:63)
==13328== Address 0x445c072 is 2 bytes after a block of size 0 alloc'd
==13328== at 0x402A17C: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==13328== by 0x80783CC: ppmd_alloc (archive_read_support_format_rar.c:611)
==13328== by 0x809BD73: Ppmd7_Alloc (archive_ppmd7.c:136)
==13328== by 0x807C190: parse_codes (archive_read_support_format_rar.c:2115)
==13328== by 0x807B8CA: read_data_compressed (archive_read_support_format_rar.c:1919)
==13328== by 0x8079049: archive_read_format_rar_read_data (archive_read_support_format_rar.c:1025)
==13328== by 0x804ED6B: _archive_read_data_block (archive_read.c:982)
==13328== by 0x8091B3B: archive_read_data_block (archive_virtual.c:161)
==13328== by 0x805083C: copy_data (archive_read_extract2.c:139)
==13328== by 0x8050770: archive_read_extract2 (archive_read_extract2.c:101)
==13328== by 0x80505CE: archive_read_extract (archive_read_extract.c:59)
==13328== by 0x804A3E2: extract (ext.c:63)
==13328==
==13328== Invalid write of size 2
==13328== at 0x809C3DB: SetSuccessor (archive_ppmd7.c:311)
==13328== by 0x809C55E: RestartModel (archive_ppmd7.c:340)
==13328== by 0x809C693: Ppmd7_Init (archive_ppmd7.c:364)
==13328== by 0x807C20F: parse_codes (archive_read_support_format_rar.c:2128)
==13328== by 0x807B8CA: read_data_compressed (archive_read_support_format_rar.c:1919)
==13328== by 0x8079049: archive_read_format_rar_read_data (archive_read_support_format_rar.c:1025)
==13328== by 0x804ED6B: _archive_read_data_block (archive_read.c:982)
==13328== by 0x8091B3B: archive_read_data_block (archive_virtual.c:161)
==13328== by 0x805083C: copy_data (archive_read_extract2.c:139)
==13328== by 0x8050770: archive_read_extract2 (archive_read_extract2.c:101)
==13328== by 0x80505CE: archive_read_extract (archive_read_extract.c:59)
==13328== by 0x804A3E2: extract (ext.c:63)
==13328== Address 0x445c074 is 4 bytes after a block of size 0 alloc'd
==13328== at 0x402A17C: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==13328== by 0x80783CC: ppmd_alloc (archive_read_support_format_rar.c:611)
==13328== by 0x809BD73: Ppmd7_Alloc (archive_ppmd7.c:136)
==13328== by 0x807C190: parse_codes (archive_read_support_format_rar.c:2115)
==13328== by 0x807B8CA: read_data_compressed (archive_read_support_format_rar.c:1919)
==13328== by 0x8079049: archive_read_format_rar_read_data (archive_read_support_format_rar.c:1025)
==13328== by 0x804ED6B: _archive_read_data_block (archive_read.c:982)
==13328== by 0x8091B3B: archive_read_data_block (archive_virtual.c:161)
==13328== by 0x805083C: copy_data (archive_read_extract2.c:139)
==13328== by 0x8050770: archive_read_extract2 (archive_read_extract2.c:101)
==13328== by 0x80505CE: archive_read_extract (archive_read_extract.c:59)
==13328== by 0x804A3E2: extract (ext.c:63)
==13328==
2016-04-19 - Vendor Disclosure
2016-06-18 - Public Release
Discovered by Marcin ‘Icewall’ Noga of Cisco Talos