Repository: tokio-rs/tokio (language: rust)

Issue:
Miri reported UB in ``io_async_fd``
**Version**
Tokio master branch ``01e04daa``

Miri nightly version:
```
rustc 1.84.0-nightly (439284741 2024-10-21)
binary: rustc
commit-hash: 4392847410ddd67f6734dd9845f9742ff9e85c83
commit-date: 2024-10-21
host: x86_64-unknown-linux-gnu
release: 1.84.0-nightly
LLVM version: 19.1.1
```

**Description**
After removing all ``#![cfg(not(miri))]`` and ``#[cfg_attr(miri, ignore)]`` in ``tokio/tests/io_async_fd.rs``, running ``cargo +nightly miri nextest run --test io_async_fd`` with ``MIRIFLAGS="-Zmiri-disable-isolation -Zmiri-strict-provenance -Zmiri-retag-fields" `` will make miri report UB on ``try_new`` and ``try_with_interest``, 

<details>

<summary> try_new error trace </summary>

```rust

        FAIL [   2.271s] tokio::io_async_fd try_new

--- STDOUT:              tokio::io_async_fd try_new ---

running 1 test
test try_new ... 
--- STDERR:              tokio::io_async_fd try_new ---
error: Undefined Behavior: trying to retag from <427610> for SharedReadWrite permission at alloc177964[0x0], but that tag does not exist in the borrow stack for this location
   --> /home/gh-tiif/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ptr/non_null.rs:383:18
    |
383 |         unsafe { &*self.as_ptr().cast_const() }
    |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |                  |
    |                  trying to retag from <427610> for SharedReadWrite permission at alloc177964[0x0], but that tag does not exist in the borrow stack for this location
    |                  this error occurs as part of retag at alloc177964[0x0..0x100]
    |
    = 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: <427610> was created by a SharedReadOnly retag at offsets [0xd0..0x30d]
   --> /home/gh-tiif/tokio/tokio/src/runtime/io/registration_set.rs:119:45
    |
119 |         let _ = synced.registrations.remove(io.into());
    |                                             ^^^^^^^^^
    = note: BACKTRACE (of the first span) on thread `try_new`:
    = note: inside `std::ptr::NonNull::<alloc::sync::ArcInner<tokio::runtime::io::scheduled_io::ScheduledIo>>::as_ref::<'_>` at /home/gh-tiif/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ptr/non_null.rs:383:18: 383:46
    = note: inside `std::sync::Arc::<tokio::runtime::io::scheduled_io::ScheduledIo>::inner` at /home/gh-tiif/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/alloc/src/sync.rs:1869:18: 1869:35
    = note: inside `<std::sync::Arc<tokio::runtime::io::scheduled_io::ScheduledIo> as std::ops::Drop>::drop` at /home/gh-tiif/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/alloc/src/sync.rs:2527:12: 2527:24
    = note: inside `std::ptr::drop_in_place::<std::sync::Arc<tokio::runtime::io::scheduled_io::ScheduledIo>> - shim(Some(std::sync::Arc<tokio::runtime::io::scheduled_io::ScheduledIo>))` at /home/gh-tiif/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ptr/mod.rs:521:1: 521:56
    = note: inside `std::ptr::drop_in_place::<std::option::Option<std::sync::Arc<tokio::runtime::io::scheduled_io::ScheduledIo>>> - shim(Some(std::option::Option<std::sync::Arc<tokio::runtime::io::scheduled_io::ScheduledIo>>))` at /home/gh-tiif/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ptr/mod.rs:521:1: 521:56
note: inside `tokio::runtime::io::registration_set::RegistrationSet::remove`
   --> /home/gh-tiif/tokio/tokio/src/runtime/io/registration_set.rs:119:55
    |
119 |         let _ = synced.registrations.remove(io.into());
    |                                                       ^
note: inside `tokio::runtime::io::driver::Handle::add_source::<mio::sys::unix::sourcefd::SourceFd<'_>>`
   --> /home/gh-tiif/tokio/tokio/src/runtime/io/driver.rs:227:17
    |
