-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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
Document FromRawFd unsafety #72175
Comments
That would be a breaking change. |
You're right. Maybe the correct way would be to add a new trait Assuming that If we assume this then the second idea (a new safe default function |
#74699 would provide a more concrete source of UB if FromRawFd is misused. |
I don't think there is any UB here. The constructor is guarded with an assert. But it does split the issue in two parts:
|
dup2 can be used to replace the meaning of the integer stored in an object implementing FromRawFd without using FromRawFd directly. E.g. In any case, I maintain that there is no unsafety and that there never will be. The value of the standard unix functions dup2, fcntl, etc. being safe to use is much higher than the value of being able to do some obscure optimization based on sole ownership. If there even is such an optimization. |
FromRawFd was made unsafe in 2705051. The justification was providing a safe version of mmap. Since nobody has been able to do this since, the justification seems to have been misguided. |
It's actually more ridiculous than that. The referenced issue rust-lang/rfcs#1043 contains an elementary mistake: fn main() {
let f = File::create(...);
let f2 = File::from_raw_fd(f.as_raw_fd());
let m = MemoryMap::new(f).unwrap();
drop(f2);
// Use m and segfault...
} Since mmap performs the equivalent of |
I think the problem is: it is possible to break Rust program by external means. |
My understanding of the meaning of I agree with the assessment above about And, misuse of file descriptors can break encapsulation. A library in Rust can have non- It's an arbitrary choice, because it's not about UB of the Rust code itself, but it feels within the spirit of Rust's
(This ignores that as of #76969, |
At the time that comment was written, nix also had a safe Specifically,
Yeah, that is also what I said back then and I still think that way. If you want to resolve this officially, we probably need a T-libs and/or T-lang FCP: ultimately the question is if we want to consider file descriptors as "a resource that can be owned and exclusively controlled as part of a type's safety invariant" (if yes, we need to make |
Thanks for the suggestion; I may be interested in doing this. I wrote up a draft of an RFC here:
As a caveat, I haven't written a Rust RFC before, and I'd appreciate any feedback! Edit: The URL to the draft changed; see below. |
Looks like a good start!
The point is that the "raw" versions are not owned, right? Creating them is safe. Turning them into something that can actually access a file/socket/... is unsafe.
I don't think this quite fits. That page documents aspects of the operational semantics of Rust. Your RFC does not touch the operational semantics, it only affects the logic that one can use to reason about type invariants in Rust. Using the terminology of safety and validity, the UB page is all about validity invariants, but your RFC is about safety invariants. Another way to think about this is that we do not want to add new UB to Rust for this, that seems wrong. We just want to provide the option of claiming ownership of a file descriptor. These are two wholly unrelated concepts. We should definitely document this somewhere in the reference, but I do not think this is the right page. |
Thanks! Thinking about this more, I've tentatively concluded that ownership is not the right concept for this RFC. The really important thing is to avoid accidental aliasing. There are some interesting questions about ownership here, but I think we can treat those as a separate issue along with the discussion of how #76969 interacts with ownership.
Makes sense. I updated the doc to work in terms of the standard library's description of the With both these changes, I've now substantially revised the RFC in terms of what I'm calling "I/O safety", and it now has a new name: https://github.com/sunfishcode/rfcs/blob/main/text/0000-io-safety.md |
Without having read it in full detail yet, that looks great to me. :) I think the details of the wording are best hashed out during the RFC process. I don't understand the part in the "Say that handles can be owned" section though. That example is not in contradiction with saying that handles can be owned, just like the existence of raw pointers is not in contradiction with saying that memory can be owned. To the contrary: the way that the stdlib achieves the property of "I/O safety" is through ownership of file handles. If one were to set out and formally prove I/O safety, ownership of file handles would be a necessary part of the story -- just like when we set out to formally prove memory safety, ownership of memory is necessarily part of the story, despite the fact that the Rust ownership and borrowing system does not even have a notion of "memory". |
My idea there was to say that this RFC itself doesn't define ownership of resource handles, however it doesn't preclude it either. To hopefully reduce confusion, I've now removed that section and added some ideas to the Unresolved questions section. |
Based on feedback in rust-lang/socket2#218, I've now updated the proposal to add a |
Since the last comment here, #93562 removes the language quoted above about memory unsafety and adds new language describing what |
Currently the documentation of FromRawFd uses vague language:
What kind of memory safety issues is this quote referring to?
Using the nix crate it is not hard to write FromRawFd using only safe code:
This is the simplest way but you can also use
close
on the returned file descriptor and then callFile::open
again to create twoFile
s with the same underlying file descriptor.What about performing the various
fcntl
operation on the value returned byas_raw_fd
? Can these also cause memory unsafety? Must all methods operating on file descriptors in nix be marked unsafe becauseas_raw_fd
is a safe function?Given the current state of the
AsRawFd
and the existence of other safe crates which allow manipulating the returned file descriptor, there should be very good reasons to keepfrom_raw_fd
unsafe and these should be documented. Otherwisefrom_raw_fd
should be made safe with a clear warning that odd (but not unsafe) things might happen if the assumptions about ownership are violated.The text was updated successfully, but these errors were encountered: