Skip to content

Callback handling contains UB and may lead to use-after-free #9

Open
@jasonyu1996

Description

@jasonyu1996

ConfigBuilder::with_callback receives an owned cb the address of which is assigned to cfg.decode.context.

cfg.decode.context = &mut cb as *mut _ as *mut c_void;

The callback is later invoked in decode_callback.

let (res, bytes) = c(&(&*cfg).into(), pos);

However, cb only lives until the end of with_callback. This can lead to use-after-free, as demonstrated by this test case below:

#[test]
fn test_bad_callback() {
    let mut data = [18; 3];
    let c = {
        let counter = [1, 2, 3, 4, 5, 6, 7, 8];
        ConfigBuilder::with_callback(
            &mut data,
            move |c, p| {
            assert_eq!(counter, [1, 2, 3, 4, 5, 6, 7, 8]); // counter points to freed memory
            (Unknown::new(c.0.cpu.model + p[0]), 1) })
    }.unwrap().finish();
    unsafe {
        let mut ukn: pt_packet_unknown = std::mem::zeroed();
        let _ = c.0.decode.callback.unwrap()(&mut ukn,
                                         c.0.as_ref(), c.0.begin,
                                         c.0.decode.context);
    }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions