Skip to content

ReadTicket and WriteTicket should only be sendable when T is Send #7

Closed
@ammaraskar

Description

@ammaraskar

Hi there, we (Rust group @sslab-gatech) are scanning crates on crates.io for potential soundness bugs. We noticed that ReadTicket

unsafe impl<T> Send for ReadTicket<T> {}

and WriteTicket

unsafe impl<T> Send for WriteTicket<T> {}

implement Send for all types T. However, this should probably be bounded by T: Send, otherwise it allows smuggling non-Send types across thread boundaries. Here's an example of a data race with Rcs that segfaults safe Rust code:

#![forbid(unsafe_code)]

use ticketed_lock::TicketedLock;

use futures::Future;
use std::{rc::Rc, thread};

fn main() {
    let rc = Rc::new(());
    let rc_clone = rc.clone();
    
    let mut lock = TicketedLock::new(rc_clone);

    let read_ticket = lock.read();
    thread::spawn(move || {
        let smuggled_rc = read_ticket.wait().unwrap();

        println!("Thread: {:p}", *smuggled_rc);
        // Race the refcount with the main thread.
        for _ in 0..100_000_000 {
            smuggled_rc.clone();
        }
    });

    println!("Main:   {:p}", rc);
    for _ in 0..100_000_000 {
        rc.clone();
    }
}

This outputs:

Main:   0x55998cf48a50
Thread: 0x55998cf48a50

Return Code: -4 (SIGILL)

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions