Description
Hello,
I have fuzzed dlt-daemon to search for bugs using the Tool CI-Fuzz. I think I found a write heap buffer overflow in the function dlt_buffer_write_block. You can find the full crash report below. This is from a fuzz test I wrote to execute the function dlt_buffer_push with fuzzer generated inputs.
After having a look at the code it seems that there is no size check before writing to the ring buffer: There is no check if size<=buf->size in dlt_buffer_write_block.
As far as I can say this condition isn't checked elsewhere. Since buffer overflows can often be used to get arbitrary code execution this is a potential security issue. Using the dlt_daemon_client_send function a connected dlt user could write into the memory of the daemon and possibly gain arbitrary code execution.
I think this could be fixed by changing the if condition in dlt_common.c:2508 (in function dlt_buffer_push3) into a while loop.
If you need further information or discussion I'm happy to help as far as I can.
==14==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x6260003ec810 at pc 0x000000495890 bp 0x7ffca5a15a50 sp 0x7ffca5a15218
WRITE of size 10006 at 0x6260003ec810 thread T0
#0 0x49588f in __asan_memcpy /llvmbuild/llvm-project-llvmorg-10.0.0/compiler-rt/lib/asan/asan_interceptors_memintrinsics.cpp:22:3
#1 0x7fe86a1c316b in dlt_buffer_write_block /home/user/.local/share/code-intelligence/projects/dlt-daemon-8b34ed1f/libfuzzer/address/src/shared/dlt_common.c:2281:13
#2 0x7fe86a1cf7b9 in dlt_buffer_push3 /home/user/.local/share/code-intelligence/projects/dlt-daemon-8b34ed1f/libfuzzer/address/src/shared/dlt_common.c:2530:9
#3 0x7fe86a1cd2ca in dlt_buffer_push /home/user/.local/share/code-intelligence/projects/dlt-daemon-8b34ed1f/libfuzzer/address/src/shared/dlt_common.c:2460:12
#4 0x4c5cda in LLVMFuzzerTestOneInput /home/user/.local/share/code-intelligence/projects/dlt-daemon-8b34ed1f/libfuzzer/address/.code-intelligence/fuzz_targets/fuzz_dlt_common_dlt_buffer_push.c:81:4
#5 0x4feb61 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) /llvmbuild/llvm-project-llvmorg-10.0.0/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:556:15
#6 0x4fe2a5 in fuzzer::Fuzzer::RunOne(unsigned char const*, unsigned long, bool, fuzzer::InputInfo*, bool*) /llvmbuild/llvm-project-llvmorg-10.0.0/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:470:3
#7 0x500bc7 in fuzzer::Fuzzer::ReadAndExecuteSeedCorpora(std::__Fuzzer::vector<fuzzer::SizedFile, fuzzer::fuzzer_allocatorfuzzer::SizedFile >&) /llvmbuild/llvm-project-llvmorg-10.0.0/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:765:7
#8 0x500f29 in fuzzer::Fuzzer::Loop(std::__Fuzzer::vector<fuzzer::SizedFile, fuzzer::fuzzer_allocatorfuzzer::SizedFile >&) /llvmbuild/llvm-project-llvmorg-10.0.0/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:792:3
#9 0x4efbee in fuzzer::FuzzerDriver(int*, char***, int ()(unsigned char const, unsigned long)) /llvmbuild/llvm-project-llvmorg-10.0.0/compiler-rt/lib/fuzzer/FuzzerDriver.cpp:829:6
#10 0x518a22 in main /llvmbuild/llvm-project-llvmorg-10.0.0/compiler-rt/lib/fuzzer/FuzzerMain.cpp:19:10
#11 0x7fe869bb00b2 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x270b2)
#12 0x41de5d in _start (/projects/dlt-daemon-8b34ed1f/libfuzzer/address/fuzz_dlt_common_dlt_buffer_push+0x41de5d)
0x6260003ec810 is located 0 bytes to the right of 10000-byte region [0x6260003ea100,0x6260003ec810)
allocated by thread T0 here:
#0 0x49638d in malloc /llvmbuild/llvm-project-llvmorg-10.0.0/compiler-rt/lib/asan/asan_malloc_linux.cpp:145:3
#1 0x7fe86a1c5f2e in dlt_buffer_increase_size /home/user/.local/share/code-intelligence/projects/dlt-daemon-8b34ed1f/libfuzzer/address/src/shared/dlt_common.c:2344:15
#2 0x7fe86a1cec2f in dlt_buffer_push3 /home/user/.local/share/code-intelligence/projects/dlt-daemon-8b34ed1f/libfuzzer/address/src/shared/dlt_common.c:2510:13
#3 0x7fe86a1cd2ca in dlt_buffer_push /home/user/.local/share/code-intelligence/projects/dlt-daemon-8b34ed1f/libfuzzer/address/src/shared/dlt_common.c:2460:12
#4 0x4c5cda in LLVMFuzzerTestOneInput /home/user/.local/share/code-intelligence/projects/dlt-daemon-8b34ed1f/libfuzzer/address/.code-intelligence/fuzz_targets/fuzz_dlt_common_dlt_buffer_push.c:81:4
#5 0x4feb61 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) /llvmbuild/llvm-project-llvmorg-10.0.0/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:556:15
#6 0x4fe2a5 in fuzzer::Fuzzer::RunOne(unsigned char const*, unsigned long, bool, fuzzer::InputInfo*, bool*) /llvmbuild/llvm-project-llvmorg-10.0.0/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:470:3
#7 0x500bc7 in fuzzer::Fuzzer::ReadAndExecuteSeedCorpora(std::__Fuzzer::vector<fuzzer::SizedFile, fuzzer::fuzzer_allocatorfuzzer::SizedFile >&) /llvmbuild/llvm-project-llvmorg-10.0.0/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:765:7
#8 0x500f29 in fuzzer::Fuzzer::Loop(std::__Fuzzer::vector<fuzzer::SizedFile, fuzzer::fuzzer_allocatorfuzzer::SizedFile >&) /llvmbuild/llvm-project-llvmorg-10.0.0/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:792:3
#9 0x4efbee in fuzzer::FuzzerDriver(int*, char***, int ()(unsigned char const, unsigned long)) /llvmbuild/llvm-project-llvmorg-10.0.0/compiler-rt/lib/fuzzer/FuzzerDriver.cpp:829:6
#10 0x518a22 in main /llvmbuild/llvm-project-llvmorg-10.0.0/compiler-rt/lib/fuzzer/FuzzerMain.cpp:19:10
#11 0x7fe869bb00b2 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x270b2)
SUMMARY: AddressSanitizer: heap-buffer-overflow /llvmbuild/llvm-project-llvmorg-10.0.0/compiler-rt/lib/asan/asan_interceptors_memintrinsics.cpp:22:3 in __asan_memcpy
Shadow bytes around the buggy address:
0x0c4c800758b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c4c800758c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c4c800758d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c4c800758e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c4c800758f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0c4c80075900: 00 00[fa]fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c4c80075910: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c4c80075920: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c4c80075930: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c4c80075940: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c4c80075950: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
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
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
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
Shadow gap: cc
==14==ABORTING
MS: 0 ; base unit: 0000000000000000000000000000000000000000
artifact_prefix='./'; Test unit written to ./crash-0dc6c277a5b5996e2eb49350577026f1820bb1e7