mirror of
https://github.com/samba-team/samba.git
synced 2025-02-26 21:57:41 +03:00
lzxpress: add bounds checking to lzxpress_decompress()
lzxpress_decompress() would wander past the end of the array in numerous locations. Credit to OSS-Fuzz. BUG: https://bugzilla.samba.org/show_bug.cgi?id=14190 REF: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=19382 REF: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=20083 REF: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=22485 REF: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=22667 Signed-off-by: Stefan Metzmacher <metze@samba.org> Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> Autobuild-User(master): Douglas Bagnall <dbagnall@samba.org> Autobuild-Date(master): Sun Aug 9 00:30:26 UTC 2020 on sn-devel-184
This commit is contained in:
parent
f50987df03
commit
a97c78fb22
@ -252,8 +252,24 @@ ssize_t lzxpress_decompress(const uint8_t *input,
|
||||
offset = 0;
|
||||
nibble_index = 0;
|
||||
|
||||
#define __CHECK_BYTES(__size, __index, __needed) do { \
|
||||
if (unlikely(__index >= __size)) { \
|
||||
return -1; \
|
||||
} else { \
|
||||
uint32_t __avail = __size - __index; \
|
||||
if (unlikely(__needed > __avail)) { \
|
||||
return -1; \
|
||||
} \
|
||||
} \
|
||||
} while(0)
|
||||
#define CHECK_INPUT_BYTES(__needed) \
|
||||
__CHECK_BYTES(input_size, input_index, __needed)
|
||||
#define CHECK_OUTPUT_BYTES(__needed) \
|
||||
__CHECK_BYTES(max_output_size, output_index, __needed)
|
||||
|
||||
do {
|
||||
if (indicator_bit == 0) {
|
||||
CHECK_INPUT_BYTES(4);
|
||||
indicator = PULL_LE_UINT32(input, input_index);
|
||||
input_index += sizeof(uint32_t);
|
||||
indicator_bit = 32;
|
||||
@ -266,10 +282,13 @@ ssize_t lzxpress_decompress(const uint8_t *input,
|
||||
* check whether the 4th bit of the value in indicator is set
|
||||
*/
|
||||
if (((indicator >> indicator_bit) & 1) == 0) {
|
||||
CHECK_INPUT_BYTES(1);
|
||||
CHECK_OUTPUT_BYTES(1);
|
||||
output[output_index] = input[input_index];
|
||||
input_index += sizeof(uint8_t);
|
||||
output_index += sizeof(uint8_t);
|
||||
} else {
|
||||
CHECK_INPUT_BYTES(2);
|
||||
length = PULL_LE_UINT16(input, input_index);
|
||||
input_index += sizeof(uint16_t);
|
||||
offset = length / 8;
|
||||
@ -277,6 +296,7 @@ ssize_t lzxpress_decompress(const uint8_t *input,
|
||||
|
||||
if (length == 7) {
|
||||
if (nibble_index == 0) {
|
||||
CHECK_INPUT_BYTES(1);
|
||||
nibble_index = input_index;
|
||||
length = input[input_index] % 16;
|
||||
input_index += sizeof(uint8_t);
|
||||
@ -286,9 +306,11 @@ ssize_t lzxpress_decompress(const uint8_t *input,
|
||||
}
|
||||
|
||||
if (length == 15) {
|
||||
CHECK_INPUT_BYTES(1);
|
||||
length = input[input_index];
|
||||
input_index += sizeof(uint8_t);
|
||||
if (length == 255) {
|
||||
CHECK_INPUT_BYTES(2);
|
||||
length = PULL_LE_UINT16(input, input_index);
|
||||
input_index += sizeof(uint16_t);
|
||||
length -= (15 + 7);
|
||||
@ -299,10 +321,16 @@ ssize_t lzxpress_decompress(const uint8_t *input,
|
||||
}
|
||||
|
||||
length += 3;
|
||||
if (length == 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (offset >= output_index) {
|
||||
return -1;
|
||||
}
|
||||
CHECK_OUTPUT_BYTES(length);
|
||||
|
||||
do {
|
||||
if ((output_index >= max_output_size) || ((offset + 1) > output_index)) break;
|
||||
|
||||
output[output_index] = output[output_index - offset - 1];
|
||||
|
||||
output_index += sizeof(uint8_t);
|
||||
|
Loading…
x
Reference in New Issue
Block a user