Skip to content

Assignments leave their place partially-destroyed if the destructor panics #30380

Description

@arielb1

STR

struct Bomb;
struct Observer<'a>(&'a mut (String, Bomb));

impl Drop for Bomb {
    fn drop(&mut self) {
        panic!("panicking destructors ftw!");
    }
}

impl<'a> Drop for Observer<'a> {
    fn drop(&mut self) {
        let _spray = "0wned".to_owned();
        println!("{}", &self.0 .0);
    }
}

fn foo(b: &mut Observer) {
    *b.0 = ("~".to_owned(), Bomb);
}

fn main() {
    let mut bomb = ("clear".to_owned(), Bomb);
    let mut observer = Observer(&mut bomb);
    foo(&mut observer);
}

Results

The assignment to *b.0 within foo calls the drop-glue for the value inside. The new tuple ("~", Bomb) is created, and then the drop glue for the old value of b is executed. It first frees the original string, and then attempts to calls Bomb's destructor. As the latter destructor panics, the function unwinds without storing a value in the place of the missing String, leaving a &mut reference that points to an invalid value, which can later be observed by a destructor or recover.

Fixes

The new value for the destination is available the whole time - the panic handler can just write it in.

Activity

  1. added
    T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.
    on Dec 14, 2015
  2. pnkfelix commented on Dec 14, 2015

    @pnkfelix
    Contributor

    cc me

  3. arielb1 commented on Dec 14, 2015

    @arielb1
    ContributorAuthor

    It must be noted that the assigned location is supposed to be borrowed mutably while the drop glue is called, so underhanded tricks used by the drop-glue to get a reference to that location (e.g. #30228, which led to the discovery of this issue) are just aliasing-UB.

  4. nikomatsakis commented on Dec 15, 2015

    @nikomatsakis
    Contributor

    cc me.

  5. self-assigned this
    on Dec 17, 2015
  6. pnkfelix commented on Dec 17, 2015

    @pnkfelix
    Contributor

    triage: P-medium

  7. arielb1 commented on May 12, 2016

    @arielb1
    ContributorAuthor

    This is causing problems to my non-zeroing-drop work.

  8. 6 remaining items

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

Metadata

Metadata

Assignees

Labels

A-destructorsArea: Destructors (`Drop`, …)I-unsoundIssue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/SoundnessP-mediumMedium priorityT-compilerRelevant to the compiler 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

    Issue actions