-
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
Make RawFd implement the RawFd traits #76969
Conversation
r? @dtolnay (rust_highfive has picked a reviewer for you, use r? to override) |
I would generally assume that it is safe to take ownership of file descriptor returned from IntoRawFd. With changes here it would be unsafe, since RawFd is just an integer. |
@tmiasko That assumption would be wrong and any code which relies on it for safety is unsound, because |
Thanks for correction. I thought that trait was unsafe to implement. It is quite disappointing that it is otherwise. The search results from grep.app reveals that pretty much every single use of IntoRawFd as input bound is unsound, e.g., in wastime, nix, wayland-rs, duct.rs ... |
Glanced at some of those APIs in crates I already had a copy of on my system, and I expect that using these API with invalid RawFds would lead to program bugs, but not undefined behavior. It seems pretty uncommon to rely on on fd validity for soundness. |
Note that |
It would be nice if it were an opaque type rather than an alias, but I don't think that could be changed backwards-compatibly. |
Even a transparent newtype would have been fine, but alas. |
I agree that it's unfortunate that we made The footgunniness is a consequence of that decision we have already made and stabilized; hobbling the API because of it is just leaving us in a worst-of-all-worlds situation where we have a footgunny API that is incomplete. The previous PR and reversion in 2017 seems to have happened with basically no discussion. Going to FCP to get a discussion. @rfcbot fcp merge |
@rfcbot fcp merge (with team tags) |
Team member @withoutboats has proposed to merge this. The next step is review by the rest of the tagged team members: No concerns currently listed. Once a majority of reviewers approve (and at most 2 approvals are outstanding), this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up! See this document for info about what commands tagged team members can give me. |
It looks like the contract of
It means you could start doing this: fn take_fd(object: impl IntoRawFd) {
let fd = object.into_raw_fd();
// I'm now responsible for closing fd so I'd better do that
} let fd = object.as_raw_fd();
take_fd(fd);
// Probably going to get an `io::Error` here
object.do_something_else(); But as we've pointed out that these traits are totally safe and |
If people would rather I remove the impl of The current API correctly understands that there is no guarantee that any method of getting a But normally even doing something very wrong with an fd will "just" result in an program error, not unsoundness. A double close is not a double free, a read on a random FD is not a wild pointer dereference. They are very bad and can even in the worst case lead to terrible outcomes like irretrievable data loss, security vulnerabilities, and so on. But we do not guarantee that they will never occur in safe code the same way we do with memory vulnerabilities. The best API makes this unlikely to occur. I think even with RawFd as a type alias, we've done a pretty good job because its very rare that users actually interact with RawFd, and they hopefully know to do so with care. Mainly I have low-level APIs that need to take a |
Leaving the |
There was another attempt in #43254, again closed for the effect on |
I think we should seriously consider deprecating #[repr(transparent)]
pub struct UnixFd(pub raw::c_int); // or even just `Fd` |
I also think this is a good idea to explore, but its gonna be a pretty big transition. Not sure if there's enough energy for it. |
🔔 This is now entering its final comment period, as per the review above. 🔔 |
Makes sense to me. The footgun is weird, but I buy @withoutboats' argument: adding these impls doesn't make the footgun worse. A newtype might have been a better approach, but I don't know that it's enough of a value add to follow through on that at this point. At the very least, these impls improve the status quo and don't really make it any harder to pursue a newtype strategy later if we deemed it worth it. |
I would like to get feedback from @dtolnay before we merge this, since he participated in previous discussions and may have had concerns about these impls |
I think this is fine. @rfcbot reviewed I notice another thing we would want but can't do is |
@bors r+ |
📌 Commit 35b30e2 has been approved by |
☀️ Test successful - checks-actions, checks-azure |
This comes from the suggestion [here]. [here]: rust-lang/rust#76969 (comment)
If anyone is interested in a newtype for |
This PR makes
RawFd
implementAsRawFd
,IntoRawFd
andFromRawFd
, so it can be passed to interfaces that use one of those traits as a bound.