Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Better documentation needed: reentrancy through the panic hook #505

Open
RalfJung opened this issue Apr 17, 2024 · 3 comments
Open

Better documentation needed: reentrancy through the panic hook #505

RalfJung opened this issue Apr 17, 2024 · 3 comments

Comments

@RalfJung
Copy link
Member

RalfJung commented Apr 17, 2024

The following function may seem sound:

fn definitely_safe(b: bool) {
    static mut S: i32 = 0;
    
    struct Bomb<'a>(&'a mut i32);
    impl<'a> Drop for Bomb<'a> {
        fn drop(&mut self) {
            *self.0 = 42;
        }
    }
    
    // SAEFTY: we're not creating a second reference while
    // this one is live.
    let _bomb = Bomb(unsafe { &mut *ptr::addr_of_mut!(S) });
    if b {
        panic!("Oopsie, something went wrong!");
    }
}

But actually it is not. The panic can call arbitrary user-defined code via a panic hook, and that can do a reentrant call do definitely_safe, and then we have UB.

I don't think there is any way to say that definitely_safe is sound, so the main question is -- how to we raise awareness of this reentrancy issue so that unsafe code authors don't stumble into it?

@RalfJung
Copy link
Member Author

RalfJung commented Apr 17, 2024

I wonder if swc-project/swc#8362 can be turned into an unsoundness on stable via a custom panic hook.

EDIT: I was not able to find any way to make that code panic, other than via allocation failure. But if/when allocation failure can lead to a panic, then this definitely becomes an unsoundness.

@RalfJung
Copy link
Member Author

RalfJung commented Apr 22, 2024

@rust-lang/libs-api @rust-lang/lang I wonder what your take on this is -- do crates in general have to consider every panic as a possible point of reentrancy? That seems really hard to reason about as panics can occur in a lot of places. It's also unclear what the alternative is though, since panic::set_hook is stable. (Making that hook require a Send closure is something that could have helped here, but it's probably too late for that. It's also kind of a hack.)

Also note the related #506 -- if allocation or allocation failure can lead to a panic, then every allocation site also necessarily has to be considered a possible point of reentrancy (i.e., a point where arbitrary safe code is executed, including code that may call back into the current library -- even for !Sync types).

@nikomatsakis
Copy link
Contributor

nikomatsakis commented Apr 22, 2024 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants