Skip to content

Missing wraparound checks in DroplessArena allocation #72624

Closed

Description

DroplessArena::alloc_raw does not check for wraparound when computing the end of the allocation, pointer arithmetic using self.ptr and bytes:

rust/src/libarena/lib.rs

Lines 382 to 391 in aeca4d6

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

  1. Check arithmetic and ensure the allocation can fit into the current (or any) chunk

(Suggested) cleanups to make

  1. The arith_offset intrinsic is the same thing as <*mut T>::wrapping_add, and the method should be preferred.
  2. 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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

No one assigned

    Labels

    C-bugCategory: This is a bug.I-unsoundIssue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/SoundnessP-mediumMedium priorityT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.T-libsRelevant to the library team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions