Skip to content

&'s T&'static T in safe code (UAF) #132186

Duplicate of#25860
@rucsesec

Description

@rucsesec

I tried this code:

fn static_str_identity()
  -> for<'s> fn(&'s str) -> (
        [&'static &'s (); 0],
        &'static str,
    )
{
    |s: &str| (
        [],
        s,
    )
}

fn main()
{
    let f = static_str_identity();
    let local = String::from("123");
    let s: &'static str = f(&local).1; // <- should be rejected!
    drop(local);
    let _unrelated = String::from("UAF!");
    dbg!(s); // <- compiles and prints `"UAF!"`
}

I expected to see this happen: argument requires that s is borrowed for 'static

Instead, this happened: code compiles successfully and the excution potentially triggers Use-After-Free on the String local.

rogram returned: 0
Program stderr
[/app/example.rs:21:5] s = "UAF!"

This seems very much like a Use-After-Free issue, and it's quite likely related to the compiler.It can be reproduced in the latest version of the Rust compiler.

rustc --version --verbose:

rustc 1.84.0-nightly (c1db4dc24 2024-10-25)

note: This issue appears to be different from #114936, which was related to the Fn* Trait and was fixed in version 1.78; whereas this problem can still trigger a vulnerability in the latest version.

Activity

added
needs-triageThis issue may need triage. Remove it if it has been sufficiently triaged.
on Oct 26, 2024
added
T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.
I-unsoundIssue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/Soundness
T-typesRelevant to the types team, which will review and decide on the PR/issue.
and removed
needs-triageThis issue may need triage. Remove it if it has been sufficiently triaged.
on Oct 26, 2024
added
I-prioritizeIssue: Indicates that prioritization has been requested for this issue.
on Oct 26, 2024
compiler-errors

compiler-errors commented on Oct 26, 2024

@compiler-errors
Member

This is just another instance of #25860.

Subtyping when storing the return value of static_str_identity() causes us to "cast away" implied bounds of the output type of the function. This allows us to turn the signature from ([&'static &'s (); 0], &'static str) to ([&'first &'s (); 0], &'second str), for two other arbitrary existential regions 'first and 'second, with only the requirement that 'static: 'first and 'static: 'second.

Then later, when we check that the signature is well-formed at the call-site (f(&local)), we only require that 's: 'first due to the well-formedness of the [&'first &'s (); 0] argument, but don't do anything for the 'second region. That allows us to later constrain 'second: 'static without actually "linking" it to 's, which is the lifetime of the local string we're passing in.

changed the title [-]&'s T` → &'static T` in safe code (UAF)[/-] [+]`&'s T` → `&'static T` in safe code (UAF)[/+] on Oct 26, 2024
apiraino

apiraino commented on Oct 30, 2024

@apiraino
Contributor

For additional context, T-types is aware of this issue and the current status is summarized at this comment.

@rustbot label -I-prioritize

removed
I-prioritizeIssue: Indicates that prioritization has been requested for this issue.
on Oct 30, 2024
lcnr

lcnr commented on Jan 8, 2025

@lcnr
Contributor

Closing in favor of #25860 which we're slowly working towards. Thank you for finding and reporting this issue 👍

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

Metadata

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/SoundnessT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.T-typesRelevant to the types 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

        Participants

        @compiler-errors@apiraino@lcnr@rustbot@Noratrieb

        Issue actions

          `&'s T` → `&'static T` in safe code (UAF) · Issue #132186 · rust-lang/rust