bootstrap: fix FD allocation to match upstream userspace fd model

The bootstrap's start.rs used libredox::call::openat which resolved to
the bootstrap's own redox_openat_v1 in initfs.rs, calling syscall::openat
(SYS_OPENAT). This let the kernel allocate POSIX FDs 0,1,2 for
stdin/stdout/stderr, but the userspace FILETABLE was never updated.

Later, exec.rs called auth.dup(b'cur-context') via redox_rt::sys::dup,
which asked the empty FILETABLE for a free slot (returning 0), then
passed it to SYS_DUP_INTO. The kernel rejected it with EEXIST because
posix_fdtbl[0] was already occupied by stdin.

Fix: use syscall::openat_into to directly specify FD slots 0,1,2 in
start.rs, and use syscall::dup_into with a computed FD index for
cur-context in exec.rs. Both bypass the FILETABLE, which is only
populated later by redox_rt::initialize_freestanding.
This commit is contained in:
Red Bear OS
2026-07-11 17:02:37 +03:00
parent f4c7552767
commit aedc416f0c
2 changed files with 7 additions and 20 deletions
+4 -2
View File
@@ -53,6 +53,8 @@ pub fn main() -> ! {
FdGuard::new(*(base_ptr as *const usize))
};
let cur_context_idx = scheme_creation_cap.as_raw_fd() + 1;
let mut kernel_schemes = KernelSchemeMap::new(kernel_scheme_infos);
let auth = kernel_schemes
@@ -60,8 +62,8 @@ pub fn main() -> ! {
.remove(&GlobalSchemes::Proc)
.expect("failed to get proc fd");
let this_thr_fd = auth
.dup(b"cur-context")
let this_thr_fd = syscall::dup_into(auth.as_raw_fd(), cur_context_idx, b"cur-context")
.map(FdGuard::new)
.expect("failed to open open_via_dup")
.to_upper()
.unwrap();
+3 -18
View File
@@ -35,10 +35,6 @@ mod offsets {
}
}
fn dbg(msg: &[u8]) {
let _ = libredox::call::write(1, msg);
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn start() -> ! {
let (text_start, text_end) = offsets::text();
@@ -46,18 +42,14 @@ pub unsafe extern "C" fn start() -> ! {
let (data_start, data_end) = offsets::data_and_bss();
let debug_fd = syscall::UPPER_FDTBL_TAG + syscall::data::GlobalSchemes::Debug as usize;
let _ = libredox::call::openat(debug_fd, "", syscall::O_RDONLY as i32, 0);
let _ = libredox::call::openat(debug_fd, "", syscall::O_WRONLY as i32, 0);
let _ = libredox::call::openat(debug_fd, "", syscall::O_WRONLY as i32, 0);
dbg(b"BS:0\n");
let _ = syscall::openat_into(debug_fd, 0, "", syscall::O_RDONLY, 0);
let _ = syscall::openat_into(debug_fd, 1, "", syscall::O_WRONLY, 0);
let _ = syscall::openat_into(debug_fd, 2, "", syscall::O_WRONLY, 0);
unsafe {
let _ = syscall::mprotect(4096, 4096, MapFlags::PROT_READ | MapFlags::MAP_PRIVATE)
.expect("mprotect failed for initfs header page");
dbg(b"BS:1\n");
let _ = syscall::mprotect(
text_start,
text_end - text_start,
@@ -65,8 +57,6 @@ pub unsafe extern "C" fn start() -> ! {
)
.expect("mprotect failed for .text");
dbg(b"BS:2\n");
let _ = syscall::mprotect(
rodata_start,
rodata_end - rodata_start,
@@ -74,8 +64,6 @@ pub unsafe extern "C" fn start() -> ! {
)
.expect("mprotect failed for .rodata");
dbg(b"BS:3\n");
let _ = syscall::mprotect(
data_start,
data_end - data_start,
@@ -83,8 +71,6 @@ pub unsafe extern "C" fn start() -> ! {
)
.expect("mprotect failed for .data/.bss");
dbg(b"BS:4\n");
let _ = syscall::mprotect(
data_end,
crate::arch::STACK_START - data_end,
@@ -93,6 +79,5 @@ pub unsafe extern "C" fn start() -> ! {
.expect("mprotect failed for rest of memory");
}
dbg(b"BS:5\n");
crate::exec::main();
}