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

Implementing a trait allows changing lifetime requirements, leading to memory corruption #35730

Closed
alexcrichton opened this issue Aug 16, 2016 · 2 comments
Labels
I-unsound Issue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/Soundness T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@alexcrichton
Copy link
Member

This code snipped, when compiled locally on OSX segfaults on stable (1.10.0) and exhibits memory corruption on nightly:

use std::fmt;

#[derive(Debug)]
struct MyString<'a>(&'a String);

struct B {
    list: Vec<Box<fmt::Debug>>,
}

trait A<'a> {
    fn foo<F>(&mut self, f: F)
        where F: fmt::Debug + 'a,
              Self: Sized;
}

impl<'a> A<'a> for B {
    fn foo<F>(&mut self, f: F)
        where F: fmt::Debug + 'static, // note that this is 'static, not 'a
    {
        self.list.push(Box::new(f));
    }
}

fn main() {
    let mut b = B { list: Vec::new() };

    // Create a borrowed pointer, put it in `b`, then drop what's borrowing it
    let a = "hello".to_string();
    b.foo(MyString(&a));

    // Drop the data which `b` has a reference to
    drop(a);

    // Use the data, probably segfaulting
    for b in b.list.iter() {
        println!("{:?}", b);
    }
}

I believe the issue here is that the implementation of the A trait allows application of the 'static bound, enabling the implementation of that function to assume that. The trait, however, uses the 'a bound. When calling this function we can then feed in non-'static lifetimes and wind up corrupting data.

cc @nikomatsakis
cc @arielb1
cc @rust-lang/compiler

@alexcrichton alexcrichton added I-nominated T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. I-unsound Issue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/Soundness labels Aug 16, 2016
@apasel422
Copy link
Contributor

Is this related to #18937?

@alexcrichton
Copy link
Member Author

Aha indeed! Appears to be a dupe of that. I'll close and add a comment over there.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
I-unsound Issue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/Soundness T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

2 participants