-
Notifications
You must be signed in to change notification settings - Fork 681
Description
This happens when I do some fuzzing with AFL++.
Expected
I suppose we don't want to panic
Actual behaviour
I was doing fuzzing with AFL++ using this wrapper. And I found this error: source slice length (1548) does not match destination slice length (774). Here is the stacktrace:
#0 0x00007ffff7c7700b in raise () from /lib/x86_64-linux-gnu/libc.so.6
#1 0x00007ffff7c56859 in abort () from /lib/x86_64-linux-gnu/libc.so.6
#2 0x0000555555695d77 in panic_abort::__rust_start_panic::abort () at /rustc/270c94e484e19764a2832ef918c95224eb3f17c7/library/panic_abort/src/lib.rs:42
#3 0x0000555555695d66 in panic_abort::__rust_start_panic () at /rustc/270c94e484e19764a2832ef918c95224eb3f17c7/library/panic_abort/src/lib.rs:37
#4 0x000055555568a76c in std::panicking::rust_panic () at /rustc/270c94e484e19764a2832ef918c95224eb3f17c7/library/std/src/panicking.rs:736
#5 0x000055555568a61a in std::panicking::rust_panic_with_hook () at /rustc/270c94e484e19764a2832ef918c95224eb3f17c7/library/std/src/panicking.rs:706,
#6 0x000055555568a359 in std::panicking::begin_panic_handler::{closure#0} () at /rustc/270c94e484e19764a2832ef918c95224eb3f17c7/library/std/src/panicking.rs:579",
#7 0x0000555555688fec in std::sys_common::backtrace::__rust_end_short_backtrace<std::panicking::begin_panic_handler::{closure_env#0}, !> () at /rustc/270c94e484e19764a2832ef918c95224eb3f17c7/library/std/src/sys_common/backtrace.rs:137
#8 0x000055555568a062 in std::panicking::begin_panic_handler () at /rustc/270c94e484e19764a2832ef918c95224eb3f17c7/library/std/src/panicking.rs:575
#9 0x0000555555579f43 in core::panicking::panic_fmt () at /rustc/270c94e484e19764a2832ef918c95224eb3f17c7/library/core/src/panicking.rs:64
#10 0x000055555557a4d2 in core::slice::{impl#0}::copy_from_slice::len_mismatch_fail () at /rustc/270c94e484e19764a2832ef918c95224eb3f17c7/library/core/src/slice/mod.rs:3289
#11 0x00005555555dbe95 in core::slice::{impl#0}::copy_from_slice<u8> (self=..., src=...) at /rustc/270c94e484e19764a2832ef918c95224eb3f17c7/library/core/src/slice/mod.rs:3296
#12 image::codecs::jpeg::decoder::{impl#2}::read_image<std::io::cursor::Cursor<&[u8]>> (self=..., buf=...) at /image/src/codecs/jpeg/decoder.rs:115
#13 0x00005555555f31cf in image::image::decoder_to_vec<u8, image::codecs::jpeg::decoder::JpegDecoder<std::io::cursor::Cursor<&[u8]>>> (decoder=...) at /image/src/image.rs:608
#14 0x00005555555d8f9d in image::dynimage::decoder_to_image<image::codecs::jpeg::decoder::JpegDecoder<std::io::cursor::Cursor<&[u8]>>> (decoder=...) at /image/src/dynimage.rs:1030
#15 image::dynimage::DynamicImage::from_decoder<image::codecs::jpeg::decoder::JpegDecoder<std::io::cursor::Cursor<&[u8]>>> (decoder=...) at /image/src/dynimage.rs:177
#16 0x00005555555e3147 in image::io::free_functions::load_inner::{impl#0}::visit_decoder<image::codecs::jpeg::decoder::JpegDecoder<std::io::cursor::Cursor<&[u8]>>> (decoder=..., self=<error reading variable: Cannot access memory at address 0x10>) at /image/src/io/free_functions.rs:109
#17 image::io::free_functions::load_decoder<std::io::cursor::Cursor<&[u8]>, image::io::free_functions::load_inner::LoadVisitor> (format=<optimized out>, limits=..., r=..., visitor=<error reading variable: Cannot access memory at address 0x10>) at /image/src/io/free_functions.rs:61
#18 image::io::free_functions::load_inner<std::io::cursor::Cursor<&[u8]>> (limits=..., format=<optimized out>, r=...) at /image/src/io/free_functions.rs:113
#19 image::io::free_functions::load<std::io::cursor::Cursor<&[u8]>> (r=..., format=<optimized out>) at /image/src/io/free_functions.rs:37
#20 0x00005555555d41a9 in image::dynimage::load_from_memory_with_format () at /image/src/dynimage.rs:1215
#21 sydr_script_jpeg::main () at /image/fuzz/fuzzers/sydr_script_jpeg.rs:15
I've also done a small investigation. As we could see crash is occurred at decoder.rs:115. But before we've got a vector with wrong size at decoder.rs:109. This buffer is constructed here:
let mut decoded: Vec<u16> =
vec![0u16; ncomp * output_size.width as usize * output_size.height as usize];some gdb output at this point:
(gdb) p ncomp
$4 = 3
(gdb) p frame.output_size
$5 = jpeg_decoder::parser::Dimensions {width: 86, height: 3}
We could see here that decoded.len() is equal to 774, but it has Vec<u16> type. So, after conversion to Vec<u8> here we've got the wrong 1548 size of buffer . Maybe we could add some size checks to in read_image for that? I could do a PR.
Reproduction steps
If you want to reproduce this, I could provide a crash input and you could follow this instructions.