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

Hang when iterating over frames of a malformed file #101

Closed
5225225 opened this issue Mar 22, 2021 · 0 comments · Fixed by #116
Closed

Hang when iterating over frames of a malformed file #101

5225225 opened this issue Mar 22, 2021 · 0 comments · Fixed by #116

Comments

@5225225
Copy link

5225225 commented Mar 22, 2021

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();)

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

Successfully merging a pull request may close this issue.

1 participant