-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
Tracking Issue for RFC 3128: I/O Safety #87074
Comments
I've now posted an initial PR implementing the proposal in the RFC: #87329 |
Since we now use the niche feature on Unix it's unsound to use SockRef::from(-1), but it can be done without any unsafe. This change adds an assertion to ensure we hit this soundness issue. Still need to wait on the I/O safety RFC: https://github.com/rust-lang/rfcs/blob/master/text/3128-io-safety.md Tracking issue: rust-lang/rust#87074 Implementation pr: rust-lang/rust#87329
Since we now use the niche feature on Unix it's unsound to use SockRef::from(-1), but it can be done without any unsafe. This change adds an assertion to ensure we hit this soundness issue. Still need to wait on the I/O safety RFC: https://github.com/rust-lang/rfcs/blob/master/text/3128-io-safety.md Tracking issue: rust-lang/rust#87074 Implementation pr: rust-lang/rust#87329
Since we now use the niche feature on Unix it's unsound to use SockRef::from(-1), but it can be done without any unsafe. This change adds an assertion to ensure we hit this soundness issue. Still need to wait on the I/O safety RFC: https://github.com/rust-lang/rfcs/blob/master/text/3128-io-safety.md Tracking issue: rust-lang/rust#87074 Implementation pr: rust-lang/rust#87329
Since we now use the niche feature on Unix it's unsound to use SockRef::from(-1), but it can be done without any unsafe. This change adds an assertion to ensure we hit this soundness issue. Still need to wait on the I/O safety RFC: https://github.com/rust-lang/rfcs/blob/master/text/3128-io-safety.md Tracking issue: rust-lang/rust#87074 Implementation pr: rust-lang/rust#87329
Introduce `OwnedFd` and `BorrowedFd`, and the `AsFd` trait, and implementations of `AsFd`, `From<OwnedFd>` and `From<T> for OwnedFd` for relevant types, along with Windows counterparts for handles and sockets. Tracking issue: - <rust-lang#87074> RFC: - <https://github.com/rust-lang/rfcs/blob/master/text/3128-io-safety.md>
…joshtriplett I/O safety. Introduce `OwnedFd` and `BorrowedFd`, and the `AsFd` trait, and implementations of `AsFd`, `From<OwnedFd>` and `From<T> for OwnedFd` for relevant types, along with Windows counterparts for handles and sockets. Tracking issue: <rust-lang#87074> RFC: <https://github.com/rust-lang/rfcs/blob/master/text/3128-io-safety.md> Highlights: - The doc comments at the top of library/std/src/os/unix/io/mod.rs and library/std/src/os/windows/io/mod.rs - The new types and traits in library/std/src/os/unix/io/fd.rs and library/std/src/os/windows/io/handle.rs - The removal of the `RawHandle` struct the Windows impl, which had the same name as the `RawHandle` type alias, and its functionality is now folded into `Handle`. Managing five levels of wrapping (File wraps sys::fs::File wraps sys::fs::FileDesc wraps OwnedFd wraps RawFd, etc.) made for a fair amount of churn and verbose as/into/from sequences in some places. I've managed to simplify some of them, but I'm open to ideas here. r? `@joshtriplett`
The implementation PR is now merged! |
Examples of using the I/O safety types and traits in Rust Nightly in real-world codebases, with all tests passing: |
Hi, I'm on the Windows team at Microsoft. Perhaps this deserves a separate issue, but posting here for now...
But this doesn't make sense for In fact, in user mode (which is all we care about for this target), the only valid owned handle values are > 0--negative handle values are reserved for kernel handles (which are inaccessible to user mode) and pseudo handles, neither of which can be closed. So the documentation should be updated. But I also think the use of This also gives you a much bigger niche if you choose to use it. It would be reasonable to stick with NonNull for now and optimize as a second step, even after stabilization. But you can't strengthen the assertions after stabilization.
|
Related question: does Just my 2c. |
That makes sense, however there's another dimension: it's a somewhat established convention to use One thing we could easily do though would be to While you're here 😄 would you be able to authoritatively state that NULL is never returned, as an error or as a valid handle, from functions that use
Indeed, |
Ah, yes. I'm not familiar with the V4L2 APIs myself, but this sounds similar to the case with |
For example,
Both of these functions use |
I'd say this is a bit of a grey area. You can already do extremely dangerous (including memory safety) things just by writing to things like It leaves the judgment call how airtight you want your wrappers to be to the developers. E.g. for a
I think the shared file description thing is a bit of a problem in general. E.g. you could write a thing that very very carefully pokes around on the block device underlying a mounted filesystem (e.g. only fiddling around with a boot sector which isn't used at runtime) and if everything goes right your system won't blow up. But if there's another thing accessing the same file description through a duped file descriptor and only does random seeks all the time (which in itself would appear to be perfectly harmless) then this will go horribly horribly wrong. |
I think we've addressed these gray areas at this point.
The only time Rust code can assume it has exclusive access to a file description is if it created a file descriptor for itself and fully encapsulated it, including not implementing |
I've now opened #97837 to add documentation about |
This is specific to Edit: I see the PR already tries to generalize beyond that Regarding things that take |
I'd still suggest stating somewhere in the documentation that if safety of your type depends on some properties (filesystem, device driver, etc.) of the underlying file descriptor that can not hold for a reasonable FD (where "reasonable" means "not |
On Unix-family platforms, All open file descriptors are suitable for |
I see several overlapping cases
|
I'm having difficulty translating these into specific areas in the documentation that could be modified, and specific points to make. Would anyone be able to suggest wording here?
I'm not aware of any system calls which behave like this. Does anyone have specific examples of this? |
https://lore.kernel.org/lkml/1276525077-26347-1-git-send-email-tytso@mit.edu/ The ioctl 2 has different meanings for regular files and some character device drivers. That was about a kernel bug where the kernel misinterpreted it, but they fixed that which still means that it can cause different behavior (or error out because the ioctl is not supported) depending on what file descriptor you call it on. |
APIs for
|
The 2 remaining items in the Steps / History at the top are completed:
The 2 Unresolved Questions are questions are questions for the future, and not questions that I expect need to be answered for this feature to proceed. |
…o-safety, r=joshtriplett Implement stabilization of `#[feature(io_safety)]`. Implement stabilization of [I/O safety], aka `#[feature(io_safety)]`. Fixes rust-lang#87074. [I/O safety]: https://github.com/rust-lang/rfcs/blob/master/text/3128-io-safety.md
…o-safety, r=joshtriplett Implement stabilization of `#[feature(io_safety)]`. Implement stabilization of [I/O safety], aka `#[feature(io_safety)]`. Fixes rust-lang#87074. [I/O safety]: https://github.com/rust-lang/rfcs/blob/master/text/3128-io-safety.md
Thanks to @RalfJung for helping me understand this space and @joshtriplett for mentoring and reviews, and many others for discussions and comments that helped shape this. For the next chapter in the I/O safety story: once this feature reaches stable, the next step is to begin adding trait implementations for |
This migrates terminal_size from using libc directly to using rustix, which eliminates a few unsafe blocks and manual error handling. It does also add one new unsafe block, though this is because `terminal_size_using_fd` is a public safe function that has a `RawFd` argument. With [I/O safety], which is expected to be [stabilized in Rust 1.63], there will be new guidance saying be that [such functions should be unsafe]. It's not urgent to make any changes for this right now though. [I/O safety]: https://github.com/rust-lang/rfcs/blob/master/text/3128-io-safety.md [expected to be stabilized in Rust 1.63]: rust-lang/rust#87074 [such functions should be unsafe]: https://doc.rust-lang.org/nightly/std/os/unix/io/index.html
This migrates terminal_size from using libc directly to using rustix, which eliminates a few unsafe blocks and manual error handling. It does also add one new unsafe block, though this is because `terminal_size_using_fd` is a public safe function that has a `RawFd` argument. With [I/O safety], which is expected to be [stabilized in Rust 1.63], there will be new guidance saying be that [such functions should be unsafe]. It's not urgent to make any changes for this right now though. [I/O safety]: https://github.com/rust-lang/rfcs/blob/master/text/3128-io-safety.md [stabilized in Rust 1.63]: rust-lang/rust#87074 [such functions should be unsafe]: https://doc.rust-lang.org/nightly/std/os/unix/io/index.html
This migrates terminal_size from using libc directly to using rustix, which eliminates a few unsafe blocks and manual error handling. It does also add one new unsafe block, though this is because `terminal_size_using_fd` is a public safe function that has a `RawFd` argument. With [I/O safety], which is expected to be [stabilized in Rust 1.63], there will be new guidance saying be that [such functions should be unsafe]. It's not urgent to make any changes for this right now though. This also updates the minimum Rust version to 1.48, which is about as old as the previous minimum Rust version was when it was last updated. [I/O safety]: https://github.com/rust-lang/rfcs/blob/master/text/3128-io-safety.md [stabilized in Rust 1.63]: rust-lang/rust#87074 [such functions should be unsafe]: https://doc.rust-lang.org/nightly/std/os/unix/io/index.html
…r=joshtriplett Define a dedicated error type for `HandleOrNull` and `HandleOrInvalid`. Define `NullHandleError` and `InvalidHandleError` types, that implement std::error::Error, and use them as the error types in `HandleOrNull` and `HandleOrInvalid`, This addresses [this concern](rust-lang/rust#87074 (comment)). This is the same as #95387. r? `@joshtriplett`
Feature gate:
#![feature(io_safety)]
This is a tracking issue for RFC 3128: I/O Safety.
Raw OS handles such as
RawFd
andRawHandle
have hazards similar to raw pointers; they may be bogus or may dangle, leading to broken encapsulation boundaries and code whose behavior is impossible to bound in general.Introduce a concept of I/O safety, and introduce a new set of types and traits, led by
OwnedFd
andBorrowedFd
, to support it.Public API
The public API on UNIX platforms consists of the types
OwnedFd
andBorrowedFd
, the traitAsFd
, and implementations ofAsFd
,Into<OwnedFd>
, andFrom<OwnedFd>
for various types (such as files and sockets).The public API on Windows platforms consists of two sets of parallel types and traits and impls for
OwnedHandle
,OwnedSocket
,BorrowedHandle
,BorrowedSocket
, etc.Steps / History
Unresolved Questions
The text was updated successfully, but these errors were encountered: