Ask questionsDocument FromRawFd unsafety

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},
use std::{
    fs::{self, File},

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 Files 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.


Answer questions mahkoh

dup2 can be used to replace the meaning of the integer stored in an object implementing FromRawFd without using FromRawFd directly. E.g. let file = File::open(), dup2(xyz, file.as_raw_fd()).

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.


Related questions

Spurious NaNs produced by trig functions with valid inputs on Windows GNU toolchains hot 3
Archive all nightlies hot 3
using 'cargo install xsv' on windows 10 triggers rustc internal error hot 2
if/while Some(n) = &mut foo sugar will leak a temporary mutable borrow to current scope in particular situation hot 2
under latest MinGW, cannot link with C code using stdout hot 2
chain() make collect very slow hot 1
build an empty project failed (undefined reference to `__onexitbegin') hot 1
Invalid collision with TryFrom implementation? hot 1
Crater runs for Rust 1.38.0 hot 1
Spurious NaNs produced by trig functions with valid inputs on Windows GNU toolchains hot 1
Building LLVM with Clang fails hot 1
Internal compiler error: can't buffer lints after HIR lowering hot 1
E0373 help suggests `move async` but the correct syntax is `async move` hot 1
Tracking issue for `Option::contains` and `Result::contains` hot 1
async fn + rustfmt don't "just work" inside of RLS hot 1
Github User Rank List