lizard
lizard copied to clipboard
Fixed use-of-uninitialized-value MSAN warning in Lizard_decompress_LIZv1
When reading compressed input it is possible to read past the end of the input due to missing check for 2 bytes before the call to MEM_readLE16.
Here is the memory sanitizer warning:
==141574==WARNING: MemorySanitizer: use-of-uninitialized-value
#0 0x4af776 in Lizard_decompress_LIZv1 /home/nathan/Source/lizard/cmake_unofficial/../lib/lizard_decompress_liz.h:166:81
#1 0x4af776 in Lizard_decompress_generic /home/nathan/Source/lizard/lib/lizard_decompress.c:241:19
#2 0x4af776 in Lizard_decompress_safe /home/nathan/Source/lizard/lib/lizard_decompress.c:269:12
#3 0x91bf15 in main /home/nathan/Source/lizard/programs/liztest.c:30:18
#4 0x7ffff7c4b0b2 in __libc_start_main /build/glibc-ZN95T4/glibc-2.31/csu/../csu/libc-start.c:308:16
#5 0x41f29d in _start (/home/nathan/Source/lizard/build/lizardx+0x41f29d)
Uninitialized value was stored to memory at
#0 0x4ad1e9 in Lizard_decompress_LIZv1 /home/nathan/Source/lizard/cmake_unofficial/../lib/lizard_decompress_liz.h:102:26
#1 0x4ad1e9 in Lizard_decompress_generic /home/nathan/Source/lizard/lib/lizard_decompress.c:241:19
#2 0x4ad1e9 in Lizard_decompress_safe /home/nathan/Source/lizard/lib/lizard_decompress.c:269:12
#3 0x91bf15 in main /home/nathan/Source/lizard/programs/liztest.c:30:18
#4 0x7ffff7c4b0b2 in __libc_start_main /build/glibc-ZN95T4/glibc-2.31/csu/../csu/libc-start.c:308:16
Uninitialized value was stored to memory at
#0 0x4acf85 in Lizard_decompress_LIZv1 /home/nathan/Source/lizard/cmake_unofficial/../lib/lizard_decompress_liz.h:100:26
#1 0x4acf85 in Lizard_decompress_generic /home/nathan/Source/lizard/lib/lizard_decompress.c:241:19
#2 0x4acf85 in Lizard_decompress_safe /home/nathan/Source/lizard/lib/lizard_decompress.c:269:12
#3 0x91bf15 in main /home/nathan/Source/lizard/programs/liztest.c:30:18
#4 0x7ffff7c4b0b2 in __libc_start_main /build/glibc-ZN95T4/glibc-2.31/csu/../csu/libc-start.c:308:16
Uninitialized value was stored to memory at
#0 0x583051 in MEM_readLE16 /home/nathan/Source/lizard/cmake_unofficial/../lib/entropy/mem.h:226:9
#1 0x4acf11 in Lizard_decompress_LIZv1 /home/nathan/Source/lizard/cmake_unofficial/../lib/lizard_decompress_liz.h:100:36
#2 0x4acf11 in Lizard_decompress_generic /home/nathan/Source/lizard/lib/lizard_decompress.c:241:19
#3 0x4acf11 in Lizard_decompress_safe /home/nathan/Source/lizard/lib/lizard_decompress.c:269:12
#4 0x91bf15 in main /home/nathan/Source/lizard/programs/liztest.c:30:18
#5 0x7ffff7c4b0b2 in __libc_start_main /build/glibc-ZN95T4/glibc-2.31/csu/../csu/libc-start.c:308:16
Uninitialized value was stored to memory at
#0 0x424e06 in __msan_memcpy (/home/nathan/Source/lizard/build/lizardx+0x424e06)
#1 0x583559 in MEM_read16 /home/nathan/Source/lizard/cmake_unofficial/../lib/entropy/mem.h:146:14
#2 0x582fe5 in MEM_readLE16 /home/nathan/Source/lizard/cmake_unofficial/../lib/entropy/mem.h:226:16
#3 0x4acf11 in Lizard_decompress_LIZv1 /home/nathan/Source/lizard/cmake_unofficial/../lib/lizard_decompress_liz.h:100:36
#4 0x4acf11 in Lizard_decompress_generic /home/nathan/Source/lizard/lib/lizard_decompress.c:241:19
#5 0x4acf11 in Lizard_decompress_safe /home/nathan/Source/lizard/lib/lizard_decompress.c:269:12
#6 0x91bf15 in main /home/nathan/Source/lizard/programs/liztest.c:30:18
#7 0x7ffff7c4b0b2 in __libc_start_main /build/glibc-ZN95T4/glibc-2.31/csu/../csu/libc-start.c:308:16
Uninitialized value was created by a heap allocation
#0 0x42b47d in malloc (/home/nathan/Source/lizard/build/lizardx+0x42b47d)
#1 0x49af7b in Lizard_decompress_generic /home/nathan/Source/lizard/lib/lizard_decompress.c:150:33
#2 0x49af7b in Lizard_decompress_safe /home/nathan/Source/lizard/lib/lizard_decompress.c:269:12
#3 0x91bf15 in main /home/nathan/Source/lizard/programs/liztest.c:30:18
#4 0x7ffff7c4b0b2 in __libc_start_main /build/glibc-ZN95T4/glibc-2.31/csu/../csu/libc-start.c:308:16
SUMMARY: MemorySanitizer: use-of-uninitialized-value /home/nathan/Source/lizard/cmake_unofficial/../lib/lizard_decompress_liz.h:166:81 in Lizard_decompress_LIZv1
Exiting
Here is a sample app that can reproduce it:
#include <stdio.h>
#include <stdlib.h>
#include "lizard_decompress.h"
int main(int argc, const char** argv) {
char output[1024], *input;
int input_size = 0;
if (argc <= 1) {
printf("Missing input file to decompress\n");
return -1;
}
FILE *f = fopen(argv[1], "rb");
fseek(f, 0, SEEK_END);
input_size = ftell(f);
input = (char *)malloc(input_size);
if (input == NULL) {
fclose(f);
return -1;
}
fseek(f, 0, SEEK_SET);
fread(input, input_size, 1, f);
fclose(f);
int length = Lizard_decompress_safe((const char *)input, output,
input_size, sizeof(output));
if (length > 0)
printf("Decompressed bytes %d\n", length);
else
printf("Unexpected error %d\n", length);
return length;
}
Here is the arguments I use when compiling with Clang:
-fsanitize=memory -fsanitize-memory-track-origins=2 -fno-omit-frame-pointer -fno-optimize-sibling-calls -g -O0
Here is the environment variables I use when running:
export MSAN_OPTIONS=print_stacktrace=1:abort_on_error=1
Here is the input file that can be used with the sample app above: https://www.dropbox.com/s/6jatquukhngdxzh/msan.bin?dl=0
Here is the original OSS-fuzz test case, but you won't have access to it. https://oss-fuzz.com/testcase-detail/5673261951877120