You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
rustix::thread::unshare(UnshareFlags::FILES) can violate io_safety #1479
unshare the file descriptor table using this API that's not marked unsafe
open a file, create a pipe, whatever you like, get an OwnedFd
OwnedFd is Send so you can move it to another thread, but the fd won't exist there
even worse, if another unrelated fd with the same number gets created in the receiving thread and then you drop the moved fd from the thread then it'll close the other fd, leaving a dangling reference, potentially in far-away and unrelated code
also nice, but not technically UB: by moving the OwnedFd out of the first thread, you'll have effectively leaked the original fd
unshare is a pretty powerful API. I wouldn't be surprised if some of the other variants caused issues (although we are protected by the kernel requiring single-threaded processes for many of them).
Here's a reproducer:
use std::thread::spawn;use rustix::{fs::{OFlags,Mode, open, fstat}, thread::{unshare,UnshareFlags}};fnmain(){let broken_fd = spawn(|| {unshare(UnshareFlags::FILES).unwrap();open("/",OFlags::PATH,Mode::empty()).unwrap()}).join().unwrap();// fstat() is always successful on a valid fd, right?fstat(broken_fd).unwrap();}
[package]
name = "fd-unsafe"version = "0.1.0"edition = "2024"
[dependencies]
rustix = { version = "1.0.7", features = ["fs", "thread"] }
Activity
Deprecate `unshare` and add `unshare_unsafe`.
sunfishcode commentedon Jun 28, 2025
Thanks for the report! Your analysis sounds correct to me. I've now submitted #1482 to fix this.
Deprecate `unshare` and add `unshare_unsafe`. (#1482)
Deprecate `unshare` and add `unshare_unsafe`. (#1482)
Deprecate `unshare` and add `unshare_unsafe`. (#1482)