Skip to content

Possible unsound unsafe usages #3

Description

@charlesxsh
pub struct StackVec<A: Array> {
    // The capacity field is used for iteration and other optimizations.
    // Publicly expose the fields, so they may be used in constant
    // initialization.
    pub data: mem::MaybeUninit<A>,
    pub length: usize,
}
impl<A: Array> StackVec<A> {
...
pub fn remove(&mut self, index: usize) -> A::Item {
        assert!(index < self.len());
        unsafe {
            self.length -= 1;
            let ptr = self.as_mut_ptr().padd(index);
            let item = ptr::read(ptr);
            ptr::copy(ptr.offset(1), ptr, self.length - index);
            item
        }
    }
...
}

variable StackVec::length is dangerous to be public. For example, asserts in StackVec::remove will become useless if length is set larger than capacity. It will violate many safety requirements of functions like pointer add, offset, write, and copy (which means might have out of bound access and other memory issues). Similar things happened on StackVec::pop, StackVec::truncate.

References:
https://doc.rust-lang.org/std/primitive.pointer.html#method.write
https://doc.rust-lang.org/std/primitive.pointer.html#method.offset

Metadata

Metadata

Assignees

Labels

A-securitySecurity/unsoundness issues.bugSomething isn't working

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions