Skip to content

Hang when iterating over frames of a malformed file #101

@ghost

Description

I added a cargo-fuzz target that is

#![no_main]
use libfuzzer_sys::fuzz_target;

fuzz_target!(|data: &[u8]| {
    let mut options = gif::DecodeOptions::new();

    options.set_color_output(gif::ColorOutput::RGBA);

    if let Ok(mut decoder) = options.read_info(data) {
        while let Ok(Some(_frame)) = decoder.read_next_frame() {
        }
    }
});

(Adapted from the sample code in the README.md)

And it finds a hang on this input image (as base64): R0lGODlhRxpH/wAAACwBAAAAAAAAJ/hGOAAAAQAA/7k4//9GSQQAOA==

Stack trace for the timeout is

==544106== ERROR: libFuzzer: timeout after 17 seconds
    #0 0x561b58a0c9b1 in __sanitizer_print_stack_trace /rustc/llvm/src/llvm-project/compiler-rt/lib/asan/asan_stack.cpp:86:3
    #1 0x561b58b068d8 in fuzzer::PrintStackTrace() (/home/jess/.cache/cargo/target/x86_64-unknown-linux-gnu/release/fuzz_target_1+0x1d08d8)
    #2 0x561b58adfbec in fuzzer::Fuzzer::AlarmCallback() (/home/jess/.cache/cargo/target/x86_64-unknown-linux-gnu/release/fuzz_target_1+0x1a9bec)
    #3 0x7fec7a3ff95f  (/usr/lib/libpthread.so.0+0x1395f)
    #4 0x561b58b0ecc2 in __sanitizer_cov_trace_const_cmp8 (/home/jess/.cache/cargo/target/x86_64-unknown-linux-gnu/release/fuzz_target_1+0x1d8cc2)
    #5 0x561b58a77a84 in gif::reader::decoder::StreamingDecoder::next_state::h44d629585299e184 (/home/jess/.cache/cargo/target/x86_64-unknown-linux-gnu/release/fuzz_target_1+0x141a84)
    #6 0x561b58a76fc2 in gif::reader::decoder::StreamingDecoder::update::h9ed2772a3dc85324 (/home/jess/.cache/cargo/target/x86_64-unknown-linux-gnu/release/fuzz_target_1+0x140fc2)
    #7 0x561b58a3c073 in gif::reader::ReadDecoder$LT$R$GT$::decode_next::h1114d2de4e62b2e9 (/home/jess/.cache/cargo/target/x86_64-unknown-linux-gnu/release/fuzz_target_1+0x106073)
    #8 0x561b58a38c1d in gif::reader::Decoder$LT$R$GT$::next_frame_info::hb31d57863e0746d8 (/home/jess/.cache/cargo/target/x86_64-unknown-linux-gnu/release/fuzz_target_1+0x102c1d)
    #9 0x561b58a39b90 in gif::reader::Decoder$LT$R$GT$::read_next_frame::h5c70ecc82dab9c00 (/home/jess/.cache/cargo/target/x86_64-unknown-linux-gnu/release/fuzz_target_1+0x103b90)
    #10 0x561b58a4fab4 in rust_fuzzer_test_input (/home/jess/.cache/cargo/target/x86_64-unknown-linux-gnu/release/fuzz_target_1+0x119ab4)
    #11 0x561b58ae9a30 in __rust_try (/home/jess/.cache/cargo/target/x86_64-unknown-linux-gnu/release/fuzz_target_1+0x1b3a30)
    #12 0x561b58ae968f in LLVMFuzzerTestOneInput (/home/jess/.cache/cargo/target/x86_64-unknown-linux-gnu/release/fuzz_target_1+0x1b368f)
    #13 0x561b58adfee4 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) (/home/jess/.cache/cargo/target/x86_64-unknown-linux-gnu/release/fuzz_target_1+0x1a9ee4)
    #14 0x561b58ad43fa in fuzzer::RunOneTest(fuzzer::Fuzzer*, char const*, unsigned long) (/home/jess/.cache/cargo/target/x86_64-unknown-linux-gnu/release/fuzz_target_1+0x19e3fa)
    #15 0x561b58ad8396 in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) (/home/jess/.cache/cargo/target/x86_64-unknown-linux-gnu/release/fuzz_target_1+0x1a2396)
    #16 0x561b58988462 in main (/home/jess/.cache/cargo/target/x86_64-unknown-linux-gnu/release/fuzz_target_1+0x52462)
    #17 0x7fec7a0f8b24 in __libc_start_main (/usr/lib/libc.so.6+0x27b24)
    #18 0x561b5898860d in _start (/home/jess/.cache/cargo/target/x86_64-unknown-linux-gnu/release/fuzz_target_1+0x5260

A test program that reproduces the issue without the loop:

fn main() {
    let input = b"GIF89aG\x1aG\xff\x00\x00\x00,\x01\x00\x00\x00\x00\x00\x00\'\xf8F8\x00\x00\x01\x00\x00\xff\xb98\xff\xffFI\x04\x008";

    let mut options = gif::DecodeOptions::new();

    options.set_color_output(gif::ColorOutput::RGBA);

    if let Ok(mut decoder) = options.read_info(&input[..]) {
        decoder.read_next_frame();
        decoder.read_next_frame();
    }
}

(It hangs on the second .read_next_frame();)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions