redox-rt: refresh inherited filetable before rebuilding fd table

Backport of upstream relibc 580eab8b ('Refresh filetable data before
filetable creation'). FdTbl::from_binary_fd reconstructs an exec'd
process's fd table from the inherited filetable fd. A plain lseek(0) did
not force the backing scheme to re-materialize the current descriptor
set, so an exec'd child (e.g. a login shell) could read a STALE snapshot
and end up with a desynchronized fd -- observed as an interactive shell
whose pty-slave stdin (fd 0) returns nothing while writes to fd 1/2 work.
Issue a SYS_DUP2 'refresh' on the filetable fd before reading it.
This commit is contained in:
Red Bear OS
2026-07-18 14:53:07 +09:00
parent 029064baeb
commit dd9ae256a9
+19 -1
View File
@@ -965,7 +965,25 @@ impl FdTbl {
pub fn from_binary_fd(filetable_fd: FdGuardUpper) -> Result<Self> {
let mut fdtbl = Self::new();
let files_reader_fd = filetable_fd.as_raw_fd();
let _ = filetable_fd.lseek(0, syscall::flag::SEEK_SET);
// Refresh the inherited filetable's data before reading it, so an
// exec'd process reconstructs its fd table from the LATEST parent state
// rather than a stale snapshot. Without this, some inherited fds (e.g.
// an interactive shell's pty-slave stdin) are left desynchronized and
// reads return nothing even though writes to sibling fds work.
// Upstream relibc 580eab8b ("Refresh filetable data before filetable
// creation"). A plain lseek did not force the underlying scheme to
// re-materialize the current descriptor set.
let buf = b"refresh";
unsafe {
syscall::syscall4(
syscall::SYS_DUP2,
files_reader_fd,
files_reader_fd,
buf.as_ptr() as usize,
buf.len(),
)
}?;
fdtbl.resize(Self::DEFAULT_CAPACITY);
let mut reader = crate::proc::FileBufReader::from_fd(files_reader_fd);