Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Undefined behavior in ZSTD_decompress for certain inputs #3506

Open
squeek502 opened this issue Feb 14, 2023 · 0 comments
Open

Undefined behavior in ZSTD_decompress for certain inputs #3506

squeek502 opened this issue Feb 14, 2023 · 0 comments
Assignees

Comments

@squeek502
Copy link

squeek502 commented Feb 14, 2023

Describe the bug
When compiled with clang and -fsanitize=undefined, ZSTD_decompress will hit undefined behavior with certain inputs:

/decompress/zstd_decompress_block.c:1696:45: runtime error: applying non-zero offset 79823856 to null pointer

To Reproduce

  1. Inputs that trigger the UB: zstd-non-zero-offset-inputs.zip (found when fuzzing a Zig implementation of a zstd decompressor)
  2. Compile zstd with clang via make lib CFLAGS="-fsanitize=undefined -fPIC"
  3. Compile examples with make LDFLAGS="-fsanitize=undefined"
  4. Run one of the inputs through simple_decompression, e.g. ./simple_decompression 'id:000032,sig:06,src:000673,time:3423388,execs:797038,op:havoc,rep:2'

Example of the output with DEBUGLEVEL=10

.//decompress/zstd_decompress.c: ZSTD_getFrameHeader_advanced: minInputSize = 5, srcSize = 39 
.//decompress/zstd_decompress.c: ZSTD_decompressMultiFrame 
.//decompress/zstd_decompress.c: reading magic number FD2FB528 (expecting FD2FB528) 
.//decompress/zstd_decompress.c: ZSTD_decompressFrame (srcSize:39) 
.//decompress/zstd_decompress.c: ZSTD_getFrameHeader_advanced: minInputSize = 5, srcSize = 9 
.//decompress/zstd_decompress_block.c: ZSTD_decompressBlock_internal (size : 20) 
.//decompress/zstd_decompress_block.c: ZSTD_decodeLiteralsBlock 
.//decompress/zstd_decompress_block.c: ZSTD_decodeLiteralsBlock : cSize=1, nbLiterals=0 
.//decompress/zstd_decompress_block.c: ZSTD_decodeSeqHeaders 
.//decompress/zstd_decompress_block.c: ZSTD_getLongOffsetsShare: (tableLog=5) 
.//decompress/zstd_decompress_block.c: ZSTD_decompressSequencesLong 
.//decompress/zstd_decompress_block.c: ZSTD_initFseState : val=5 using 5 bits 
.//decompress/zstd_decompress_block.c: ZSTD_initFseState : val=24 using 5 bits 
.//decompress/zstd_decompress_block.c: ZSTD_initFseState : val=0 using 0 bits 
.//decompress/zstd_decompress_block.c: seq: litL=0, matchL=3, offset=8 
/decompress/zstd_decompress_block.c:1696:45: runtime error: applying non-zero offset 94193544721696 to null pointer
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior /decompress/zstd_decompress_block.c:1696:45 in 
.//decompress/zstd_decompress_block.c: seq: litL=2, matchL=3, offset=1 
.//decompress/zstd_decompress_block.c: seq: litL=0, matchL=3, offset=4 
.//decompress/zstd_decompress_block.c: seq: litL=0, matchL=3, offset=8 
.//decompress/zstd_decompress_block.c: seq: litL=0, matchL=3, offset=2 
.//decompress/zstd_decompress_block.c: seq: litL=0, matchL=3, offset=4 
.//decompress/zstd_decompress_block.c: seq: litL=0, matchL=3, offset=8 
.//decompress/zstd_decompress_block.c: seq: litL=0, matchL=3, offset=2 
.//decompress/zstd_decompress_block.c: seq: litL=2, matchL=3, offset=8 
.//decompress/zstd_decompress_block.c:884: ERROR!: check sequenceLength > (size_t)(oend - op) failed, returning ERROR(dstSize_tooSmall): last match must fit within dstBuffer
simple_decompression.c:40 CHECK(!ZSTD_isError(err)) failed: Destination buffer is too small

Expected behavior
No UB

Desktop:

  • OS: Linux
  • Compiler clang

Additional context

UB does not happen with the streaming_decompression example for these inputs.

Related issues: #2110, #3236

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants