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

Dead objects resurrected by finalizer are incorrectly deallocated #124

Open
andersk opened this issue Jan 26, 2021 · 0 comments
Open

Dead objects resurrected by finalizer are incorrectly deallocated #124

andersk opened this issue Jan 26, 2021 · 0 comments
Labels

Comments

@andersk
Copy link
Collaborator

andersk commented Jan 26, 2021

The program below uses a finalizer to resurrect a dead object by linking it back to a root. force_collect deallocates the object anyway, leading to use after free.

It looks like this check was intended to address this problem:

rust-gc/gc/src/gc.rs

Lines 198 to 200 in e459223

if (*node.this.as_ptr()).header.marked.get() {
continue;
}

Unfortunately, the marked bit is always clear except in the middle of mark, so this check is always false.

Reproduction:

use gc::{force_collect, Finalize, Gc, GcCell, Trace};

#[derive(Finalize, Trace)]
struct Foo {
    bar: GcCell<Option<Gc<Bar>>>,
}

#[derive(Trace)]
struct Bar {
    string: String,
    foo: Gc<Foo>,
    this: GcCell<Option<Gc<Bar>>>,
}

impl Finalize for Bar {
    fn finalize(&self) {
        *self.foo.bar.borrow_mut() = self.this.borrow().clone();
    }
}

fn main() {
    let foo = Gc::new(Foo {
        bar: GcCell::new(None),
    });
    let bar = Gc::new(Bar {
        string: "Hello, world!".to_string(),
        foo: foo.clone(),
        this: GcCell::new(None),
    });
    *bar.this.borrow_mut() = Some(bar.clone());
    drop(bar);
    force_collect();
    println!("{:?}", foo.bar.borrow().as_ref().unwrap().string);
}

This outputs garbage like

"\u{0}-��\u{55000}\u{4}\u{0}\u{0}\u{0}\u{0}"

or

thread 'main' panicked at 'byte index 2 is not a char boundary; it is inside '-' (bytes 1..2) of `-��V`', library/core/src/fmt/mod.rs:2064:30
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
"\u{0}
andersk added a commit to andersk/rust-gc that referenced this issue Oct 17, 2022
andersk added a commit to andersk/rust-gc that referenced this issue Oct 17, 2022
@andersk andersk added the bug label Dec 19, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant