-
-
Notifications
You must be signed in to change notification settings - Fork 2.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Race leads to panic in oneshot::Sender::send()
#4225
Comments
Signed-off-by: Eliza Weisman <eliza@buoyant.io>
i threw together a quick Loom test based on your repro that appears to fail with a causality violation: https://github.com/tokio-rs/tokio/compare/eliza/oneshot-race?expand=1 Test output
I am fairly sure this is the same race condition; |
I think this may also deserve the |
I mean, yes, it is a race. Races are unsound. |
Yup. Modifying the repro to send a string through the channel and actually mutate/dereference it results in a more or less instantaneous segfault: #[tokio::main]
async fn main() {
loop {
let (tx, mut rx) = tokio::sync::oneshot::channel();
tokio::spawn(async move {
if let Err(mut s) = tx.send(String::from("hello")) {
s.push_str(" world");
assert_eq!(&s[..], "hello world");
}
});
tokio::spawn(async move {
rx.close();
if let Ok(mut s) = rx.try_recv() {
s.push_str(" san francisco");
assert_eq!(&s[..], "hello san francisco");
}
});
}
} A few runs with various amusingly mangled strings I got it to produce: :# eliza at noctis in adam-repro on main [?] is 📦 v0.1.0 via ⚙️ v1.56.1
:; time cargo run --release
Compiling adam-repro v0.1.0 (/home/eliza/Code/adam-repro)
Finished release [optimized] target(s) in 0.91s
Running `target/release/adam-repro`
thread 'tokio-runtime-worker' panicked at 'byte index 1 is not a char boundary; it is inside '\u{10}' (bytes 0..1) of `&�sa��sco`', library/core/src/fmt/mod.rs:2133:30
stack backtrace:
zsh: segmentation fault (core dumped) cargo run --release
cargo run --release 2.30s user 0.24s system 219% cpu 1.157 total
:# eliza at noctis in adam-repro on main [?] is 📦 v0.1.0 via ⚙️ v1.56.1
:; time cargo run --release
Finished release [optimized] target(s) in 0.01s
Running `target/release/adam-repro`
thread 'tokio-runtime-worker' panicked at 'assertion failed: `(left == right)`
left: `"�C~\u{0} francisco"`,
right: `"hello san francisco"`', src/main.rs:15:17
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
zsh: segmentation fault (core dumped) cargo run --release
cargo run --release 0.19s user 0.08s system 108% cpu 0.245 total
:# eliza at noctis in adam-repro on main [?] is 📦 v0.1.0 via ⚙️ v1.56.1
:; time cargo run --release
Finished release [optimized] target(s) in 0.01s
Running `target/release/adam-repro`
thread 'tokio-runtime-worker' panicked at 'assertion failed: `(left == right)`
left: `"hello sa\u{0}\u{0}\u{0}\u{0}\u{0}\u{0}\u{0}\u{0}sco"`,
right: `"hello san francisco"`', src/main.rs:15:17
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
zsh: segmentation fault (core dumped) cargo run --release
cargo run --release 0.23s user 0.09s system 125% cpu 0.249 total
:# eliza at noctis in adam-repro on main [?] is 📦 v0.1.0 via ⚙️ v1.56.1
:; time cargo run --release
Finished release [optimized] target(s) in 0.01s
Running `target/release/adam-repro`
zsh: segmentation fault (core dumped) cargo run --release
cargo run --release 0.07s user 0.05s system 61% cpu 0.192 total
:# eliza at noctis in adam-repro on main [?] is 📦 v0.1.0 via ⚙️ v1.56.1 |
If a `tokio::sync::oneshot` channel is closed (via the [`oneshot::Receiver::close`] method), a data race may occur if the `oneshot::Sender::send` method is called while the corresponding `oneshot::Receiver` is `await`ed or calling `try_recv`. When these methods are called concurrently on a closed channel, the two halves of the channel can concurrently access a shared memory location, resulting in a data race. This has been observed to [cause memory corruption][corruption]. Note that the race only occurs when **both** halves of the channel are used after one half has called `close`. Code where `close` is not used, or where the `Receiver` is not `await`ed and `try_recv` is not called after calling `close`, is not affected. See tokio-rs/tokio#4225 for more details. This issue was patched in v1.13.1. The patch was backported to the current LTS version (v1.8.x) in release v1.8.4.
* Add advisory for tokio-rs/tokio#4225 If a `tokio::sync::oneshot` channel is closed (via the [`oneshot::Receiver::close`] method), a data race may occur if the `oneshot::Sender::send` method is called while the corresponding `oneshot::Receiver` is `await`ed or calling `try_recv`. When these methods are called concurrently on a closed channel, the two halves of the channel can concurrently access a shared memory location, resulting in a data race. This has been observed to [cause memory corruption][corruption]. Note that the race only occurs when **both** halves of the channel are used after one half has called `close`. Code where `close` is not used, or where the `Receiver` is not `await`ed and `try_recv` is not called after calling `close`, is not affected. See tokio-rs/tokio#4225 for more details. This issue was patched in v1.13.1. The patch was backported to the current LTS version (v1.8.x) in release v1.8.4. * Update crates/tokio/RUSTSEC-0000-0000.md Co-authored-by: Tony Arcieri <bascule@gmail.com> * fix toml lint whoops * Update crates/tokio/RUSTSEC-0000-0000.md * Update crates/tokio/RUSTSEC-0000-0000.md Co-authored-by: Tony Arcieri <bascule@gmail.com>
Version
Reproduced with tokio 1.12.0 and 1.13.0
Platform
Description
There is a race between
send()
,try_recv()
, andoneshot::Receiver::close()
. The following program yields a panic roughly every 3 seconds on my 18c/36t workstation, compiled with Rust 1.56.1 in release mode:All of the panics occur when
send()
attemptsinner.consume_value().unwrap()
. For example:I suspect this is a race where the
rx.close(); rx.try_recv()
happens between theif !inner.complete()
check and theinner.consume_value().unwrap()
.The text was updated successfully, but these errors were encountered: