Skip to content

Box syntax and generator_clone can lead to double free #105084

Closed
@cjgillot

Description

@cjgillot

I tried this code:

#![feature(generators)]
#![feature(generator_clone)]
#![feature(generator_trait)]
#![feature(box_syntax)]

use std::pin::Pin;
use std::ops::Generator;

fn copy<T: Copy>(x: T) -> T { x }

fn main() {
    let mut g = || {
        // This is desuraged as 4 stages:
        // - allocate a `*mut u8` with `exchange_malloc`;
        // - create a Box that is ignored for trait computations;
        // - compute fields (and yields);
        // - assign to `t`.
        let t = box (5, yield);
        drop(t);
    };
    // Allocate the temporary box.
    Pin::new(&mut g).resume(());
    // The temporary box is in generator locals.
    // As it is not taken into account for trait computation,
    // the generator is `Copy`.
    let mut h = copy(g);
    // We now have 2 boxes with the same backing allocation:
    // one inside `g` and one inside `h`.
    // Proceed and drop `t` in `g`.
    Pin::new(&mut g).resume(());
    // Proceed and drop `t` in `h` -> double free!
    Pin::new(&mut h).resume(());
}

Playground

I expected to see this happen: compilation fails.

Instead, this happened: double free

   Compiling playground v0.0.1 (/playground)
    Finished dev [unoptimized + debuginfo] target(s) in 0.68s
     Running `target/debug/playground`
free(): double free detected in tcache 2
timeout: the monitored command dumped core

Note: if we do not resume the generators after the copy, we get a memory leak.

Meta

rustc version: tested on playground nightly on 2022-11-30.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-coroutinesArea: CoroutinesC-bugCategory: This is a bug.F-coroutine_clone`#![feature(coroutine_clone)]`F-coroutines`#![feature(coroutines)]`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.requires-nightlyThis issue requires a nightly compiler in some way.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions