Fixed a crash in liblzma.
liblzma tries to avoid useless free()/malloc() pairs in initialization when multiple files are handled using the same lzma_stream. This didn't work with filter chains due to comparison of wrong pointers in lzma_next_coder_init(), making liblzma think that no memory reallocation is needed even when it actually is. Easy way to trigger this bug is to decompress two files with a single xz command. The first file should have e.g. x86+LZMA2 as the filter chain, and the second file just LZMA2.
This commit is contained in:
parent
e518d167aa
commit
21c6b94373
|
@ -188,7 +188,7 @@ extern lzma_ret
|
||||||
lzma_alone_decoder_init(lzma_next_coder *next, lzma_allocator *allocator,
|
lzma_alone_decoder_init(lzma_next_coder *next, lzma_allocator *allocator,
|
||||||
uint64_t memlimit)
|
uint64_t memlimit)
|
||||||
{
|
{
|
||||||
lzma_next_coder_init(lzma_alone_decoder_init, next, allocator);
|
lzma_next_coder_init(&lzma_alone_decoder_init, next, allocator);
|
||||||
|
|
||||||
if (memlimit == 0)
|
if (memlimit == 0)
|
||||||
return LZMA_PROG_ERROR;
|
return LZMA_PROG_ERROR;
|
||||||
|
|
|
@ -78,7 +78,7 @@ static lzma_ret
|
||||||
alone_encoder_init(lzma_next_coder *next, lzma_allocator *allocator,
|
alone_encoder_init(lzma_next_coder *next, lzma_allocator *allocator,
|
||||||
const lzma_options_lzma *options)
|
const lzma_options_lzma *options)
|
||||||
{
|
{
|
||||||
lzma_next_coder_init(alone_encoder_init, next, allocator);
|
lzma_next_coder_init(&alone_encoder_init, next, allocator);
|
||||||
|
|
||||||
if (next->coder == NULL) {
|
if (next->coder == NULL) {
|
||||||
next->coder = lzma_alloc(sizeof(lzma_coder), allocator);
|
next->coder = lzma_alloc(sizeof(lzma_coder), allocator);
|
||||||
|
@ -140,7 +140,7 @@ extern lzma_ret
|
||||||
lzma_alone_encoder_init(lzma_next_coder *next, lzma_allocator *allocator,
|
lzma_alone_encoder_init(lzma_next_coder *next, lzma_allocator *allocator,
|
||||||
const lzma_options_alone *options)
|
const lzma_options_alone *options)
|
||||||
{
|
{
|
||||||
lzma_next_coder_init(alone_encoder_init, next, allocator, options);
|
lzma_next_coder_init(&alone_encoder_init, next, allocator, options);
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
|
@ -146,7 +146,7 @@ static lzma_ret
|
||||||
auto_decoder_init(lzma_next_coder *next, lzma_allocator *allocator,
|
auto_decoder_init(lzma_next_coder *next, lzma_allocator *allocator,
|
||||||
uint64_t memlimit, uint32_t flags)
|
uint64_t memlimit, uint32_t flags)
|
||||||
{
|
{
|
||||||
lzma_next_coder_init(auto_decoder_init, next, allocator);
|
lzma_next_coder_init(&auto_decoder_init, next, allocator);
|
||||||
|
|
||||||
if (memlimit == 0)
|
if (memlimit == 0)
|
||||||
return LZMA_PROG_ERROR;
|
return LZMA_PROG_ERROR;
|
||||||
|
|
|
@ -186,7 +186,7 @@ extern lzma_ret
|
||||||
lzma_block_decoder_init(lzma_next_coder *next, lzma_allocator *allocator,
|
lzma_block_decoder_init(lzma_next_coder *next, lzma_allocator *allocator,
|
||||||
lzma_block *block)
|
lzma_block *block)
|
||||||
{
|
{
|
||||||
lzma_next_coder_init(lzma_block_decoder_init, next, allocator);
|
lzma_next_coder_init(&lzma_block_decoder_init, next, allocator);
|
||||||
|
|
||||||
// Validate the options. lzma_block_unpadded_size() does that for us
|
// Validate the options. lzma_block_unpadded_size() does that for us
|
||||||
// except for Uncompressed Size and filters. Filters are validated
|
// except for Uncompressed Size and filters. Filters are validated
|
||||||
|
|
|
@ -149,7 +149,7 @@ extern lzma_ret
|
||||||
lzma_block_encoder_init(lzma_next_coder *next, lzma_allocator *allocator,
|
lzma_block_encoder_init(lzma_next_coder *next, lzma_allocator *allocator,
|
||||||
lzma_block *block)
|
lzma_block *block)
|
||||||
{
|
{
|
||||||
lzma_next_coder_init(lzma_block_encoder_init, next, allocator);
|
lzma_next_coder_init(&lzma_block_encoder_init, next, allocator);
|
||||||
|
|
||||||
if (block->version != 0)
|
if (block->version != 0)
|
||||||
return LZMA_OPTIONS_ERROR;
|
return LZMA_OPTIONS_ERROR;
|
||||||
|
|
|
@ -240,9 +240,9 @@ do { \
|
||||||
/// next->init to func is still OK.
|
/// next->init to func is still OK.
|
||||||
#define lzma_next_coder_init(func, next, allocator) \
|
#define lzma_next_coder_init(func, next, allocator) \
|
||||||
do { \
|
do { \
|
||||||
if ((uintptr_t)(&func) != (next)->init) \
|
if ((uintptr_t)(func) != (next)->init) \
|
||||||
lzma_next_end(next, allocator); \
|
lzma_next_end(next, allocator); \
|
||||||
(next)->init = (uintptr_t)(&func); \
|
(next)->init = (uintptr_t)(func); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -45,7 +45,7 @@ static lzma_ret
|
||||||
easy_encoder_init(lzma_next_coder *next, lzma_allocator *allocator,
|
easy_encoder_init(lzma_next_coder *next, lzma_allocator *allocator,
|
||||||
uint32_t preset, lzma_check check)
|
uint32_t preset, lzma_check check)
|
||||||
{
|
{
|
||||||
lzma_next_coder_init(easy_encoder_init, next, allocator);
|
lzma_next_coder_init(&easy_encoder_init, next, allocator);
|
||||||
|
|
||||||
if (next->coder == NULL) {
|
if (next->coder == NULL) {
|
||||||
next->coder = lzma_alloc(sizeof(lzma_coder), allocator);
|
next->coder = lzma_alloc(sizeof(lzma_coder), allocator);
|
||||||
|
|
|
@ -243,7 +243,7 @@ static lzma_ret
|
||||||
index_decoder_init(lzma_next_coder *next, lzma_allocator *allocator,
|
index_decoder_init(lzma_next_coder *next, lzma_allocator *allocator,
|
||||||
lzma_index **i, uint64_t memlimit)
|
lzma_index **i, uint64_t memlimit)
|
||||||
{
|
{
|
||||||
lzma_next_coder_init(index_decoder_init, next, allocator);
|
lzma_next_coder_init(&index_decoder_init, next, allocator);
|
||||||
|
|
||||||
if (i == NULL || memlimit == 0)
|
if (i == NULL || memlimit == 0)
|
||||||
return LZMA_PROG_ERROR;
|
return LZMA_PROG_ERROR;
|
||||||
|
|
|
@ -189,7 +189,7 @@ extern lzma_ret
|
||||||
lzma_index_encoder_init(lzma_next_coder *next, lzma_allocator *allocator,
|
lzma_index_encoder_init(lzma_next_coder *next, lzma_allocator *allocator,
|
||||||
lzma_index *i)
|
lzma_index *i)
|
||||||
{
|
{
|
||||||
lzma_next_coder_init(lzma_index_encoder_init, next, allocator);
|
lzma_next_coder_init(&lzma_index_encoder_init, next, allocator);
|
||||||
|
|
||||||
if (i == NULL)
|
if (i == NULL)
|
||||||
return LZMA_PROG_ERROR;
|
return LZMA_PROG_ERROR;
|
||||||
|
|
|
@ -398,7 +398,7 @@ extern lzma_ret
|
||||||
lzma_stream_decoder_init(lzma_next_coder *next, lzma_allocator *allocator,
|
lzma_stream_decoder_init(lzma_next_coder *next, lzma_allocator *allocator,
|
||||||
uint64_t memlimit, uint32_t flags)
|
uint64_t memlimit, uint32_t flags)
|
||||||
{
|
{
|
||||||
lzma_next_coder_init(lzma_stream_decoder_init, next, allocator);
|
lzma_next_coder_init(&lzma_stream_decoder_init, next, allocator);
|
||||||
|
|
||||||
if (memlimit == 0)
|
if (memlimit == 0)
|
||||||
return LZMA_PROG_ERROR;
|
return LZMA_PROG_ERROR;
|
||||||
|
|
|
@ -211,7 +211,7 @@ extern lzma_ret
|
||||||
lzma_stream_encoder_init(lzma_next_coder *next, lzma_allocator *allocator,
|
lzma_stream_encoder_init(lzma_next_coder *next, lzma_allocator *allocator,
|
||||||
const lzma_filter *filters, lzma_check check)
|
const lzma_filter *filters, lzma_check check)
|
||||||
{
|
{
|
||||||
lzma_next_coder_init(lzma_stream_encoder_init, next, allocator);
|
lzma_next_coder_init(&lzma_stream_encoder_init, next, allocator);
|
||||||
|
|
||||||
if (filters == NULL)
|
if (filters == NULL)
|
||||||
return LZMA_PROG_ERROR;
|
return LZMA_PROG_ERROR;
|
||||||
|
|
Loading…
Reference in New Issue