Skip to content

Better "escaping raw pointer" lint #2045

Open

Description

This is supposed to catch cases such as rust-lang/rust#44473.

Raw pointers + destructors interact in an annoying way, where an unaware user can easily create a raw pointer to a value that is invisibly destroyed:

let  pixel_ptr : *const u8 = match pixels {
    image::DecodingResult::U8(v) => v.as_ptr(),
    image::DecodingResult::U16(v) => v.as_ptr() as *const u8,
};

We currently have a lint for CString, but it specifically looks for CString::new(...).unwrap().as_ptr() and can't handle more complicated patterns as the above.

A better version that would also catch this example would be:

When we see a call to an as_ptr-like function on an autoref of a local or temporary, find

  1. the scope of that local or temporary.
  2. the scope the returned value escapes to. I think that heuristically we should just go through "value-preserving" expressions such as match, if and let for that.

And if (2) is larger than (1), the code is definitely guilty of use-after-free (thats it, if it uses the returned raw pointer) and we can lint against it.

This does not try to handle "borrow" conflicts (where the raw pointer is invalidated without going out of scope), and also does not try to track the raw pointer very far:

fn foo() -> *const () {
    let x = vec![];
    let p = x.as_ptr();
    p // We don't try to lint against this for now (but we *could* try to play
       // with it - that analysis could be as complicated as we want it
       // to be, but I suspect it's the "small-scope" cases that are the most confusing).
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

No one assigned

    Labels

    E-hardCall for participation: This a hard problem and requires more experience or effort to work onL-correctnessLint: Belongs in the correctness lint groupT-MIRType: This lint will require working with the MIR

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions