Skip to content
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

tests: fix SB violation in LeakedBuffers #5322

Merged
merged 3 commits into from Dec 29, 2022
Merged

Conversation

taiki-e
Copy link
Member

@taiki-e taiki-e commented Dec 28, 2022

Motivation

Split from #5317.

This fixes SB violation in test helper (LeakedBuffers).

cd tokio
MIRIFLAGS='-Zmiri-disable-isolation -Zmiri-strict-provenance -Zmiri-retag-fields' \
  cargo miri test --features full --target x86_64-unknown-linux-gnu --test io_read

(--test io_take -- bad_reader_fails also trigger this.)

output
error: Undefined Behavior: trying to retag from <335802> for Unique permission at alloc141485[0x0], but that tag does not exist in the borrow stack for this location
   --> tokio/tests/support/leaked_buffers.rs:24:9
    |
24  |         slice
    |         ^^^^^
    |         |
    |         trying to retag from <335802> for Unique permission at alloc141485[0x0], but that tag does not exist in the borrow stack for this location
    |         this error occurs as part of retag at alloc141485[0x0..0xa]
    |
    = help: this indicates a potential bug in the program: it performed an invalid operation, but the Stacked Borrows rules it violated are still experimental
    = help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md for further information
help: <335802> was created by a Unique retag at offsets [0x0..0xa]
   --> tokio/tests/support/leaked_buffers.rs:22:21
    |
22  |         let slice = std::slice::from_raw_parts_mut(new_mem.as_mut_ptr(), new_mem.len());
    |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
help: <335802> was later invalidated at offsets [0x0..0xa] by a Unique retag
   --> tokio/tests/support/leaked_buffers.rs:23:31
    |
23  |         self.leaked_vecs.push(new_mem);
    |                               ^^^^^^^
    = note: BACKTRACE (of the first span):
    = note: inside `support::leaked_buffers::LeakedBuffers::create::<'_>` at tokio/tests/support/leaked_buffers.rs:24:9: 24:14
note: inside `<BadAsyncRead as tokio::io::AsyncRead>::poll_read`
   --> tokio/tests/io_read.rs:63:38
    |
63  |         *buf = ReadBuf::new(unsafe { self.leaked_buffers.create(buf.capacity()) });
    |                                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: inside `<&mut BadAsyncRead as tokio::io::AsyncRead>::poll_read`
   --> /home/runner/work/tokio/tokio/tokio/src/io/async_read.rs:77:5
    |
77  |     deref_async_read!();
    |     ^^^^^^^^^^^^^^^^^^^
note: inside `<tokio::io::util::read_buf::ReadBuf<'_, BadAsyncRead, std::vec::Vec<u8>> as std::future::Future>::poll`
   --> /home/runner/work/tokio/tokio/tokio/src/io/util/read_buf.rs:57:20
    |
57  |             ready!(Pin::new(me.reader).poll_read(cx, &mut buf)?);
    |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: inside closure
   --> tokio/tests/io_read.rs:74:43
    |
74  |     BadAsyncRead::new().read_buf(&mut buf).await.unwrap();
    |                                           ^^^^^^
    = note: inside `<std::pin::Pin<&mut dyn std::future::Future<Output = ()>> as std::future::Future>::poll` at /home/runner/.rustup/toolchains/nightly-2022-12-27-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/future/future.rs:124:9: 124:61
    = note: inside `<std::pin::Pin<&mut std::pin::Pin<&mut dyn std::future::Future<Output = ()>>> as std::future::Future>::poll` at /home/runner/.rustup/toolchains/nightly-2022-12-27-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/future/future.rs:124:9: 124:61
note: inside closure
   --> /home/runner/work/tokio/tokio/tokio/src/runtime/scheduler/current_thread.rs:541:57
    |
541 |                         crate::runtime::coop::budget(|| future.as_mut().poll(&mut cx))
    |                                                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: inside `tokio::runtime::coop::with_budget::<std::task::Poll<()>, [closure@tokio::runtime::scheduler::current_thread::CoreGuard<'_>::block_on<std::pin::Pin<&mut std::pin::Pin<&mut dyn std::future::Future<Output = ()>>>>::{closure#0}::{closure#0}::{closure#0}]>`
   --> /home/runner/work/tokio/tokio/tokio/src/runtime/coop.rs:102:5
    |
102 |     f()
    |     ^^^
note: inside `tokio::runtime::coop::budget::<std::task::Poll<()>, [closure@tokio::runtime::scheduler::current_thread::CoreGuard<'_>::block_on<std::pin::Pin<&mut std::pin::Pin<&mut dyn std::future::Future<Output = ()>>>>::{closure#0}::{closure#0}::{closure#0}]>`
   --> /home/runner/work/tokio/tokio/tokio/src/runtime/coop.rs:68:5
    |
68  |     with_budget(Budget::initial(), f)
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: inside closure
   --> /home/runner/work/tokio/tokio/tokio/src/runtime/scheduler/current_thread.rs:541:25
    |
541 |                         crate::runtime::coop::budget(|| future.as_mut().poll(&mut cx))
    |                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: inside `tokio::runtime::scheduler::current_thread::Context::enter::<std::task::Poll<()>, [closure@tokio::runtime::scheduler::current_thread::CoreGuard<'_>::block_on<std::pin::Pin<&mut std::pin::Pin<&mut dyn std::future::Future<Output = ()>>>>::{closure#0}::{closure#0}]>`
   --> /home/runner/work/tokio/tokio/tokio/src/runtime/scheduler/current_thread.rs:350:19
    |
350 |         let ret = f();
    |                   ^^^
note: inside closure
   --> /home/runner/work/tokio/tokio/tokio/src/runtime/scheduler/current_thread.rs:540:36
    |
540 |                       let (c, res) = context.enter(core, || {
    |  ____________________________________^
541 | |                         crate::runtime::coop::budget(|| future.as_mut().poll(&mut cx))
542 | |                     });
    | |______________________^
note: inside closure
   --> /home/runner/work/tokio/tokio/tokio/src/runtime/scheduler/current_thread.rs:615:57
    |
615 |         let (core, ret) = CURRENT.set(&self.context, || f(core, &self.context));
    |                                                         ^^^^^^^^^^^^^^^^^^^^^^
note: inside `tokio::macros::scoped_tls::ScopedKey::<tokio::runtime::scheduler::current_thread::Context>::set::<[closure@tokio::runtime::scheduler::current_thread::CoreGuard<'_>::enter<[closure@tokio::runtime::scheduler::current_thread::CoreGuard<'_>::block_on<std::pin::Pin<&mut std::pin::Pin<&mut dyn std::future::Future<Output = ()>>>>::{closure#0}], std::option::Option<()>>::{closure#0}], (std::boxed::Box<tokio::runtime::scheduler::current_thread::Core>, std::option::Option<()>)>`
   --> /home/runner/work/tokio/tokio/tokio/src/macros/scoped_tls.rs:61:9
    |
61  |         f()
    |         ^^^
note: inside `tokio::runtime::scheduler::current_thread::CoreGuard::<'_>::enter::<[closure@tokio::runtime::scheduler::current_thread::CoreGuard<'_>::block_on<std::pin::Pin<&mut std::pin::Pin<&mut dyn std::future::Future<Output = ()>>>>::{closure#0}], std::option::Option<()>>`
   --> /home/runner/work/tokio/tokio/tokio/src/runtime/scheduler/current_thread.rs:615:27
    |
615 |         let (core, ret) = CURRENT.set(&self.context, || f(core, &self.context));
    |                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: inside `read_buf_bad_async_read`
   --> tokio/tests/io_read.rs:74:5
    |
74  |     BadAsyncRead::new().read_buf(&mut buf).await.unwrap();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: inside closure
   --> tokio/tests/io_read.rs:72:36
    |
70  | #[tokio::test]
    | -------------- in this procedural macro expansion
