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>
This commit is contained in:
Denys Vlasenko 2021-06-15 15:07:57 +02:00
parent 4d4fc5ca5e
commit 04f052c56d
3 changed files with 17 additions and 5 deletions

View File

@ -290,8 +290,11 @@ unpack_lzma_stream(transformer_state_t *xstate)
uint32_t pos; uint32_t pos;
pos = buffer_pos - rep0; pos = buffer_pos - rep0;
if ((int32_t)pos < 0) if ((int32_t)pos < 0) {
pos += header.dict_size; pos += header.dict_size;
if ((int32_t)pos < 0)
goto bad;
}
match_byte = buffer[pos]; match_byte = buffer[pos];
do { do {
int bit; int bit;

View File

@ -8,14 +8,23 @@
# Damaged encrypted streams # Damaged encrypted streams
testing "unlzma (bad archive 1)" \ testing "unlzma (bad archive 1)" \
"unlzma <unlzma_issue_1.lzma >/dev/null; echo \$?" \ "unlzma <unlzma_issue_1.lzma 2>&1 >/dev/null; echo \$?" \
"1 "unlzma: corrupted data
1
" "" "" " "" ""
# Damaged encrypted streams # Damaged encrypted streams
testing "unlzma (bad archive 2)" \ testing "unlzma (bad archive 2)" \
"unlzma <unlzma_issue_2.lzma >/dev/null; echo \$?" \ "unlzma <unlzma_issue_2.lzma 2>&1 >/dev/null; echo \$?" \
"1 "unlzma: corrupted data
1
" "" ""
# Damaged encrypted streams
testing "unlzma (bad archive 3)" \
"unlzma <unlzma_issue_3.lzma 2>&1 >/dev/null; echo \$?" \
"unlzma: corrupted data
1
" "" "" " "" ""
exit $FAILCOUNT exit $FAILCOUNT

Binary file not shown.