Skip to content

Potential RefCell unsafety due to mem::forget #25841

Closed
@Veedrac

Description

@Veedrac

I don't have a 32-bit computer to test on, but I suspect that this will overflow RefCell's counter on 32 bit builds:

let overflower = RefCell::new(());
for _ in 0u64..4294967296 {
    std::mem::forget(overflower.borrow());
}

This can allow shared mutable pointers. I imagine similar problems hold for Rc and co. and I imagine the problem also happens on 64 bit builds if you have it running for a few hundred years.

This is what made me think of the problem:

// Values [1, MAX-1] represent the number of `Ref` active
// (will not outgrow its range since `usize` is the size of the address space)

But this isn't true if memory can be reclaimed without the destructors running (I think).


To fix it you just need to use saturating addition since only leaks can allow this to happen, and once you've leaked in this way you can't ever hope to run all the destructors anyway. (Actually, this isn't strictly true if you allow for compressed storage.)

Metadata

Metadata

Assignees

No one assigned

    Labels

    I-unsoundIssue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/SoundnessT-libs-apiRelevant to the library API 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