Skip to content

Functions, closures, and HRTB-trait-objects can implement traits such that validity of associated types is never checked. #84533

Description

edit: while this issue has been mostly fixed by #115538, the underlying issue still exists for higher ranked function pointers. It feels highly likely that it can still be exploited, even if the exploit will now be even more involved.


Make sure to also read through the next few comments of mine, where I present some other, significantly different examples of related problems (that’s where HRTBs become relevant, and closures, fn-pointers and trait objects play a role). I also explain the T-lang tag there with a question on changing the meaning of HRTBs that include associated types. Possibly it’s even a sensible thing to split this issue up into two issues.

So if I write a function such as

fn foo<'b, 'a>() -> PhantomData<&'b &'a ()> {
    PhantomData
}

then foo’s return type is only valid if 'a: 'b. When we call the function this is enforced a the call site, e.g.

fn caller<'b, 'a>() {
    foo::<'b, 'a>();
}

doesn’t work, with

error[E0491]: in type `&'b &'a ()`, reference has a longer lifetime than the data it references
 --> src/lib.rs:8:5
  |
8 |     foo::<'b, 'a>();
  |     ^^^^^^^^^^^^^^^
  |
note: the pointer is valid for the lifetime `'b` as defined on the function body at 7:11
 --> src/lib.rs:7:11
  |
7 | fn caller<'b, 'a>() {
  |           ^^
note: but the referenced data is only valid for the lifetime `'a` as defined on the function body at 7:15
 --> src/lib.rs:7:15
  |
7 | fn caller<'b, 'a>() {
  |               ^^

error: aborting due to previous error

(playground)

However, if we just instantiate the lifetime parameters, there’s apparently no check being performed at all, i.e.

fn caller<'b, 'a>() {
    foo::<'b, 'a>;
}

compiles just fine. (playground).

This seems questionable, the type of foo::<'b, 'a> implements FnOnce with Output = PhantomData<&'b &'a ()>, and it is in fact possible to use this output type to circumvent the borrow checker:

use std::marker::PhantomData;

fn foo<'b, 'a>() -> PhantomData<&'b &'a ()> {
    PhantomData
}

fn extend_lifetime<'a, 'b, T: ?Sized>(x: &'a T) -> &'b T {
    let f = foo::<'b, 'a>;
    f.baz(x)
}

trait Foo<'a, 'b, T: ?Sized> {
    fn baz(self, s: &'a T) -> &'b T;
}
impl<'a, 'b, R, F, T: ?Sized> Foo<'a, 'b, T> for F
where
    F: Fn() -> R,
    R: ProofForConversion<'a, 'b, T>,
{
    fn baz(self, s: &'a T) -> &'b T {
        self().convert(s)
    }
}

trait ProofForConversion<'a, 'b, T: ?Sized> {
    fn convert(self, s: &'a T) -> &'b T;
}
impl<'a, 'b, T: ?Sized> ProofForConversion<'a, 'b, T> for PhantomData<&'b &'a ()> {
    fn convert(self, s: &'a T) -> &'b T {
        s
    }
}

fn main() {
    let d;
    {
        let x = "Hello World".to_string();
        d = extend_lifetime(&x);
    }
    println!("{}", d);
}
�ZV&�V�

(playground)

@rustbot modify labels: A-lifetimes, A-typesystem, T-compiler
and someone please add “I-unsound 💥”.

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

Metadata

Assignees

No one assigned

    Labels

    A-DSTsArea: Dynamically-sized types (DSTs)A-associated-itemsArea: Associated items (types, constants & functions)A-closuresArea: Closures (`|…| { … }`)A-higher-rankedArea: Higher-ranked things (e.g., lifetimes, types, trait bounds aka HRTBs)A-lifetimesArea: Lifetimes / regionsA-traitsArea: Trait systemA-typesystemArea: The type systemC-bugCategory: This is a bug.I-unsoundIssue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/SoundnessP-mediumMedium priorityS-bug-has-testStatus: This bug is tracked inside the repo by a `known-bug` test.T-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

    • Status

      new solver everywhere

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions