github-actions[bot] opened issue #14977:
AsyncFd::newand related constructors violate I/O safety
Details Status unsound Package tokioVersion 1.51.1URL https://github.com/tokio-rs/tokio/pull/8587 Date 2026-10-13
tokio::io::unix::AsyncFdprovides safe constructors (new,with_interest,try_new, andtry_with_interest) that accept anyT: AsRawFdrather than requiring proof of ownership or validity of the file descriptor. BecauseRawFdimplementsAsRawFd, safe code can construct anAsyncFdfrom an arbitrary or closed file descriptor, or close/replace the underlying file descriptor while theAsyncFdis still alive.This violates I/O safety in two ways:
AsyncFd<T>implementsAsFdfor allT: AsRawFdby callingBorrowedFd::borrow_raw(self.as_raw_fd()), allowing safe code to obtain an arbitraryBorrowedFd<'_>without owning the file descriptor.- Tokio's I/O driver stores a pointer to an internal allocation in the
epoll/kqueueuser data for registered file descriptors. If the underlying file descriptor is duplicated and then closed while anAsyncFdis alive, and the OS reuses that file descriptor number for a another IO resource on the same runtime, dropping the firstAsyncFdderegisters the reused file descriptor number and frees the first while the original file description remains registered inepoll, leading to a use-after-free when a readiness event fires.Starting in Tokio 1.51.6, 1.53.3, and 1.54.0,
AsyncFd::new,AsyncFd::with_interest,AsyncFd::try_new, andAsyncFd::try_with_interestare deprecated in favor of theunsafeconstructorsAsyncFd::registerandAsyncFd::register_with_interest. Callers must ensure that the file descriptor remains valid, open, and unchanged for the lifetime of theAsyncFd.See advisory page for additional details.
pchickey closed issue #14977:
AsyncFd::newand related constructors violate I/O safety
Details Status unsound Package tokioVersion 1.51.1URL https://github.com/tokio-rs/tokio/pull/8587 Date 2026-10-13
tokio::io::unix::AsyncFdprovides safe constructors (new,with_interest,try_new, andtry_with_interest) that accept anyT: AsRawFdrather than requiring proof of ownership or validity of the file descriptor. BecauseRawFdimplementsAsRawFd, safe code can construct anAsyncFdfrom an arbitrary or closed file descriptor, or close/replace the underlying file descriptor while theAsyncFdis still alive.This violates I/O safety in two ways:
AsyncFd<T>implementsAsFdfor allT: AsRawFdby callingBorrowedFd::borrow_raw(self.as_raw_fd()), allowing safe code to obtain an arbitraryBorrowedFd<'_>without owning the file descriptor.- Tokio's I/O driver stores a pointer to an internal allocation in the
epoll/kqueueuser data for registered file descriptors. If the underlying file descriptor is duplicated and then closed while anAsyncFdis alive, and the OS reuses that file descriptor number for a another IO resource on the same runtime, dropping the firstAsyncFdderegisters the reused file descriptor number and frees the first while the original file description remains registered inepoll, leading to a use-after-free when a readiness event fires.Starting in Tokio 1.51.6, 1.53.3, and 1.54.0,
AsyncFd::new,AsyncFd::with_interest,AsyncFd::try_new, andAsyncFd::try_with_interestare deprecated in favor of theunsafeconstructorsAsyncFd::registerandAsyncFd::register_with_interest. Callers must ensure that the file descriptor remains valid, open, and unchanged for the lifetime of theAsyncFd.See advisory page for additional details.
pchickey commented on issue #14977:
Closed by #14978
Last updated: Oct 31 2026 at 23:03 UTC