Package: libmad0 Version: latest
I found a security vulnerability in libmad, I could not contact the vendor so I figured I'd just send it to you guys as it's a dependency for a lot of packages (At Least 68). A heap overflow or heap overrun is a type of buffer overflow that occurs in the heap data area. Heap overflows are exploitable in a different manner to that of stack-based overflows. Memory on the heap is dynamically allocated by the application at run-time and typically contains program data. Exploitation is performed by corrupting this data in specific ways to cause the application to overwrite internal structures such as linked list pointers. The canonical heap overflow technique overwrites dynamic memory allocation linkage (such as malloc meta data) and uses the resulting pointer exchange to overwrite a program function pointer. An accidental overflow may result in data corruption or unexpected behavior by any process which uses the affected memory area. A deliberate exploit may result in data at a specific location being altered in an arbitrary way, or in arbitrary code being executed The vulnerability in this case takes place in the mad_bit_read() function in libmad. The issue was found whilst fuzzing the library. In the attachments you can find the reproducer and the ASAN crash log and the harness, on Ubuntu atleast 68 packages are dependant on libmad so I think the amount of affected packages will be similar on Debian. Kind Regards, Jordy Zomer
#include <unistd.h> #include <stdint.h> #include "mad.h" struct buffer { unsigned char const *start; unsigned long length; }; static enum mad_flow input(void *data, struct mad_stream *stream) { struct buffer *buffer = (struct buffer*) data; if (!buffer->length) return MAD_FLOW_STOP; mad_stream_buffer(stream, buffer->start, buffer->length); buffer->length = 0; return MAD_FLOW_CONTINUE; } extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { struct buffer buffer; struct mad_decoder decoder; /* initialize our private message structure */ buffer.start = Data; buffer.length = Size; /* configure input, output, and error functions */ mad_decoder_init(&decoder, &buffer, input, 0 /* header */, 0 /* filter */, 0 /* output */, 0, 0 /* message */); /* start decoding */ mad_decoder_run(&decoder, MAD_DECODER_MODE_SYNC); /* release the decoder */ mad_decoder_finish(&decoder); return 0; }
libmad-heap-buffer-overflow-c53-f36-c2d.repro
Description: Binary data
INFO: Seed: 977723447 INFO: Loaded 0 modules (0 guards): Loading corpus dir: /samples/ Loaded 1024/1222 files from /samples/ #0 READ units: 1222 #1222 INITED cov: 1305 bits: 7362 indir: 7 corp: 614/523Kb exec/s: 611 rss: 98Mb ================================================================= ==19511==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x61700004083c at pc 0x7f3b040c9c2e bp 0x7ffcf1a68cb0 sp 0x7ffcf1a68ca8 READ of size 1 at 0x61700004083c thread T0 #0 0x7f3b040c9c2d in mad_bit_read (/usr/lib/libmad.so.0+0x7c2d) #1 0x7f3b040f2f36 in II_samples (/usr/lib/libmad.so.0+0x30f36) #2 0x7f3b040f1c53 in mad_layer_II (/usr/lib/libmad.so.0+0x2fc53) #3 0x7f3b040d86c4 in mad_frame_decode (/usr/lib/libmad.so.0+0x166c4) #4 0x7f3b040e6e4b in run_sync (/usr/lib/libmad.so.0+0x24e4b) #5 0x7f3b040e5a9e in mad_decoder_run (/usr/lib/libmad.so.0+0x23a9e) #6 0x50e2bd in LLVMFuzzerTestOneInput (/src/libmad-0.15.1b/libmad-fuzzer+0x50e2bd) #7 0x4f85f4 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) /src/Fuzzer/FuzzerLoop.cpp:536:13 #8 0x4f87e4 in fuzzer::Fuzzer::RunOne(unsigned char const*, unsigned long) /src/Fuzzer/FuzzerLoop.cpp:488:3 #9 0x4f98ce in fuzzer::Fuzzer::MutateAndTestOne() /src/Fuzzer/FuzzerLoop.cpp:722:30 #10 0x4f9ae7 in fuzzer::Fuzzer::Loop() /src/Fuzzer/FuzzerLoop.cpp:755:5 #11 0x4f1ca4 in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) /src/Fuzzer/FuzzerDriver.cpp:530:3 #12 0x4ef6f0 in main /src/Fuzzer/FuzzerMain.cpp:20:10 #13 0x7f3b02e4f82f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f) #14 0x41b258 in _start (/src/libmad-0.15.1b/libmad-fuzzer+0x41b258) 0x61700004083c is located 0 bytes to the right of 700-byte region [0x617000040580,0x61700004083c) allocated by thread T0 here: #0 0x4ecad0 in operator new[](unsigned long) (/src/libmad-0.15.1b/libmad-fuzzer+0x4ecad0) #1 0x4f8537 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) /src/Fuzzer/FuzzerLoop.cpp:527:23 SUMMARY: AddressSanitizer: heap-buffer-overflow (/usr/lib/libmad.so.0+0x7c2d) in mad_bit_read Shadow bytes around the buggy address: 0x0c2e800000b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0c2e800000c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0c2e800000d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0c2e800000e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0c2e800000f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 =>0x0c2e80000100: 00 00 00 00 00 00 00[04]fa fa fa fa fa fa fa fa 0x0c2e80000110: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c2e80000120: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd 0x0c2e80000130: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd 0x0c2e80000140: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd 0x0c2e80000150: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd Shadow byte legend (one shadow byte represents 8 application bytes): Addressable: 00 Partially addressable: 01 02 03 04 05 06 07 Heap left redzone: fa Heap right redzone: fb Freed heap region: fd Stack left redzone: f1 Stack mid redzone: f2 Stack right redzone: f3 Stack partial redzone: f4 Stack after return: f5 Stack use after scope: f8 Global redzone: f9 Global init order: f6 Poisoned by user: f7 Container overflow: fc Array cookie: ac Intra object redzone: bb ASan internal: fe Left alloca redzone: ca Right alloca redzone: cb ==19511==ABORTING MS: 2 InsertRepeatedBytes-EraseBytes-; base unit: 234b027de6de12cc0f7e8ee194e36d17ec01412e artifact_prefix='./'; Test unit written to /dev/shm/repro-file