DroplessArena::alloc_raw does not check for wraparound when computing the end of the allocation, pointer arithmetic using self.ptr and bytes:
|
pub fn alloc_raw(&self, bytes: usize, align: usize) -> &mut [u8] { |
|
unsafe { |
|
assert!(bytes != 0); |
|
|
|
self.align(align); |
|
|
|
let future_end = intrinsics::arith_offset(self.ptr.get(), bytes as isize); |
|
if (future_end as *mut u8) >= self.end.get() { |
|
self.grow(bytes); |
|
} |
This can be used to make the pointer wrap around, and "allocate", bumping the pointer, without growing the underlying allocation.
Callers alloc and alloc_slice can possibly be argued to be safe due to practical size limits on values and slices, but at least alloc_from_iter can be used to trigger this bug and write out of bounds of an allocation.
Fixes to make
- Check arithmetic and ensure the allocation can fit into the current (or any) chunk
(Suggested) cleanups to make
- The arith_offset intrinsic is the same thing as
<*mut T>::wrapping_add, and the method should be preferred.
alloc_raw should return something else than &mut [u8], because the contents of the slice are uninit. For example a raw slice or a slice of MaybeUninit.
This came up in discussion in PR #72417
DroplessArena::alloc_raw does not check for wraparound when computing the end of the allocation, pointer arithmetic using
self.ptrandbytes:rust/src/libarena/lib.rs
Lines 382 to 391 in aeca4d6
This can be used to make the pointer wrap around, and "allocate", bumping the pointer, without growing the underlying allocation.
Callers
allocandalloc_slicecan possibly be argued to be safe due to practical size limits on values and slices, but at leastalloc_from_itercan be used to trigger this bug and write out of bounds of an allocation.Fixes to make
(Suggested) cleanups to make
<*mut T>::wrapping_add, and the method should be preferred.alloc_rawshould return something else than&mut [u8], because the contents of the slice are uninit. For example a raw slice or a slice ofMaybeUninit.This came up in discussion in PR #72417