Summary
I have used afl.rs to fuzz the public APIs of this crate. When calling SliceDeque::as_slices and SliceDeque::as_mut_slices on an empty SliceDeque<i32>, the function triggers a runtime abort due to a violated unsafe precondition inside slice::from_raw_parts and slice::from_raw_parts_mut.
The panic happens inSliceDeque::as_slices and SliceDeque::as_mut_slices , where the empty second slice is constructed from usize::max_value() as *const _. Even for a zero-length slice, slice::from_raw_parts and slice::from_raw_parts_mut requires the pointer to be non-null and properly aligned for T. For T = i32, usize::MAX as *const i32 is not properly aligned.
Reproduction code
extern crate slice_deque;
fn main() {
let mut d = slice_deque::SliceDeque::<i32>::new();
d.push_back(1);
d.push_back(2);
let (left, right) = d.as_slices();
assert_eq!(left, &[1, 2]);
assert_eq!(right, &[]);
}
extern crate slice_deque;
fn main() {
let mut d = slice_deque:: SliceDeque::<i32>::with_capacity(0);
let _ = d.as_mut_slices();
assert_eq!(left, &[]);
assert_eq!(right, &[]);
}
I also placed the replay files at replay_files).
Expected behavior:
should return two valid slices without panicking, aborting, or violating unsafe preconditions.
For the example above, the expected result is:
left == &[1, 2]
right == &[]
Actual behavior for as_slices:
thread 'main' panicked at /Rust-Lib-Testing/test/tests/crates/slice-deque-0.3.0/src/lib.rs:492:17:
unsafe precondition(s) violated: slice::from_raw_parts requires the pointer to be aligned and non-null, and the total size of the slice not to exceed `isize::MAX`
This indicates a bug in the program. This Undefined Behavior check is optional, and cannot be relied on for safety.
stack backtrace:
0: 0x558db501ddf8 - <std::sys::backtrace::BacktraceLock::print::DisplayBacktrace as core::fmt::Display>::fmt::h0f9d2e8e73f1bc7d
1: 0x558db5059183 - core::fmt::write::h2b15537d64ec9505
2: 0x558db504664f - std::io::Write::write_fmt::h7f766131a16fe05a
3: 0x558db501dc43 - std::sys::backtrace::BacktraceLock::print::h5e38585c963961db
4: 0x558db5018a6c - std::panicking::default_hook::{{closure}}::h7a475a2b7b7e4121
5: 0x558db501890d - std::panicking::default_hook::hac0f4b95d0cecbc2
6: 0x558db5018f41 - std::panicking::rust_panic_with_hook::hb51ba0f67890aa28
7: 0x558db501e1a6 - std::panicking::begin_panic_handler::{{closure}}::h73d0277a9a02463b
8: 0x558db501e019 - std::sys::backtrace::__rust_end_short_backtrace::hf93dae6c307b4fe8
9: 0x558db5018b5d - __rustc[b6f6af4e11d2f413]::rust_begin_unwind
10: 0x558db505812d - core::panicking::panic_nounwind_fmt::h102b43c20952100b
11: 0x558db50149e9 - core::slice::raw::from_raw_parts::precondition_check::h73250b4aea4062ac
at /Rust-Lib-Testing/test/src/rust/library/core/src/ub_checks.rs:72:21
12: 0x558db5016137 - core::slice::raw::from_raw_parts::h8e67de28ac319893
at /Rust-Lib-Testing/test/src/rust/library/core/src/ub_checks.rs:77:17
13: 0x558db5015fc0 - slice_deque::SliceDeque<T>::as_slices::hed85916b50ed7650
at /Rust-Lib-Testing/test/tests/crates/slice-deque-0.3.0/src/lib.rs:492:17
14: 0x558db501434c - replay_slice_deque1::main::h2abf81457f189292
at /Rust-Lib-Testing/test/tests/crates/slice-deque-0.3.0/fuzz_target/slice_deque_importance_fuzz/multipleTargets/replay_slice_deque1/src/main.rs:6:27
15: 0x558db5013fab - core::ops::function::FnOnce::call_once::h127d8f7ae5af77f8
at /Rust-Lib-Testing/test/src/rust/library/core/src/ops/function.rs:253:5
16: 0x558db501621e - std::sys::backtrace::__rust_begin_short_backtrace::h09b6bd66fc288ce6
at /Rust-Lib-Testing/test/src/rust/library/std/src/sys/backtrace.rs:158:18
17: 0x558db50161f1 - std::rt::lang_start::{{closure}}::h82f416d938689675
at /Rust-Lib-Testing/test/src/rust/library/std/src/rt.rs:206:18
18: 0x558db5045645 - std::rt::lang_start_internal::h9de2b5630c7cec4d
19: 0x558db50161d7 - std::rt::lang_start::h01ad6e2ad60a32fa
at /Rust-Lib-Testing/test/src/rust/library/std/src/rt.rs:205:5
20: 0x558db501448e - main
21: 0x7fa7814aa083 - __libc_start_main
at /build/glibc-B3wQXB/glibc-2.31/csu/../csu/libc-start.c:308:16
22: 0x558db50136de - _start
23: 0x0 - <unknown>
thread caused non-unwinding panic. aborting.
Aborted
Actual behavior for as_mut_slices:
This also aborts with a similar unsafe precondition violation.
Additional observation:
This behavior depends on the alignment requirement of T.
For example, with T=i8, the same code does not trigger precondition failure, because i8 has alignment 1, and usize::MAX happens to satisfy that alignment requirement.
However, with T=i32, usize::MAX as *const T is not properly aligned, so slice::from_raw_parts and slice::from_raw_parts_mut aborts under Rust's UB checks.
Environment:
slice-deque version: 0.3.0
rustc version: 1.94.1
OS: Ubuntu 20.04.6 LTS
Summary
I have used afl.rs to fuzz the public APIs of this crate. When calling
SliceDeque::as_slicesandSliceDeque::as_mut_sliceson an emptySliceDeque<i32>, the function triggers a runtime abort due to a violated unsafe precondition insideslice::from_raw_partsandslice::from_raw_parts_mut.The panic happens in
SliceDeque::as_slicesandSliceDeque::as_mut_slices, where the empty second slice is constructed fromusize::max_value() as *const _. Even for a zero-length slice,slice::from_raw_partsandslice::from_raw_parts_mutrequires the pointer to be non-null and properly aligned forT. ForT = i32,usize::MAX as *const i32is not properly aligned.Reproduction code
I also placed the replay files at replay_files).
Expected behavior:
should return two valid slices without panicking, aborting, or violating unsafe preconditions.
For the example above, the expected result is:
Actual behavior for
as_slices:Actual behavior for
as_mut_slices:This also aborts with a similar unsafe precondition violation.
Additional observation:
This behavior depends on the alignment requirement of
T.For example, with
T=i8, the same code does not trigger precondition failure, becausei8has alignment1, andusize::MAXhappens to satisfy that alignment requirement.However, with
T=i32,usize::MAX as *const Tis not properly aligned, soslice::from_raw_partsandslice::from_raw_parts_mutaborts under Rust's UB checks.Environment:
slice-deque version: 0.3.0
rustc version: 1.94.1
OS: Ubuntu 20.04.6 LTS