From a540890851ff2c213fff040436badeddc14e1578 Mon Sep 17 00:00:00 2001 From: Red Bear OS Date: Mon, 13 Jul 2026 22:42:31 +0300 Subject: [PATCH] relibc: fix open() to bypass FILETABLE.insert_upper collision The open() function used openat_into_upper which calls FILETABLE.insert_upper() to allocate UPPER fd slots. This can collide with the namespace fd (ns_fd) that is stored in DYNAMIC_PROC_INFO, causing the kernel to overwrite the namespace fd entry. All subsequent open() calls then resolve to the wrong scheme. Fix: use raw SYS_OPENAT syscalls (which auto-assign POSIX fds) and register them with register_external_fd, bypassing insert_upper entirely. --- redox-rt/src/sys.rs | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) 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,