From cd69a5a6c16c289f6f8e2823b03c72289472270f Mon Sep 17 00:00:00 2001 From: Lasse Collin Date: Fri, 10 Jul 2009 11:39:38 +0300 Subject: [PATCH] BCJ filters: Reject invalid start offsets with LZMA_OPTIONS_ERROR. This is a quick and slightly dirty fix to make the code conform to the latest file format specification. Without this patch, it's possible to make corrupt files by specifying start offset that is not a multiple of the filter's alignment. Custom start offset is almost never used, so this was only a minor bug. The xz command line tool doesn't validate the start offset, so one will get a bit unclear error message if trying to use an invalid start offset. --- src/liblzma/simple/arm.c | 2 +- src/liblzma/simple/armthumb.c | 2 +- src/liblzma/simple/ia64.c | 2 +- src/liblzma/simple/powerpc.c | 2 +- src/liblzma/simple/simple_coder.c | 5 ++++- src/liblzma/simple/simple_private.h | 3 ++- src/liblzma/simple/sparc.c | 2 +- src/liblzma/simple/x86.c | 2 +- 8 files changed, 12 insertions(+), 8 deletions(-) diff --git a/src/liblzma/simple/arm.c b/src/liblzma/simple/arm.c index 46960fc..8fcf643 100644 --- a/src/liblzma/simple/arm.c +++ b/src/liblzma/simple/arm.c @@ -49,7 +49,7 @@ arm_coder_init(lzma_next_coder *next, lzma_allocator *allocator, const lzma_filter_info *filters, bool is_encoder) { return lzma_simple_coder_init(next, allocator, filters, - &arm_code, 0, 4, is_encoder); + &arm_code, 0, 4, 4, is_encoder); } diff --git a/src/liblzma/simple/armthumb.c b/src/liblzma/simple/armthumb.c index e20151c..eb6a69d 100644 --- a/src/liblzma/simple/armthumb.c +++ b/src/liblzma/simple/armthumb.c @@ -54,7 +54,7 @@ armthumb_coder_init(lzma_next_coder *next, lzma_allocator *allocator, const lzma_filter_info *filters, bool is_encoder) { return lzma_simple_coder_init(next, allocator, filters, - &armthumb_code, 0, 4, is_encoder); + &armthumb_code, 0, 4, 2, is_encoder); } diff --git a/src/liblzma/simple/ia64.c b/src/liblzma/simple/ia64.c index 60247b3..fd263d4 100644 --- a/src/liblzma/simple/ia64.c +++ b/src/liblzma/simple/ia64.c @@ -90,7 +90,7 @@ ia64_coder_init(lzma_next_coder *next, lzma_allocator *allocator, const lzma_filter_info *filters, bool is_encoder) { return lzma_simple_coder_init(next, allocator, filters, - &ia64_code, 0, 16, is_encoder); + &ia64_code, 0, 16, 16, is_encoder); } diff --git a/src/liblzma/simple/powerpc.c b/src/liblzma/simple/powerpc.c index 7ae734c..aaa14f2 100644 --- a/src/liblzma/simple/powerpc.c +++ b/src/liblzma/simple/powerpc.c @@ -53,7 +53,7 @@ powerpc_coder_init(lzma_next_coder *next, lzma_allocator *allocator, const lzma_filter_info *filters, bool is_encoder) { return lzma_simple_coder_init(next, allocator, filters, - &powerpc_code, 0, 4, is_encoder); + &powerpc_code, 0, 4, 4, is_encoder); } diff --git a/src/liblzma/simple/simple_coder.c b/src/liblzma/simple/simple_coder.c index d44d632..497949a 100644 --- a/src/liblzma/simple/simple_coder.c +++ b/src/liblzma/simple/simple_coder.c @@ -215,7 +215,8 @@ lzma_simple_coder_init(lzma_next_coder *next, lzma_allocator *allocator, const lzma_filter_info *filters, size_t (*filter)(lzma_simple *simple, uint32_t now_pos, bool is_encoder, uint8_t *buffer, size_t size), - size_t simple_size, size_t unfiltered_max, bool is_encoder) + size_t simple_size, size_t unfiltered_max, + uint32_t alignment, bool is_encoder) { // Allocate memory for the lzma_coder structure if needed. if (next->coder == NULL) { @@ -249,6 +250,8 @@ lzma_simple_coder_init(lzma_next_coder *next, lzma_allocator *allocator, if (filters[0].options != NULL) { const lzma_options_bcj *simple = filters[0].options; next->coder->now_pos = simple->start_offset; + if (next->coder->now_pos & (alignment - 1)) + return LZMA_OPTIONS_ERROR; } else { next->coder->now_pos = 0; } diff --git a/src/liblzma/simple/simple_private.h b/src/liblzma/simple/simple_private.h index 7571ae2..a69f827 100644 --- a/src/liblzma/simple/simple_private.h +++ b/src/liblzma/simple/simple_private.h @@ -70,6 +70,7 @@ extern lzma_ret lzma_simple_coder_init(lzma_next_coder *next, lzma_allocator *allocator, const lzma_filter_info *filters, size_t (*filter)(lzma_simple *simple, uint32_t now_pos, bool is_encoder, uint8_t *buffer, size_t size), - size_t simple_size, size_t unfiltered_max, bool is_encoder); + size_t simple_size, size_t unfiltered_max, + uint32_t alignment, bool is_encoder); #endif diff --git a/src/liblzma/simple/sparc.c b/src/liblzma/simple/sparc.c index 04d4282..808a59a 100644 --- a/src/liblzma/simple/sparc.c +++ b/src/liblzma/simple/sparc.c @@ -61,7 +61,7 @@ sparc_coder_init(lzma_next_coder *next, lzma_allocator *allocator, const lzma_filter_info *filters, bool is_encoder) { return lzma_simple_coder_init(next, allocator, filters, - &sparc_code, 0, 4, is_encoder); + &sparc_code, 0, 4, 4, is_encoder); } diff --git a/src/liblzma/simple/x86.c b/src/liblzma/simple/x86.c index 425eae9..5d1509b 100644 --- a/src/liblzma/simple/x86.c +++ b/src/liblzma/simple/x86.c @@ -127,7 +127,7 @@ x86_coder_init(lzma_next_coder *next, lzma_allocator *allocator, const lzma_filter_info *filters, bool is_encoder) { const lzma_ret ret = lzma_simple_coder_init(next, allocator, filters, - &x86_code, sizeof(lzma_simple), 5, is_encoder); + &x86_code, sizeof(lzma_simple), 5, 1, is_encoder); if (ret == LZMA_OK) { next->coder->simple->prev_mask = 0; -- 2.7.4