Skip to content

Borrowck regression: allows segfault in 1.27.1 #52213

Closed

Description

@NilSet

The following sample correctly fails to build on stable channel, but erroneously passes on beta and nightly.

It's worth noting that with NLL turned on it also correctly fails to build.

enum Inner {
    Stack {
        data: [u8;23]
    },
    Heap {
        capacity: usize,
        data: *mut u8
    }
}

struct SmallString {
    len: usize,
    inner: Inner
}

impl SmallString {
    fn push_str(&mut self, item: &str) {
        match (&mut self.inner, self.len + item.len()) {
            (Inner::Heap { capacity, ref data }, x) => {
                if x > *capacity {
                    self.grow();
                    // data is now null pointer
                }
                unsafe {
                    ::std::ptr::copy_nonoverlapping(item.as_ptr(), data.add(self.len), item.len())
                }
            },
            _ => ()
        }
    }
    fn grow(&mut self){
        // Invalidate borrowed Heap.data
        self.inner = Inner::Stack { data: [0;23] };
    }
}

Activity

  1. changed the title [-]Borrowck regression: multiple mut borrows[/-] [+]Borrowck regression: allows segfault in safe rust on beta[/+] on Jul 10, 2018
  2. NilSet commented on Jul 10, 2018

    @NilSet
    ContributorAuthor

    Here is an example of being able to segfault in safe rust on beta

    enum Inner {
        Stack {
            data: [u8;23]
        },
        Heap {
            data: Box<[u8]>
        }
    }
    
    struct SmallString {
        len: usize,
        inner: Inner
    }
    
    impl SmallString {
        fn push_str(&mut self, item: &str) {
            match (&mut self.inner, self.len + item.len()) {
                (Inner::Heap { data }, x) => {
                    println!("{}", data.len());
                    if x > data.len() {
                        self.grow();
                        // data is now garbage pointer
                    }
                    println!("{:?}", data);
                },
                _ => ()
            }
        }
        fn grow(&mut self){
            // Invalidate borrowed Heap.data
            self.inner = Inner::Stack { data: [1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1] };
        }
    }
    
    fn main (){
        let slice = "this is gonna go bad".to_owned().into_bytes().into_boxed_slice();
        let mut ss = SmallString { len: slice.len(), inner: Inner::Heap { data: slice } };
        ss.push_str(" right now");
    }

    http://play.rust-lang.org/?gist=e9ebe1460df7a817467ee017de9655dc&version=beta&mode=debug&edition=2015

  3. changed the title [-]Borrowck regression: allows segfault in safe rust on beta[/-] [+]Borrowck regression: allows segfault in 1.27.1[/+] on Jul 10, 2018
  4. NilSet commented on Jul 10, 2018

    @NilSet
    ContributorAuthor

    Turns out this regression is now also in the new patch release on stable!

  5. added
    T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.
    regression-from-stable-to-stablePerformance or correctness regression from one stable version to another.
    I-unsoundIssue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/Soundness
    C-bugCategory: This is a bug.
    on Jul 10, 2018
  6. est31 commented on Jul 10, 2018

    @est31
    Member

    If this can be reproduced on 1.27.1 but can't be reproduced on 1.27.0 (@NilSet said that on IRC), I guess that this regression is caused by #51686 .

  7. kennytm commented on Jul 10, 2018

    @kennytm
    Member
  8. nagisa commented on Jul 10, 2018

    @nagisa
    Member

    @rust-lang/compiler the obligatory ping to all of you.

  9. arielb1 commented on Jul 10, 2018

    @arielb1
    Contributor

    Minified:

    fn transmute_lifetime<'a, 'b, T>(t: &'a (T,)) -> &'b T {
        match (&t, ()) {
            ((t,), ()) => t,
        }
    }
    
    fn main() {
        let x = {
            let y = Box::new((42,));
            transmute_lifetime(&y)
        };
    
        println!("{}", x);
    }
  10. arielb1 commented on Jul 10, 2018

    @arielb1
    Contributor

    Did anyone verify that this reproduces on 1.27.1? I am not sure

  11. arielb1 commented on Jul 10, 2018

    @arielb1
    Contributor

    And now I'm in the state of "how does this ever work", given that cat_pattern is returning Err "correctly".

  12. stephaneyfx commented on Jul 10, 2018

    @stephaneyfx
    Contributor

    @arielb1: Your minified example compiles with 1.27.1, and so does the second example in this thread.

  13. self-assigned this
    on Jul 10, 2018
  14. arielb1 commented on Jul 10, 2018

    @arielb1
    Contributor

    I have a fix up, will push it soon.

  15. added 3 commits that reference this issue on Jul 11, 2018
    05d6e55
    4c04453
    4700e11
  16. added 2 commits that reference this issue on Jul 14, 2018
    52d15f6
    e0e046c
  17. added 2 commits that reference this issue on Jul 18, 2018
    14655a6
    1628b50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

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.regression-from-stable-to-stablePerformance or correctness regression from one stable version to another.

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions