diff --git a/redox-rt/src/sys.rs b/redox-rt/src/sys.rs index c05d7c1671..f54fba8f86 100644 --- a/redox-rt/src/sys.rs +++ b/redox-rt/src/sys.rs @@ -592,13 +592,32 @@ pub fn open>(path: T, flags: usize) -> Result { let fcntl_flags = flags & syscall::O_FCNTL_MASK; let redox_path = RedoxPath::from_absolute(path.as_ref()).ok_or(Error::new(EINVAL))?; let (_, reference) = redox_path.as_parts().ok_or(Error::new(EINVAL))?; - let root_fd = FdGuard::new(openat_into_upper( - crate::current_namespace_fd()?, + + let ns_fd = crate::current_namespace_fd()?; + + // Open the scheme root using raw SYS_OPENAT (auto-assigned POSIX fd). + // This bypasses FILETABLE.insert_upper, which could collide with the + // namespace fd (ns_fd) that is not always tracked in the UPPER table. + let root_fd = syscall::openat( + ns_fd, path.as_ref(), syscall::O_DIRECTORY | O_CLOEXEC, 0, - )?); - openat_into_posix(root_fd.as_raw_fd(), reference.as_ref(), flags, fcntl_flags) + )?; + register_external_fd(root_fd)?; + + let posix_fd = syscall::openat( + root_fd, + reference.as_ref(), + flags, + fcntl_flags, + )?; + + // Close root_fd and remove from FILETABLE, then register posix_fd. + close(root_fd)?; + register_external_fd(posix_fd)?; + + Ok(posix_fd) } pub fn openat>( fd: usize,