71  | #[should_panic]
72  | async fn read_buf_bad_async_read() {
    |                                    ^
    = note: this error originates in the macro `deref_async_read` which comes from the expansion of the attribute macro `tokio::test` (in Nightly builds, run with -Z macro-backtrace for more info)

note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace

error: aborting due to previous error

error: test failed, to rerun pass `--test io_read`

Caused by:
  process didn't exit successfully: `/home/runner/.rustup/toolchains/nightly-2022-12-27-x86_64-unknown-linux-gnu/bin/cargo-miri runner /home/runner/work/tokio/tokio/target/miri/x86_64-unknown-linux-gnu/debug/deps/io_read-9a80d00f6027f2d9` (exit status: 1)

```
error: Undefined Behavior: trying to retag from <335802> for Unique permission at alloc141485[0x0], but that tag does not exist in the borrow stack for this location
   --> tokio/tests/support/leaked_buffers.rs:24:9
    |
24  |         slice
    |         ^^^^^
    |         |
    |         trying to retag from <335802> for Unique permission at alloc141485[0x0], but that tag does not exist in the borrow stack for this location
    |         this error occurs as part of retag at alloc141485[0x0..0xa]
    |
    = help: this indicates a potential bug in the program: it performed an invalid operation, but the Stacked Borrows rules it violated are still experimental
    = help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md for further information
help: <335802> was created by a Unique retag at offsets [0x0..0xa]
   --> tokio/tests/support/leaked_buffers.rs:22:21
    |
22  |         let slice = std::slice::from_raw_parts_mut(new_mem.as_mut_ptr(), new_mem.len());
    |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
help: <335802> was later invalidated at offsets [0x0..0xa] by a Unique retag
   --> tokio/tests/support/leaked_buffers.rs:23:31
    |
23  |         self.leaked_vecs.push(new_mem);
    |                               ^^^^^^^
    = note: BACKTRACE (of the first span):
    = note: inside `support::leaked_buffers::LeakedBuffers::create::<'_>` at tokio/tests/support/leaked_buffers.rs:24:9: 24:14
note: inside `<BadAsyncRead as tokio::io::AsyncRead>::poll_read`
   --> tokio/tests/io_read.rs:63:38
    |
63  |         *buf = ReadBuf::new(unsafe { self.leaked_buffers.create(buf.capacity()) });
    |                                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: inside `<&mut BadAsyncRead as tokio::io::AsyncRead>::poll_read`
   --> /home/runner/work/tokio/tokio/tokio/src/io/async_read.rs:77:5
    |
77  |     deref_async_read!();
    |     ^^^^^^^^^^^^^^^^^^^
note: inside `<tokio::io::util::read_buf::ReadBuf<'_, BadAsyncRead, std::vec::Vec<u8>> as std::future::Future>::poll`
   --> /home/runner/work/tokio/tokio/tokio/src/io/util/read_buf.rs:57:20
    |
57  |             ready!(Pin::new(me.reader).poll_read(cx, &mut buf)?);
    |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: inside closure
   --> tokio/tests/io_read.rs:74:43
    |
74  |     BadAsyncRead::new().read_buf(&mut buf).await.unwrap();
    |                                           ^^^^^^
    = note: inside `<std::pin::Pin<&mut dyn std::future::Future<Output = ()>> as std::future::Future>::poll` at /home/runner/.rustup/toolchains/nightly-2022-12-27-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/future/future.rs:124:9: 124:61
    = note: inside `<std::pin::Pin<&mut std::pin::Pin<&mut dyn std::future::Future<Output = ()>>> as std::future::Future>::poll` at /home/runner/.rustup/toolchains/nightly-2022-12-27-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/future/future.rs:124:9: 124:61
note: inside closure
   --> /home/runner/work/tokio/tokio/tokio/src/runtime/scheduler/current_thread.rs:541:57
    |
541 |                         crate::runtime::coop::budget(|| future.as_mut().poll(&mut cx))
    |                                                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: inside `tokio::runtime::coop::with_budget::<std::task::Poll<()>, [closure@tokio::runtime::scheduler::current_thread::CoreGuard<'_>::block_on<std::pin::Pin<&mut std::pin::Pin<&mut dyn std::future::Future<Output = ()>>>>::{closure#0}::{closure#0}::{closure#0}]>`
   --> /home/runner/work/tokio/tokio/tokio/src/runtime/coop.rs:102:5
    |
102 |     f()
    |     ^^^
note: inside `tokio::runtime::coop::budget::<std::task::Poll<()>, [closure@tokio::runtime::scheduler::current_thread::CoreGuard<'_>::block_on<std::pin::Pin<&mut std::pin::Pin<&mut dyn std::future::Future<Output = ()>>>>::{closure#0}::{closure#0}::{closure#0}]>`
   --> /home/runner/work/tokio/tokio/tokio/src/runtime/coop.rs:68:5
    |
68  |     with_budget(Budget::initial(), f)
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: inside closure
   --> /home/runner/work/tokio/tokio/tokio/src/runtime/scheduler/current_thread.rs:541:25
    |
541 |                         crate::runtime::coop::budget(|| future.as_mut().poll(&mut cx))
    |                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: inside `tokio::runtime::scheduler::current_thread::Context::enter::<std::task::Poll<()>, [closure@tokio::runtime::scheduler::current_thread::CoreGuard<'_>::block_on<std::pin::Pin<&mut std::pin::Pin<&mut dyn std::future::Future<Output = ()>>>>::{closure#0}::{closure#0}]>`
   --> /home/runner/work/tokio/tokio/tokio/src/runtime/scheduler/current_thread.rs:350:19
    |
350 |         let ret = f();
    |                   ^^^
note: inside closure
   --> /home/runner/work/tokio/tokio/tokio/src/runtime/scheduler/current_thread.rs:540:36
    |
540 |                       let (c, res) = context.enter(core, || {
    |  ____________________________________^
541 | |                         crate::runtime::coop::budget(|| future.as_mut().poll(&mut cx))
542 | |                     });
    | |______________________^
note: inside closure
   --> /home/runner/work/tokio/tokio/tokio/src/runtime/scheduler/current_thread.rs:615:57
    |
615 |         let (core, ret) = CURRENT.set(&self.context, || f(core, &self.context));
    |                                                         ^^^^^^^^^^^^^^^^^^^^^^
note: inside `tokio::macros::scoped_tls::ScopedKey::<tokio::runtime::scheduler::current_thread::Context>::set::<[closure@tokio::runtime::scheduler::current_thread::CoreGuard<'_>::enter<[closure@tokio::runtime::scheduler::current_thread::CoreGuard<'_>::block_on<std::pin::Pin<&mut std::pin::Pin<&mut dyn std::future::Future<Output = ()>>>>::{closure#0}], std::option::Option<()>>::{closure#0}], (std::boxed::Box<tokio::runtime::scheduler::current_thread::Core>, std::option::Option<()>)>`
   --> /home/runner/work/tokio/tokio/tokio/src/macros/scoped_tls.rs:61:9
    |
61  |         f()
    |         ^^^
note: inside `tokio::runtime::scheduler::current_thread::CoreGuard::<'_>::enter::<[closure@tokio::runtime::scheduler::current_thread::CoreGuard<'_>::block_on<std::pin::Pin<&mut std::pin::Pin<&mut dyn std::future::Future<Output = ()>>>>::{closure#0}], std::option::Option<()>>`
   --> /home/runner/work/tokio/tokio/tokio/src/runtime/scheduler/current_thread.rs:615:27
    |
615 |         let (core, ret) = CURRENT.set(&self.context, || f(core, &self.context));
    |                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: inside `read_buf_bad_async_read`
   --> tokio/tests/io_read.rs:74:5
    |
74  |     BadAsyncRead::new().read_buf(&mut buf).await.unwrap();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: inside closure
   --> tokio/tests/io_read.rs:72:36
    |
70  | #[tokio::test]
    | -------------- in this procedural macro expansion
71  | #[should_panic]
72  | async fn read_buf_bad_async_read() {
    |                                    ^
    = note: this error originates in the macro `deref_async_read` which comes from the expansion of the attribute macro `tokio::test` (in Nightly builds, run with -Z macro-backtrace for more info)

note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace

error: aborting due to previous error

error: test failed, to rerun pass `--test io_read`

Caused by:
  process didn't exit successfully: `/home/runner/.rustup/toolchains/nightly-2022-12-27-x86_64-unknown-linux-gnu/bin/cargo-miri runner /home/runner/work/tokio/tokio/target/miri/x86_64-unknown-linux-gnu/debug/deps/io_read-9a80d00f6027f2d9` (exit status: 1)
```
@taiki-e taiki-e added the A-tokio Area: The main tokio crate label Dec 28, 2022
@taiki-e
Copy link
Member Author

taiki-e commented Dec 28, 2022

Reverted nightly toolchain bump for now because it triggered another SB violation (#5317 (comment) -- Is it fine to suppress the error in the way I mentioned there for now?).

@taiki-e taiki-e merged commit ef02242 into master Dec 29, 2022
@taiki-e taiki-e deleted the taiki-e/miri-leaked-buffers branch December 29, 2022 02:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-tokio Area: The main tokio crate
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants