Skip to content

zstd decompression regressions (fuzz test results) #24817

@squeek502

Description

@squeek502

Zig Version

master

Steps to Reproduce and Observed Behavior

These results are just testing for crashes/hangs, not correctness (yet).

zstd-fuzz-20250812-1.zip

Easiest way to reproduce the errors:

  • Clone https://github.com/squeek502/zig-std-lib-fuzzing
  • zig build fuzz-zstandard-debug (no AFL++ required, this just builds the pure Zig version for debugging)
  • ./zig-out/bin/fuzz-zstandard-debug < 'path-to-unzipped-repros/crashes/id:000000,sig:06,src:000000,time:8842,execs:3848,op:ext_UO,pos:0'
    • etc, for the rest of the repros

All the crashes have this stack trace:

thread 753422 panic: access of union field 'in_frame' while field 'skipping_frame' is active
/home/ryan/Programming/zig/zig/lib/std/compress/zstd/Decompress.zig:167:53: 0x1159222 in stream (std.zig)
            return readInFrame(d, w, limit, &d.state.in_frame) catch |err| switch (err) {
                                                    ^
/home/ryan/Programming/zig/zig/lib/std/Io/Reader.zig:178:34: 0x107edbe in stream (std.zig)
    const n = try r.vtable.stream(r, w, limit);
                                 ^
/home/ryan/Programming/zig/zig/lib/std/Io/Reader.zig:257:27: 0x114fb75 in streamRemaining (std.zig)
        offset += r.stream(w, .unlimited) catch |err| switch (err) {
                          ^
/home/ryan/Programming/zig/zig-std-lib-fuzzing/fuzzers/zstandard.zig:27:43: 0x114c95d in zigMain (zstandard.zig)
    _ = zstd_stream.reader.streamRemaining(&out.writer) catch {
                                          ^
/home/ryan/Programming/zig/zig-std-lib-fuzzing/fuzzers/zstandard.zig:4:12: 0x114ce61 in main (zstandard.zig)
    zigMain() catch unreachable;
           ^
/home/ryan/Programming/zig/zig/lib/std/start.zig:618:22: 0x114ac1d in posixCallMainAndExit (std.zig)
            root.main();
                     ^
/home/ryan/Programming/zig/zig/lib/std/start.zig:232:5: 0x114a4b1 in _start (std.zig)
    asm volatile (switch (native_arch) {
    ^
???:?:?: 0x0 in ??? (???)

The hangs seem to be the same as the hangs found with flate in #24741, where there's an infinite loop here:

zig/lib/std/Io/Writer.zig

Lines 381 to 383 in 0d0f09f

while (w.buffer.len - w.end < minimum_length) {
try drainPreserve(w, preserve_len);
} else {

but it's being called from here:

const dest = (try w.writableSliceGreedyPreserve(window_len, frame_block_size_max))[0..frame_block_size_max];

Expected Behavior

No crashes/hangs

Metadata

Metadata

Assignees

Labels

bugObserved behavior contradicts documented or intended behaviorregressionIt worked in a previous version of Zig, but stopped working.standard libraryThis issue involves writing Zig code for the standard library.

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions