Description
Currently the documentation of FromRawFd uses vague language:
This function is also unsafe as the primitives currently returned have the contract that they are the sole owner of the file descriptor they are wrapping. Usage of this function could accidentally allow violating this contract which can cause memory unsafety in code that relies on it being true.
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:
use nix::{
fcntl::{open, OFlag},
sys::stat::Mode,
unistd::dup2,
};
use std::{
fs::{self, File},
io::Read,
os::unix::io::AsRawFd,
};
fn main() {
fs::write("a", "a").unwrap();
fs::write("b", "b").unwrap();
let mut a = File::open("a").unwrap();
let b = open("b", OFlag::O_RDONLY, Mode::empty()).unwrap();
dup2(b, a.as_raw_fd()).unwrap();
let mut a_contents = String::new();
a.read_to_string(&mut a_contents).unwrap();
assert!(a_contents == "b");
}
This is the simplest way but you can also use close
on the returned file descriptor and then call File::open
again to create two File
s with the same underlying file descriptor.
What about performing the various fcntl
operation on the value returned by as_raw_fd
? Can these also cause memory unsafety? Must all methods operating on file descriptors in nix be marked unsafe because as_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 keep from_raw_fd
unsafe and these should be documented. Otherwise from_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.