Skip to content
This repository has been archived by the owner on Aug 14, 2023. It is now read-only.

Unowned read/write can access beyond the lifetime of the buffer #5

Closed
hcs64 opened this issue Dec 7, 2018 · 1 comment
Closed

Unowned read/write can access beyond the lifetime of the buffer #5

hcs64 opened this issue Dec 7, 2018 · 1 comment

Comments

@hcs64
Copy link

hcs64 commented Dec 7, 2018

No attempt is made to cancel a pending overlapped operation (e.g. using CancelIoEx) before the buffer it is writing into is dropped.

As an example, try to read from a pipe into a buffer, timeout, the buffer goes away, and later the read finishes. The read will write into the space where the buffer had been.

In the example below function f can run two ways (done this way in order to put another instance of buf in the same place): First it tries to read, which times out. Second it just sleeps, and then asserts that buf hasn't changed.

The events:
Start of first buf lifetime
0ms: Start read
10ms: Read timeout
End of first buf lifetime
10ms+: Begin sleep
100ms: Write from main thread, read writes into first buf which is now second buf
210ms: Check second buf

extern crate named_pipe;

use std::thread;
use std::time::Duration;
use std::io::{ErrorKind, Read, Write};

use named_pipe::{PipeClient, PipeOptions};

fn f(client: &mut PipeClient, first: bool) {
    let mut buf = [0; 10];
    println!("{:?}", &mut buf as *mut _);

    if first {
        let err = client.read(&mut buf).unwrap_err();
        assert_eq!(err.kind(), ErrorKind::TimedOut);
    } else {
        assert_eq!(buf, [0; 10]);
        thread::sleep(Duration::from_millis(100*2));
        assert_eq!(buf, [0; 10]);
    }
}

fn main() {
    let name = r"\\.\pipe\named_pipe_test";
    let server = PipeOptions::new(name).single().unwrap();
    let t1 = thread::spawn(move || {
        let mut client = PipeClient::connect(name).unwrap();
        client.set_read_timeout(Some(Duration::from_millis(10)));

        f(&mut client, true);
        f(&mut client, false);
    });

    thread::sleep(Duration::from_millis(100));
    let mut server = server.wait().unwrap();
    server.write(b"0123456789").unwrap();

    t1.join().unwrap();
}
@blackbeam
Copy link
Owner

Thanks for report.
Fixed in v0.4.0

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants