After following the instructions here I compiled zstd with clang-5 and UBSan on Debian 9 x64 and started fuzzing with stream_round_trip. This error is the result:
./stream_round_trip ./crash-0b4920ed8d4e81b93b613e3938ff593a5e0bcd2a
INFO: Seed: 2370722290
INFO: Loaded 1 modules (11932 guards): [0x81b660, 0x8270d0),
./stream_round_trip: Running 1 inputs 1 time(s) each.
Running: ./crash-0b4920ed8d4e81b93b613e3938ff593a5e0bcd2a
==18592== ERROR: libFuzzer: deadly signal
#0 0x4c6e37 in __sanitizer_print_stack_trace (/root/zstd/tests/fuzz/stream_round_trip+0x4c6e37)
#1 0x5bd471 in fuzzer::Fuzzer::CrashCallback() /root/zstd/tests/fuzz/./Fuzzer/FuzzerLoop.cpp:195:5
#2 0x5bd43d in fuzzer::Fuzzer::StaticCrashSignalCallback() /root/zstd/tests/fuzz/./Fuzzer/FuzzerLoop.cpp:179:6
#3 0x7f837fe3f0bf (/lib/x86_64-linux-gnu/libpthread.so.0+0x110bf)
#4 0x53e091 in ZSTD_compressContinue_internal /root/zstd/tests/fuzz/../../lib/compress/zstd_compress.c:2978:20
#5 0x5407ea in ZSTD_compressEnd /root/zstd/tests/fuzz/../../lib/compress/zstd_compress.c:3310:26
#6 0x546e04 in ZSTD_compressStream_generic /root/zstd/tests/fuzz/../../lib/compress/zstd_compress.c:3809:38
#7 0x54850d in ZSTD_endStream /root/zstd/tests/fuzz/../../lib/compress/zstd_compress.c:4018:5
#8 0x5b218e in compress /root/zstd/tests/fuzz/stream_round_trip.c:80:30
#9 0x5b218e in LLVMFuzzerTestOneInput /root/zstd/tests/fuzz/stream_round_trip.c:140
#10 0x5be2b4 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) /root/zstd/tests/fuzz/./Fuzzer/FuzzerLoop.cpp:460:13
#11 0x5be523 in fuzzer::Fuzzer::RunOne(unsigned char const*, unsigned long) /root/zstd/tests/fuzz/./Fuzzer/FuzzerLoop.cpp:399:3
#12 0x5b2ce1 in fuzzer::RunOneTest(fuzzer::Fuzzer*, char const*, unsigned long) /root/zstd/tests/fuzz/./Fuzzer/FuzzerDriver.cpp:268:6
#13 0x5b6bf4 in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) /root/zstd/tests/fuzz/./Fuzzer/FuzzerDriver.cpp:683:9
#14 0x5b2a50 in main /root/zstd/tests/fuzz/./Fuzzer/FuzzerMain.cpp:20:10
#15 0x7f837f48c2b0 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x202b0)
#16 0x41f2f9 in _start (/root/zstd/tests/fuzz/stream_round_trip+0x41f2f9)
NOTE: libFuzzer has rudimentary signal handlers.
Combine libFuzzer with AddressSanitizer or similar for better crash reports.
SUMMARY: libFuzzer: deadly signal
Thread 1 "stream_round_tr" received signal SIGILL, Illegal instruction.
0x000000000053e092 in ZSTD_compressContinue_internal
(cctx=<optimized out>, dst=0x6160000006e8, dstCapacity=384, src=0x0, srcSize=<optimized out>, frame=1, lastFrameChunk=<optimized out>) at ../../lib/compress/zstd_compress.c:2978
2978 cctx->base -= delta;
(gdb) bt
#0 0x000000000053e092 in ZSTD_compressContinue_internal (cctx=<optimized out>, dst=0x6160000006e8, dstCapacity=384, src=0x0, srcSize=<optimized out>, frame=1, lastFrameChunk=<optimized out>) at ../../lib/compress/zstd_compress.c:2978
#1 0x00000000005407eb in ZSTD_compressEnd (cctx=0x617000000080, dst=0x6160000006e2, dstCapacity=390, src=0x10007fff7e00, srcSize=2415882239) at ../../lib/compress/zstd_compress.c:3310
#2 0x0000000000546e05 in ZSTD_compressStream_generic (zcs=<optimized out>, output=<optimized out>, input=<optimized out>, flushMode=<optimized out>) at ../../lib/compress/zstd_compress.c:3809
#3 0x000000000054850e in ZSTD_endStream (zcs=0x617000000080, output=0x7fffffffc800) at ../../lib/compress/zstd_compress.c:4018
#4 0x00000000005b218f in compress (dst=0x6160000006e2 "(\265", <incomplete sequence \375>, capacity=486, src=<optimized out>, srcSize=6) at stream_round_trip.c:80
#5 LLVMFuzzerTestOneInput (src=<optimized out>, size=<optimized out>) at stream_round_trip.c:140
#6 0x00000000005be2b5 in fuzzer::Fuzzer::ExecuteCallback (this=0x614000000040, Data=0x611000000040 "(\265/\375d\a\016e*", Size=229) at ./Fuzzer/FuzzerLoop.cpp:460
#7 0x00000000005be524 in fuzzer::Fuzzer::RunOne (this=0x614000000040, Data=0x611000000040 "(\265/\375d\a\016e*", Size=17594333494784) at ./Fuzzer/FuzzerLoop.cpp:399
#8 0x00000000005b2ce2 in fuzzer::RunOneTest (F=0x614000000040, InputFilePath=0x604000000110 "crash-0b4920ed8d4e81b93b613e3938ff593a5e0bcd2a", MaxLen=<optimized out>) at ./Fuzzer/FuzzerDriver.cpp:268
#9 0x00000000005b6bf5 in fuzzer::FuzzerDriver (argc=<optimized out>, argv=<optimized out>, Callback=0x5b1c80 <LLVMFuzzerTestOneInput>) at ./Fuzzer/FuzzerDriver.cpp:683
#10 0x00000000005b2a51 in main (argc=2, argv=0x7fffffffe278) at ./Fuzzer/FuzzerMain.cpp:20
(gdb) list
2973 /* not contiguous */
2974 ptrdiff_t const delta = cctx->nextSrc - ip;
2975 cctx->lowLimit = cctx->dictLimit;
2976 cctx->dictLimit = (U32)(cctx->nextSrc - cctx->base);
2977 cctx->dictBase = cctx->base;
2978 cctx->base -= delta;
2979 cctx->nextToUpdate = cctx->dictLimit;
2980 if (cctx->dictLimit - cctx->lowLimit < HASH_READ_SIZE) cctx->lowLimit = cctx->dictLimit; /* too small extDict */
2981 }
2982
(gdb) i r
rax 0x10007fff7600 17594333492736
rbx 0x100 256
rcx 0x10007fff7e00 17594333494784
rdx 0x10007fff7e00 17594333494784
rsi 0x0 0
rdi 0x0 0
rbp 0x7fffffffc4d0 0x7fffffffc4d0
rsp 0x7fffffffc370 0x7fffffffc370
r8 0x8fff6fff 2415882239
r9 0x0 0
r10 0x100 256
r11 0x617000000088 107133664231560
r12 0x61700000009c 107133664231580
r13 0xc2e00000013 13391708028947
r14 0xc2e00000010 13391708028944
r15 0x0 0
rip 0x53e092 0x53e092 <ZSTD_compressContinue_internal+5746>
eflags 0x10206 [ PF IF RF ]
cs 0x33 51
ss 0x2b 43
ds 0x0 0
es 0x0 0
fs 0x0 0
gs 0x0 0
cc @terrelln
I'm not sure why the SIGILL occurs, but on clang-5 you need to need to compile with -fno-sanitize=pointer-overflow, because the computations with cctx->base can underflow. I'll add it to the documentation.
When I build with -O2 -fno-omit-frame-pointer -g -fsanitize=address,undefined -fsanitize-coverage=trace-pc-guard -fno-sanitize=pointer-overflow I still see this happening:
./stream_round_trip crash-65b151ca798cc7e33dbbc059d767e6570017c668
INFO: Seed: 1847299958
INFO: Loaded 1 modules (11932 guards): [0x81b660, 0x8270d0),
./stream_round_trip: Running 1 inputs 1 time(s) each.
Running: crash-65b151ca798cc7e33dbbc059d767e6570017c668
==24757== ERROR: libFuzzer: deadly signal
#0 0x4c6e37 in __sanitizer_print_stack_trace (/root/zstd/tests/fuzz/stream_round_trip+0x4c6e37)
#1 0x5bd49c in fuzzer::Fuzzer::CrashCallback() /root/test/Fuzzer/FuzzerLoop.cpp:195:5
#2 0x5bd46a in fuzzer::Fuzzer::StaticCrashSignalCallback() /root/test/Fuzzer/FuzzerLoop.cpp:179:6
#3 0x7f085b7400bf (/lib/x86_64-linux-gnu/libpthread.so.0+0x110bf)
#4 0x53e091 in ZSTD_compressContinue_internal /root/zstd/tests/fuzz/../../lib/compress/zstd_compress.c:2978:20
#5 0x5407ea in ZSTD_compressEnd /root/zstd/tests/fuzz/../../lib/compress/zstd_compress.c:3310:26
#6 0x546e04 in ZSTD_compressStream_generic /root/zstd/tests/fuzz/../../lib/compress/zstd_compress.c:3809:38
#7 0x54850d in ZSTD_endStream /root/zstd/tests/fuzz/../../lib/compress/zstd_compress.c:4018:5
#8 0x5b218e in compress /root/zstd/tests/fuzz/stream_round_trip.c:80:30
#9 0x5b218e in LLVMFuzzerTestOneInput /root/zstd/tests/fuzz/stream_round_trip.c:140
#10 0x5be2ea in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) /root/test/Fuzzer/FuzzerLoop.cpp:460:13
#11 0x5be551 in fuzzer::Fuzzer::RunOne(unsigned char const*, unsigned long) /root/test/Fuzzer/FuzzerLoop.cpp:399:3
#12 0x5b2ceb in fuzzer::RunOneTest(fuzzer::Fuzzer*, char const*, unsigned long) /root/test/Fuzzer/FuzzerDriver.cpp:268:6
#13 0x5b6e5f in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) /root/test/Fuzzer/FuzzerDriver.cpp:683:9
#14 0x5b2a50 in main /root/test/Fuzzer/FuzzerMain.cpp:20:10
#15 0x7f085ad8d2b0 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x202b0)
#16 0x41f2f9 in _start (/root/zstd/tests/fuzz/stream_round_trip+0x41f2f9)
NOTE: libFuzzer has rudimentary signal handlers.
Combine libFuzzer with AddressSanitizer or similar for better crash reports.
SUMMARY: libFuzzer: deadly signal
/third_party/llvm-build/Release+Asserts/bin/clang --version
clang version 5.0.0 (trunk 305735)
Target: x86_64-unknown-linux-gnu
Thread model: posix
InstalledDir: /third_party/llvm-build/Release+Asserts/bin
Registered Targets:
aarch64 - AArch64 (little endian)
aarch64_be - AArch64 (big endian)
amdgcn - AMD GCN GPUs
arm - ARM
arm64 - ARM64 (little endian)
armeb - ARM (big endian)
bpf - BPF (host endian)
bpfeb - BPF (big endian)
bpfel - BPF (little endian)
hexagon - Hexagon
lanai - Lanai
mips - Mips
mips64 - Mips64 [experimental]
mips64el - Mips64el [experimental]
mipsel - Mipsel
msp430 - MSP430 [experimental]
nvptx - NVIDIA PTX 32-bit
nvptx64 - NVIDIA PTX 64-bit
ppc32 - PowerPC 32
ppc64 - PowerPC 64
ppc64le - PowerPC 64 LE
r600 - AMD GPUs HD2XXX-HD6XXX
riscv32 - 32-bit RISC-V
riscv64 - 64-bit RISC-V
sparc - Sparc
sparcel - Sparc LE
sparcv9 - Sparc V9
systemz - SystemZ
thumb - Thumb
thumbeb - Thumb (big endian)
x86 - 32-bit X86: Pentium-Pro and above
x86-64 - 64-bit X86: EM64T and AMD64
xcore - XCore
Which I get via
git clone https://chromium.googlesource.com/chromium/src/tools/clang
clang/scripts/update.py
I'll try with the Chromium clang tomorrow, but I couldn't reproduce it on Centos 7 x86_64 with clang-5.0 with these flags.
-DZSTD_DEBUG=1 -DMEM_FORCE_MEMORY_ACCESS=0 -DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION -g -fno-omit-frame-pointer -g -fsanitize=undefined -fno-sanitize=pointer-overflow
clang version 5.0.0
Target: x86_64-unknown-linux-gnu
Thread model: posix
InstalledDir: /home/terrelln/bin
Registered Targets:
bpf - BPF (host endian)
bpfeb - BPF (big endian)
bpfel - BPF (little endian)
nvptx - NVIDIA PTX 32-bit
nvptx64 - NVIDIA PTX 64-bit
x86 - 32-bit X86: Pentium-Pro and above
x86-64 - 64-bit X86: EM64T and AMD64
Can you reproduce the SIGILL without UBSan enabled?
My previous comment was my bad, had too many windows open, didn't make clean in the right spot. It appears as though the SIGILL does goes away with these flags after all:
-O2 -fno-omit-frame-pointer -g -fsanitize=address,undefined -fsanitize-coverage=trace-pc-guard -fno-sanitize=pointer-overflow
Most helpful comment
My previous comment was my bad, had too many windows open, didn't
make cleanin the right spot. It appears as though the SIGILL does goes away with these flags after all:-O2 -fno-omit-frame-pointer -g -fsanitize=address,undefined -fsanitize-coverage=trace-pc-guard -fno-sanitize=pointer-overflow