227 | /                 self.registrations
228 | |                     .remove(&mut self.synced.lock(), &scheduled_io)
    | |___________________________________________________________________^
note: inside closure
   --> tokio/tests/io_async_fd.rs:841:17
    |
841 |     let error = AsyncFd::try_new(original.clone()).unwrap_err();
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = note: inside `<std::pin::Pin<&mut dyn futures::Future<Output = ()>> as futures::Future>::poll` at /home/gh-tiif/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/future/future.rs:123:9: 123:61
    = note: inside `<std::pin::Pin<&mut std::pin::Pin<&mut dyn futures::Future<Output = ()>>> as futures::Future>::poll` at /home/gh-tiif/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/future/future.rs:123:9: 123:61
note: inside closure
   --> /home/gh-tiif/tokio/tokio/src/runtime/scheduler/current_thread/mod.rs:729:57
    |
729 |                         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 futures::Future<Output = ()>>>>::{closure#0}::{closure#0}::{closure#0}}>`
   --> /home/gh-tiif/tokio/tokio/src/runtime/coop.rs:107:5
    |
107 |     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 futures::Future<Output = ()>>>>::{closure#0}::{closure#0}::{closure#0}}>`
   --> /home/gh-tiif/tokio/tokio/src/runtime/coop.rs:73:5
    |
73  |     with_budget(Budget::initial(), f)
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: inside closure
   --> /home/gh-tiif/tokio/tokio/src/runtime/scheduler/current_thread/mod.rs:729:25
    |
729 |                         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 futures::Future<Output = ()>>>>::{closure#0}::{closure#0}}>`
   --> /home/gh-tiif/tokio/tokio/src/runtime/scheduler/current_thread/mod.rs:428:19
    |
428 |         let ret = f();
    |                   ^^^
note: inside closure
   --> /home/gh-tiif/tokio/tokio/src/runtime/scheduler/current_thread/mod.rs:728:36
    |
728 |                       let (c, res) = context.enter(core, || {
    |  ____________________________________^
729 | |                         crate::runtime::coop::budget(|| future.as_mut().poll(&mut cx))
730 | |                     });
    | |______________________^
note: inside closure
   --> /home/gh-tiif/tokio/tokio/src/runtime/scheduler/current_thread/mod.rs:807:68
    |
807 |         let (core, ret) = context::set_scheduler(&self.context, || f(core, context));
    |                                                                    ^^^^^^^^^^^^^^^^
note: inside `tokio::runtime::context::scoped::Scoped::<tokio::runtime::scheduler::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 futures::Future<Output = ()>>>>::{closure#0}}, std::option::Option<()>>::{closure#0}}, (std::boxed::Box<tokio::runtime::scheduler::current_thread::Core>, std::option::Option<()>)>`
   --> /home/gh-tiif/tokio/tokio/src/runtime/context/scoped.rs:40:9
    |
40  |         f()
    |         ^^^
note: inside closure
   --> /home/gh-tiif/tokio/tokio/src/runtime/context.rs:180:26
    |
180 |         CONTEXT.with(|c| c.scheduler.set(v, f))
    |                          ^^^^^^^^^^^^^^^^^^^^^
    = note: inside `std::thread::LocalKey::<tokio::runtime::context::Context>::try_with::<{closure@tokio::runtime::context::set_scheduler<(std::boxed::Box<tokio::runtime::scheduler::current_thread::Core>, std::option::Option<()>), {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 futures::Future<Output = ()>>>>::{closure#0}}, std::option::Option<()>>::{closure#0}}>::{closure#0}}, (std::boxed::Box<tokio::runtime::scheduler::current_thread::Core>, std::option::Option<()>)>` at /home/gh-tiif/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/thread/local.rs:283:12: 283:27
    = note: inside `std::thread::LocalKey::<tokio::runtime::context::Context>::with::<{closure@tokio::runtime::context::set_scheduler<(std::boxed::Box<tokio::runtime::scheduler::current_thread::Core>, std::option::Option<()>), {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 futures::Future<Output = ()>>>>::{closure#0}}, std::option::Option<()>>::{closure#0}}>::{closure#0}}, (std::boxed::Box<tokio::runtime::scheduler::current_thread::Core>, std::option::Option<()>)>` at /home/gh-tiif/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/thread/local.rs:260:9: 260:25
note: inside `tokio::runtime::context::set_scheduler::<(std::boxed::Box<tokio::runtime::scheduler::current_thread::Core>, std::option::Option<()>), {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 futures::Future<Output = ()>>>>::{closure#0}}, std::option::Option<()>>::{closure#0}}>`
   --> /home/gh-tiif/tokio/tokio/src/runtime/context.rs:180:9
    |
180 |         CONTEXT.with(|c| c.scheduler.set(v, 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 futures::Future<Output = ()>>>>::{closure#0}}, std::option::Option<()>>`
   --> /home/gh-tiif/tokio/tokio/src/runtime/scheduler/current_thread/mod.rs:807:27
    |
807 |         let (core, ret) = context::set_scheduler(&self.context, || f(core, context));
    |                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: inside closure
   --> /home/gh-tiif/tokio/tokio/src/runtime/scheduler/current_thread/mod.rs:196:28
    |
196 |                     return core.block_on(future);
    |                            ^^^^^^^^^^^^^^^^^^^^^
note: inside `try_new`
   --> tokio/tests/io_async_fd.rs:844:5
    |
844 |     assert!(Arc::ptr_eq(&original, &returned));
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: inside closure
   --> tokio/tests/io_async_fd.rs:838:19
    |
837 | #[tokio::test]
    | -------------- in this procedural macro expansion
838 | async fn try_new() {
    |                   ^
    = note: this error originates in the attribute macro `::core::prelude::v1::test` 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 1 previous error
```

</details>

<details> 
<summary> try_with_interest error trace </summary>

```rust
        FAIL [   3.207s] tokio::io_async_fd try_with_interest

--- STDOUT:              tokio::io_async_fd try_with_interest ---

running 1 test
test try_with_interest ... 
--- STDERR:              tokio::io_async_fd try_with_interest ---
error: Undefined Behavior: trying to retag from <428806> for SharedReadWrite permission at alloc178669[0x0], but that tag does not exist in the borrow stack for this location
   --> /home/gh-tiif/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ptr/non_null.rs:383:18
    |
383 |         unsafe { &*self.as_ptr().cast_const() }
    |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |                  |
    |                  trying to retag from <428806> for SharedReadWrite permission at alloc178669[0x0], but that tag does not exist in the borrow stack for this location
    |                  this error occurs as part of retag at alloc178669[0x0..0x100]
    |
    = 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: <428806> was created by a SharedReadOnly retag at offsets [0xd0..0x30d]
   --> /home/gh-tiif/tokio/tokio/src/runtime/io/registration_set.rs:119:45
    |
119 |         let _ = synced.registrations.remove(io.into());
    |                                             ^^^^^^^^^
    = note: BACKTRACE (of the first span) on thread `try_with_intere`:
    = note: inside `std::ptr::NonNull::<alloc::sync::ArcInner<tokio::runtime::io::scheduled_io::ScheduledIo>>::as_ref::<'_>` at /home/gh-tiif/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ptr/non_null.rs:383:18: 383:46
    = note: inside `std::sync::Arc::<tokio::runtime::io::scheduled_io::ScheduledIo>::inner` at /home/gh-tiif/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/alloc/src/sync.rs:1869:18: 1869:35
    = note: inside `<std::sync::Arc<tokio::runtime::io::scheduled_io::ScheduledIo> as std::ops::Drop>::drop` at /home/gh-tiif/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/alloc/src/sync.rs:2527:12: 2527:24
    = note: inside `std::ptr::drop_in_place::<std::sync::Arc<tokio::runtime::io::scheduled_io::ScheduledIo>> - shim(Some(std::sync::Arc<tokio::runtime::io::scheduled_io::ScheduledIo>))` at /home/gh-tiif/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ptr/mod.rs:521:1: 521:56
    = note: inside `std::ptr::drop_in_place::<std::option::Option<std::sync::Arc<tokio::runtime::io::scheduled_io::ScheduledIo>>> - shim(Some(std::option::Option<std::sync::Arc<tokio::runtime::io::scheduled_io::ScheduledIo>>))` at /home/gh-tiif/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ptr/mod.rs:521:1: 521:56
note: inside `tokio::runtime::io::registration_set::RegistrationSet::remove`
   --> /home/gh-tiif/tokio/tokio/src/runtime/io/registration_set.rs:119:55
    |
119 |         let _ = synced.registrations.remove(io.into());
    |                                                       ^
note: inside `tokio::runtime::io::driver::Handle::add_source::<mio::sys::unix::sourcefd::SourceFd<'_>>`
   --> /home/gh-tiif/tokio/tokio/src/runtime/io/driver.rs:227:17
    |
227 | /                 self.registrations
228 | |                     .remove(&mut self.synced.lock(), &scheduled_io)
    | |___________________________________________________________________^
note: inside closure
   --> tokio/tests/io_async_fd.rs:851:17
    |
851 |     let error = AsyncFd::try_with_interest(original.clone(), Interest::READABLE).unwrap_err();
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = note: inside `<std::pin::Pin<&mut dyn futures::Future<Output = ()>> as futures::Future>::poll` at /home/gh-tiif/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/future/future.rs:123:9: 123:61
    = note: inside `<std::pin::Pin<&mut std::pin::Pin<&mut dyn futures::Future<Output = ()>>> as futures::Future>::poll` at /home/gh-tiif/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/future/future.rs:123:9: 123:61
note: inside closure
   --> /home/gh-tiif/tokio/tokio/src/runtime/scheduler/current_thread/mod.rs:729:57
    |
729 |                         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 futures::Future<Output = ()>>>>::{closure#0}::{closure#0}::{closure#0}}>`
   --> /home/gh-tiif/tokio/tokio/src/runtime/coop.rs:107:5
    |
107 |     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 futures::Future<Output = ()>>>>::{closure#0}::{closure#0}::{closure#0}}>`
   --> /home/gh-tiif/tokio/tokio/src/runtime/coop.rs:73:5
    |
73  |     with_budget(Budget::initial(), f)
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: inside closure
   --> /home/gh-tiif/tokio/tokio/src/runtime/scheduler/current_thread/mod.rs:729:25
    |
729 |                         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 futures::Future<Output = ()>>>>::{closure#0}::{closure#0}}>`
   --> /home/gh-tiif/tokio/tokio/src/runtime/scheduler/current_thread/mod.rs:428:19
    |
428 |         let ret = f();
    |                   ^^^
note: inside closure
   --> /home/gh-tiif/tokio/tokio/src/runtime/scheduler/current_thread/mod.rs:728:36
    |
728 |                       let (c, res) = context.enter(core, || {
    |  ____________________________________^
729 | |                         crate::runtime::coop::budget(|| future.as_mut().poll(&mut cx))
730 | |                     });
    | |______________________^
note: inside closure
   --> /home/gh-tiif/tokio/tokio/src/runtime/scheduler/current_thread/mod.rs:807:68
    |
807 |         let (core, ret) = context::set_scheduler(&self.context, || f(core, context));
    |                                                                    ^^^^^^^^^^^^^^^^
note: inside `tokio::runtime::context::scoped::Scoped::<tokio::runtime::scheduler::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 futures::Future<Output = ()>>>>::{closure#0}}, std::option::Option<()>>::{closure#0}}, (std::boxed::Box<tokio::runtime::scheduler::current_thread::Core>, std::option::Option<()>)>`
   --> /home/gh-tiif/tokio/tokio/src/runtime/context/scoped.rs:40:9
    |
40  |         f()
    |         ^^^
note: inside closure
   --> /home/gh-tiif/tokio/tokio/src/runtime/context.rs:180:26
    |
180 |         CONTEXT.with(|c| c.scheduler.set(v, f))
    |                          ^^^^^^^^^^^^^^^^^^^^^
    = note: inside `std::thread::LocalKey::<tokio::runtime::context::Context>::try_with::<{closure@tokio::runtime::context::set_scheduler<(std::boxed::Box<tokio::runtime::scheduler::current_thread::Core>, std::option::Option<()>), {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 futures::Future<Output = ()>>>>::{closure#0}}, std::option::Option<()>>::{closure#0}}>::{closure#0}}, (std::boxed::Box<tokio::runtime::scheduler::current_thread::Core>, std::option::Option<()>)>` at /home/gh-tiif/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/thread/local.rs:283:12: 283:27
    = note: inside `std::thread::LocalKey::<tokio::runtime::context::Context>::with::<{closure@tokio::runtime::context::set_scheduler<(std::boxed::Box<tokio::runtime::scheduler::current_thread::Core>, std::option::Option<()>), {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 futures::Future<Output = ()>>>>::{closure#0}}, std::option::Option<()>>::{closure#0}}>::{closure#0}}, (std::boxed::Box<tokio::runtime::scheduler::current_thread::Core>, std::option::Option<()>)>` at /home/gh-tiif/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/thread/local.rs:260:9: 260:25
note: inside `tokio::runtime::context::set_scheduler::<(std::boxed::Box<tokio::runtime::scheduler::current_thread::Core>, std::option::Option<()>), {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 futures::Future<Output = ()>>>>::{closure#0}}, std::option::Option<()>>::{closure#0}}>`
   --> /home/gh-tiif/tokio/tokio/src/runtime/context.rs:180:9
    |
180 |         CONTEXT.with(|c| c.scheduler.set(v, 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 futures::Future<Output = ()>>>>::{closure#0}}, std::option::Option<()>>`
   --> /home/gh-tiif/tokio/tokio/src/runtime/scheduler/current_thread/mod.rs:807:27
    |
807 |         let (core, ret) = context::set_scheduler(&self.context, || f(core, context));
    |                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: inside closure
   --> /home/gh-tiif/tokio/tokio/src/runtime/scheduler/current_thread/mod.rs:196:28
    |
196 |                     return core.block_on(future);
    |                            ^^^^^^^^^^^^^^^^^^^^^
note: inside `try_with_interest`
   --> tokio/tests/io_async_fd.rs:854:5
    |
854 |     assert!(Arc::ptr_eq(&original, &returned));
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: inside closure
   --> tokio/tests/io_async_fd.rs:848:29
    |
847 | #[tokio::test]
    | -------------- in this procedural macro expansion
848 | async fn try_with_interest() {
    |                             ^
    = note: this error originates in the attribute macro `::core::prelude::v1::test` 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 1 previous error

```

</details>

(cc #6812 as this might need to be annotated in the test)



Discussion / hints:
I believe we need to add
```rs
super::EXPOSE_IO.expose_provenance(&*ret);
```
to the end of `RegistrationSet::allocate` to fix this.
This seems like a simple fix, I could help to fix this and test it again. 

Fix patch:
diff --git a/tokio/src/runtime/io/registration_set.rs b/tokio/src/runtime/io/registration_set.rs
index 9b2f3f13c43..9b23732d96a 100644
--- a/tokio/src/runtime/io/registration_set.rs
+++ b/tokio/src/runtime/io/registration_set.rs
@@ -106,7 +106,7 @@ impl RegistrationSet {
 
         for io in pending {
             // safety: the registration is part of our list
-            unsafe { self.remove(synced, io.as_ref()) }
+            unsafe { self.remove(synced, &io) }
         }
 
         self.num_pending_release.store(0, Release);
@@ -114,9 +114,12 @@ impl RegistrationSet {
 
     // This function is marked as unsafe, because the caller must make sure that
     // `io` is part of the registration set.
-    pub(super) unsafe fn remove(&self, synced: &mut Synced, io: &ScheduledIo) {
-        super::EXPOSE_IO.unexpose_provenance(io);
-        let _ = synced.registrations.remove(io.into());
+    pub(super) unsafe fn remove(&self, synced: &mut Synced, io: &Arc<ScheduledIo>) {
+        // SAFETY: Pointers into an Arc are never null.
+        let io = unsafe { NonNull::new_unchecked(Arc::as_ptr(io).cast_mut()) };
+
+        super::EXPOSE_IO.unexpose_provenance(io.as_ptr());
+        let _ = synced.registrations.remove(io);
     }
 }
 


Test patch:
diff --git a/tokio/tests/io_async_fd.rs b/tokio/tests/io_async_fd.rs
index 469d2a4acbe..fc243eb729a 100644
--- a/tokio/tests/io_async_fd.rs
+++ b/tokio/tests/io_async_fd.rs
@@ -1,5 +1,5 @@
 #![warn(rust_2018_idioms)]
-#![cfg(all(unix, feature = "full", not(miri)))]
+#![cfg(all(unix, feature = "full"))]
 
 use std::os::unix::io::{AsRawFd, RawFd};
 use std::sync::{
@@ -148,6 +148,7 @@ fn drain(mut fd: &FileDescriptor, mut amt: usize) {
 }
 
 #[tokio::test]
+#[cfg_attr(miri, ignore)] // No F_GETFL for fcntl in miri.
 async fn initially_writable() {
     let (a, b) = socketpair();
 
@@ -166,6 +167,7 @@ async fn initially_writable() {
 }
 
 #[tokio::test]
+#[cfg_attr(miri, ignore)] // No F_GETFL for fcntl in miri.
 async fn reset_readable() {
     let (a, mut b) = socketpair();
 
@@ -210,6 +212,7 @@ async fn reset_readable() {
 }
 
 #[tokio::test]
+#[cfg_attr(miri, ignore)] // No F_GETFL for fcntl in miri.
 async fn reset_writable() {
     let (a, b) = socketpair();
 
@@ -247,6 +250,7 @@ impl<T: AsRawFd> AsRawFd for ArcFd<T> {
 }
 
 #[tokio::test]
+#[cfg_attr(miri, ignore)] // No F_GETFL for fcntl in miri.
 async fn drop_closes() {
     let (a, mut b) = socketpair();
 
@@ -287,6 +291,7 @@ async fn drop_closes() {
 }
 
 #[tokio::test]
+#[cfg_attr(miri, ignore)] // No F_GETFL for fcntl in miri.
 async fn reregister() {
     let (a, _b) = socketpair();
 
@@ -296,6 +301,7 @@ async fn reregister() {
 }
 
 #[tokio::test]
+#[cfg_attr(miri, ignore)] // No F_GETFL for fcntl in miri.
 async fn try_io() {
     let (a, mut b) = socketpair();
 
@@ -331,6 +337,7 @@ async fn try_io() {
 }
 
 #[tokio::test]
+#[cfg_attr(miri, ignore)] // No F_GETFL for fcntl in miri.
 async fn multiple_waiters() {
     let (a, mut b) = socketpair();
     let afd_a = Arc::new(AsyncFd::new(a).unwrap());
@@ -379,6 +386,7 @@ async fn multiple_waiters() {
 }
 
 #[tokio::test]
+#[cfg_attr(miri, ignore)] // No F_GETFL for fcntl in miri.
 async fn poll_fns() {
     let (a, b) = socketpair();
     let afd_a = Arc::new(AsyncFd::new(a).unwrap());
@@ -472,6 +480,7 @@ fn rt() -> tokio::runtime::Runtime {
 }
 
 #[test]
+#[cfg_attr(miri, ignore)] // No F_GETFL for fcntl in miri.
 fn driver_shutdown_wakes_currently_pending() {
     let rt = rt();
 
@@ -493,6 +502,7 @@ fn driver_shutdown_wakes_currently_pending() {
 }
 
 #[test]
+#[cfg_attr(miri, ignore)] // No F_GETFL for fcntl in miri.
 fn driver_shutdown_wakes_future_pending() {
     let rt = rt();
 
@@ -508,6 +518,7 @@ fn driver_shutdown_wakes_future_pending() {
 }
 
 #[test]
+#[cfg_attr(miri, ignore)] // No F_GETFL for fcntl in miri.
 fn driver_shutdown_wakes_pending_race() {
     // TODO: make this a loom test
     for _ in 0..100 {
@@ -538,6 +549,7 @@ async fn poll_writable<T: AsRawFd>(fd: &AsyncFd<T>) -> std::io::Result<AsyncFdRe
 }
 
 #[test]
+#[cfg_attr(miri, ignore)] // No F_GETFL for fcntl in miri.
 fn driver_shutdown_wakes_currently_pending_polls() {
     let rt = rt();
 
@@ -560,6 +572,7 @@ fn driver_shutdown_wakes_currently_pending_polls() {
 }
 
 #[test]
+#[cfg_attr(miri, ignore)] // No F_GETFL for fcntl in miri.
 fn driver_shutdown_wakes_poll() {
     let rt = rt();
 
@@ -576,6 +589,7 @@ fn driver_shutdown_wakes_poll() {
 }
 
 #[test]
+#[cfg_attr(miri, ignore)] // No F_GETFL for fcntl in miri.
 fn driver_shutdown_then_clear_readiness() {
     let rt = rt();
 
@@ -593,6 +607,7 @@ fn driver_shutdown_then_clear_readiness() {
 }
 
 #[test]
+#[cfg_attr(miri, ignore)] // No F_GETFL for fcntl in miri.
 fn driver_shutdown_wakes_poll_race() {
     // TODO: make this a loom test
     for _ in 0..100 {
@@ -615,6 +630,7 @@ fn driver_shutdown_wakes_poll_race() {
 }
 
 #[tokio::test]
+#[cfg_attr(miri, ignore)] // No socket in miri.
 #[cfg(any(target_os = "linux", target_os = "android"))]
 async fn priority_event_on_oob_data() {
     use std::net::SocketAddr;
@@ -655,7 +671,7 @@ fn send_oob_data<S: AsRawFd>(stream: &S, data: &[u8]) -> io::Result<usize> {
 }
 
 #[tokio::test]
-#[cfg_attr(miri, ignore)]
+#[cfg_attr(miri, ignore)] // No F_GETFL for fcntl in miri.
 async fn clear_ready_matching_clears_ready() {
     use tokio::io::{Interest, Ready};
 
@@ -679,7 +695,7 @@ async fn clear_ready_matching_clears_ready() {
 }
 
 #[tokio::test]
-#[cfg_attr(miri, ignore)]
+#[cfg_attr(miri, ignore)] // No F_GETFL for fcntl in miri.
 async fn clear_ready_matching_clears_ready_mut() {
     use tokio::io::{Interest, Ready};
 
@@ -703,8 +719,8 @@ async fn clear_ready_matching_clears_ready_mut() {
 }
 
 #[tokio::test]
+#[cfg_attr(miri, ignore)] // No socket in miri.
 #[cfg(target_os = "linux")]
-#[cfg_attr(miri, ignore)]
 async fn await_error_readiness_timestamping() {
     use std::net::{Ipv4Addr, SocketAddr};
 
@@ -760,8 +776,8 @@ fn configure_timestamping_socket(udp_socket: &std::net::UdpSocket) -> std::io::R
 }
 
 #[tokio::test]
+#[cfg_attr(miri, ignore)] // No F_GETFL for fcntl in miri.
 #[cfg(target_os = "linux")]
-#[cfg_attr(miri, ignore)]
 async fn await_error_readiness_invalid_address() {
     use std::net::{Ipv4Addr, SocketAddr};
     use tokio::io::{Interest, Ready};