Skip to content

safe doc(hidden) APIs (async_stream::AsyncStream::new, async_stream::Sender::send, async_stream::pair) allow UB #83

Closed
@ewilden

Description

@ewilden

This playground is an example of invoking UB using only the pub, safe API of this crate (pair(), AsyncStream::new(), and Sender::send()): https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=8cf61ab15c81d7a946cdbf60a1fd4c46

The gist of this is inside of the "generator" passed to AsyncStream::new(receiver, generator), we can construct a Sender, Receiver pair for a different type from the Receiver the AsyncStream is yielding results from. We can use this Sender to send a u8 while generating an AsyncStream, which results in the AsyncStream yielding a String value that causes a segmentation fault when printed.

#[tokio::main(flavor = "current_thread")]
async fn main() {
    let (mut sndstr, mut rcvstr) = pair::<String>();
    let stream = AsyncStream::new(rcvstr, async {
        let (mut sndint, mut rcvint) = pair::<u8>();
        let send_fut = sndint.send(5);
        
        // hack to get tokio to wake again after Send::send
        tokio::select! {
            _ = send_fut => {} 
            _ = async {
                for _ in 1..=10 {
                    tokio::time::sleep(tokio::time::Duration::from_millis(10)).await;
                }
            } => {}
        }
    });
    
    for _ in 1..=10 {
        tokio::time::sleep(tokio::time::Duration::from_millis(10)).await;
    }

    stream.for_each(|item| {
        println!("about to segfault:");
        println!("item: {item:?}");
        futures::future::ready(())
    }).await;
    
    println!("done");
}

I'm not familiar enough with the crate implementation to say which part should be marked unsafe, but I think this shows at least one of (AsyncStream::new, Sender::send, pair) needs to be marked unsafe.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions