mirror of
https://git.tukaani.org/xz.git
synced 2024-04-04 12:36:23 +02:00
liblzma: Validate encoder arguments better.
The biggest problem was that the integrity check type wasn't validated, and e.g. lzma_easy_buffer_encode() would create a corrupt .xz Stream if given an unsupported Check ID. Luckily applications don't usually try to use an unsupport Check ID, so this bug is unlikely to cause many real-world problems.
This commit is contained in:
parent
ec7e3dbad7
commit
71b9380145
3 changed files with 20 additions and 6 deletions
|
@ -226,16 +226,23 @@ lzma_block_buffer_encode(lzma_block *block, lzma_allocator *allocator,
|
||||||
const uint8_t *in, size_t in_size,
|
const uint8_t *in, size_t in_size,
|
||||||
uint8_t *out, size_t *out_pos, size_t out_size)
|
uint8_t *out, size_t *out_pos, size_t out_size)
|
||||||
{
|
{
|
||||||
// Sanity checks
|
// Validate the arguments.
|
||||||
if (block == NULL || block->filters == NULL
|
if (block == NULL || (in == NULL && in_size != 0) || out == NULL
|
||||||
|| (in == NULL && in_size != 0) || out == NULL
|
|
||||||
|| out_pos == NULL || *out_pos > out_size)
|
|| out_pos == NULL || *out_pos > out_size)
|
||||||
return LZMA_PROG_ERROR;
|
return LZMA_PROG_ERROR;
|
||||||
|
|
||||||
// Check the version field.
|
// The contents of the structure may depend on the version so
|
||||||
|
// check the version before validating the contents of *block.
|
||||||
if (block->version != 0)
|
if (block->version != 0)
|
||||||
return LZMA_OPTIONS_ERROR;
|
return LZMA_OPTIONS_ERROR;
|
||||||
|
|
||||||
|
if ((unsigned int)(block->check) > LZMA_CHECK_ID_MAX
|
||||||
|
|| block->filters == NULL)
|
||||||
|
return LZMA_PROG_ERROR;
|
||||||
|
|
||||||
|
if (!lzma_check_is_supported(block->check))
|
||||||
|
return LZMA_UNSUPPORTED_CHECK;
|
||||||
|
|
||||||
// Size of a Block has to be a multiple of four, so limit the size
|
// Size of a Block has to be a multiple of four, so limit the size
|
||||||
// here already. This way we don't need to check it again when adding
|
// here already. This way we don't need to check it again when adding
|
||||||
// Block Padding.
|
// Block Padding.
|
||||||
|
@ -243,8 +250,7 @@ lzma_block_buffer_encode(lzma_block *block, lzma_allocator *allocator,
|
||||||
|
|
||||||
// Get the size of the Check field.
|
// Get the size of the Check field.
|
||||||
const size_t check_size = lzma_check_size(block->check);
|
const size_t check_size = lzma_check_size(block->check);
|
||||||
if (check_size == UINT32_MAX)
|
assert(check_size != UINT32_MAX);
|
||||||
return LZMA_PROG_ERROR;
|
|
||||||
|
|
||||||
// Reserve space for the Check field.
|
// Reserve space for the Check field.
|
||||||
if (out_size - *out_pos <= check_size)
|
if (out_size - *out_pos <= check_size)
|
||||||
|
|
|
@ -161,6 +161,11 @@ lzma_block_encoder_init(lzma_next_coder *next, lzma_allocator *allocator,
|
||||||
{
|
{
|
||||||
lzma_next_coder_init(&lzma_block_encoder_init, next, allocator);
|
lzma_next_coder_init(&lzma_block_encoder_init, next, allocator);
|
||||||
|
|
||||||
|
if (block == NULL)
|
||||||
|
return LZMA_PROG_ERROR;
|
||||||
|
|
||||||
|
// The contents of the structure may depend on the version so
|
||||||
|
// check the version first.
|
||||||
if (block->version != 0)
|
if (block->version != 0)
|
||||||
return LZMA_OPTIONS_ERROR;
|
return LZMA_OPTIONS_ERROR;
|
||||||
|
|
||||||
|
|
|
@ -51,6 +51,9 @@ lzma_stream_buffer_encode(lzma_filter *filters, lzma_check check,
|
||||||
|| out_pos_ptr == NULL || *out_pos_ptr > out_size)
|
|| out_pos_ptr == NULL || *out_pos_ptr > out_size)
|
||||||
return LZMA_PROG_ERROR;
|
return LZMA_PROG_ERROR;
|
||||||
|
|
||||||
|
if (!lzma_check_is_supported(check))
|
||||||
|
return LZMA_UNSUPPORTED_CHECK;
|
||||||
|
|
||||||
// Note for the paranoids: Index encoder prevents the Stream from
|
// Note for the paranoids: Index encoder prevents the Stream from
|
||||||
// getting too big and still being accepted with LZMA_OK, and Block
|
// getting too big and still being accepted with LZMA_OK, and Block
|
||||||
// encoder catches if the input is too big. So we don't need to
|
// encoder catches if the input is too big. So we don't need to
|
||||||
|
|
Loading…
Reference in a new issue