Skip to content

Borrowed pointers in destructors enable use-after-free crashes #3167

Description

@bblum

This struct has a borrowed pointer to another one of itself. By making it mutable, I can build a cycle, and then no matter the order that the destructors run, the second one will segfault because the first one's id will have been freed.

This is sort of related to #3164, and more closely related to #3039.

Probably accessing mutable &-pointers in destructors should be unsafe. If they are immutable, it should be impossible to build a cycle.

struct oops {
    mut a: option<&oops>;
    id: ~~str;
    new(+a: option<&oops>, +id: ~~str) {
        self.a = a; self.id = id; 
    }   
    drop {
        do self.a.iter |nbr| {
            #error["Me: %?; Neighbour: %?", self.id, nbr.id];
        }   
    }   
}

fn main() {
    let x = oops(none, ~~"x");
    let y = oops(some(&x), ~~"y");
    x.a = some(&y);
}

Activity

  1. bblum commented on Sep 6, 2012

    @bblum
    ContributorAuthor

    It occurs to me I could also abuse the cycle collector to cause even immutable borrowed pointers to escape their lifetimes. Build a cycle of @-boxes with a borrowed pointer to a thing in it, don't refer to the cycle after the thing gets freed, but the cycle is not collected until later, at which point if the destructors access it it's a use-after-free.

  2. catamorphism commented on Mar 29, 2013

    @catamorphism
    Contributor

    Blocked on #4301 -- de-milestoning.

  3. thestinger commented on Mar 29, 2013

    @thestinger
    Contributor

    d4fee24 limited destructors to Owned types, so this is disallowed now.

  4. added a commit that references this issue on Nov 17, 2023
  5. added a commit that references this issue on Aug 21, 2026
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

    A-destructorsArea: Destructors (`Drop`, …)A-lifetimesArea: Lifetimes / regionsI-crashIssue: The compiler crashes (SIGSEGV, SIGABRT, etc). Use I-ICE instead when the compiler panics.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions