You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Layout::new and Layout::contiguous_with_offset accept an arbitrary start_offset value without any validation. Downstream unsafe code in cpu_backend::utils::unary_map unconditionally trusts this offset via get_unchecked, resulting in out-of-bounds memory access. This is a soundness bug: undefined behavior is reachable without writing any unsafe code.
Confirmed on 0.11.0
Root Cause
The Layout type stores a start_offset: usize field that determines where element access begins within a backing storage buffer. The two public constructors accept any start_offset without validation:
Once a Layout is constructed with a valid start_offset, all derived operations (narrow, transpose, permute, broadcast_as) preserve the invariant that start_offset stays within bounds — narrow's start + len <= dims[dim] check guarantees the new offset cannot overflow given a valid initial state. The bug is therefore entirely in the constructors: they are the sole entry point for an invalid start_offset.
PoC
#[test]fnpoc_layout_unchecked_offset_oob(){use candle_core::backend::BackendStorage;use candle_core::cpu_backend::CpuStorage;use candle_core::Layout;// Step 1: Create a layout with start_offset = usize::MAX.// Layout::contiguous_with_offset accepts this without any validation.let layout = Layout::contiguous_with_offset(&[4usize,3usize], usize::MAX);// Step 2: narrow(dim=1, start=0, len=1)// New offset: usize::MAX + stride[1] * 0 = usize::MAX (unchanged).let layout = layout.narrow(1,0,1).unwrap();// Step 3: Trigger OOB read via elu().// unary_map → get_unchecked(usize::MAX + ...) → heap-buffer-overflowlet storage = CpuStorage::F32(vec![0.5f32;20]);let _result = storage.elu(&layout,1.0);}
Reachable from safe Rust through public API: Layout::contiguous_with_offset → Layout::narrow → any unary/binary storage operation (elu, relu, gelu, cos, sin, etc.).
Activity