refactor: Adapt to userspace fd allocation

This commit is contained in:
Ibuki Omatsu
2026-07-01 14:20:05 +00:00
committed by Jeremy Soller
parent 29a1f4f8ec
commit 372b200f26
16 changed files with 308 additions and 241 deletions
Generated
+63 -61
View File
@@ -13,7 +13,7 @@ dependencies = [
"pcid",
"redox-scheme",
"redox_event",
"redox_syscall 0.8.1",
"redox_syscall 0.9.0",
"scheme-utils",
"spin",
]
@@ -48,7 +48,7 @@ dependencies = [
"plain",
"redox-scheme",
"redox_event",
"redox_syscall 0.8.1",
"redox_syscall 0.9.0",
"ron",
"rustc-hash",
"scheme-utils",
@@ -80,7 +80,7 @@ dependencies = [
"log",
"pcid",
"redox_event",
"redox_syscall 0.8.1",
"redox_syscall 0.9.0",
]
[[package]]
@@ -193,7 +193,7 @@ dependencies = [
"libc",
"libredox",
"redox-scheme",
"redox_syscall 0.8.1",
"redox_syscall 0.9.0",
"scheme-utils",
]
@@ -225,7 +225,7 @@ dependencies = [
"fdt 0.2.0-alpha1",
"libredox",
"redox_event",
"redox_syscall 0.8.1",
"redox_syscall 0.9.0",
]
[[package]]
@@ -423,7 +423,7 @@ dependencies = [
"libredox",
"log",
"redox-log",
"redox_syscall 0.8.1",
"redox_syscall 0.9.0",
]
[[package]]
@@ -514,7 +514,7 @@ dependencies = [
"libc",
"libredox",
"redox-scheme",
"redox_syscall 0.8.1",
"redox_syscall 0.9.0",
]
[[package]]
@@ -582,7 +582,7 @@ dependencies = [
"log",
"partitionlib",
"redox-scheme",
"redox_syscall 0.8.1",
"redox_syscall 0.9.0",
"scheme-utils",
]
@@ -599,7 +599,7 @@ dependencies = [
"log",
"redox-ioctl",
"redox-scheme",
"redox_syscall 0.8.1",
"redox_syscall 0.9.0",
"scheme-utils",
]
@@ -610,7 +610,7 @@ dependencies = [
"daemon",
"libredox",
"redox-scheme",
"redox_syscall 0.8.1",
"redox_syscall 0.9.0",
"scheme-utils",
]
@@ -667,7 +667,7 @@ dependencies = [
"log",
"pcid",
"redox_event",
"redox_syscall 0.8.1",
"redox_syscall 0.9.0",
]
[[package]]
@@ -747,7 +747,7 @@ dependencies = [
"ransid",
"redox-scheme",
"redox_event",
"redox_syscall 0.8.1",
"redox_syscall 0.9.0",
"scheme-utils",
]
@@ -768,7 +768,7 @@ dependencies = [
"ransid",
"redox-scheme",
"redox_event",
"redox_syscall 0.8.1",
"redox_syscall 0.9.0",
"scheme-utils",
"serde",
"toml",
@@ -1027,7 +1027,7 @@ dependencies = [
"fdt 0.1.5",
"libredox",
"log",
"redox_syscall 0.8.1",
"redox_syscall 0.9.0",
"ron",
]
@@ -1072,7 +1072,7 @@ dependencies = [
"log",
"pcid",
"redox_event",
"redox_syscall 0.8.1",
"redox_syscall 0.9.0",
]
[[package]]
@@ -1087,7 +1087,7 @@ dependencies = [
"pcid",
"redox-scheme",
"redox_event",
"redox_syscall 0.8.1",
"redox_syscall 0.9.0",
"scheme-utils",
"spin",
]
@@ -1111,7 +1111,7 @@ dependencies = [
"range-alloc",
"redox-scheme",
"redox_event",
"redox_syscall 0.8.1",
"redox_syscall 0.9.0",
"void",
]
@@ -1135,7 +1135,7 @@ dependencies = [
"libc",
"libredox",
"plain",
"redox_syscall 0.8.1",
"redox_syscall 0.9.0",
"serde",
"serde_json",
"toml",
@@ -1152,7 +1152,7 @@ dependencies = [
"log",
"orbclient",
"redox-scheme",
"redox_syscall 0.8.1",
"redox_syscall 0.9.0",
"scheme-utils",
]
@@ -1177,7 +1177,7 @@ dependencies = [
"rand 0.10.1",
"redox-scheme",
"redox_event",
"redox_syscall 0.8.1",
"redox_syscall 0.9.0",
"scheme-utils",
]
@@ -1204,7 +1204,7 @@ dependencies = [
"libredox",
"pcid",
"redox_event",
"redox_syscall 0.8.1",
"redox_syscall 0.9.0",
]
[[package]]
@@ -1239,15 +1239,15 @@ checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66"
[[package]]
name = "libredox"
version = "0.1.17"
version = "0.1.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f02ab6bace2054fb888a3c16f990117b579d14a3088e472d63c6011fa185c9d3"
checksum = "c943259e342f1e06ff2da7a83eabdfe7f92ce10262688dbf1895ff0b3e6e4652"
dependencies = [
"bitflags 2.11.1",
"ioslice",
"libc",
"plain",
"redox_syscall 0.8.1",
"redox_syscall 0.9.0",
]
[[package]]
@@ -1271,7 +1271,7 @@ dependencies = [
"driver-block",
"libredox",
"redox_event",
"redox_syscall 0.8.1",
"redox_syscall 0.9.0",
]
[[package]]
@@ -1296,7 +1296,7 @@ dependencies = [
"daemon",
"libredox",
"redox-scheme",
"redox_syscall 0.8.1",
"redox_syscall 0.9.0",
"scheme-utils",
]
@@ -1353,7 +1353,7 @@ dependencies = [
"redox-log",
"redox-scheme",
"redox_event",
"redox_syscall 0.8.1",
"redox_syscall 0.9.0",
"scheme-utils",
"smoltcp",
]
@@ -1409,7 +1409,7 @@ dependencies = [
"partitionlib",
"pcid",
"redox_event",
"redox_syscall 0.8.1",
"redox_syscall 0.9.0",
"smallvec 1.15.1",
]
@@ -1433,9 +1433,9 @@ checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c"
[[package]]
name = "orbclient"
version = "0.4.1"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d6a81febac10e8d8e15c33b67a4a88807d587d9ac5689392239b6b83d9fa2ae"
checksum = "ccbf30fea937f00c68caf77cd6fdf2c6c0616ea88e629c42b56670c0978f8cee"
dependencies = [
"libc",
"libredox",
@@ -1536,7 +1536,7 @@ dependencies = [
"pico-args",
"plain",
"redox-scheme",
"redox_syscall 0.8.1",
"redox_syscall 0.9.0",
"scheme-utils",
"serde",
]
@@ -1549,10 +1549,11 @@ dependencies = [
"common",
"config",
"daemon",
"libredox",
"log",
"pcid",
"pico-args",
"redox_syscall 0.8.1",
"redox_syscall 0.9.0",
"serde",
"toml",
]
@@ -1638,7 +1639,7 @@ dependencies = [
"orbclient",
"redox-scheme",
"redox_event",
"redox_syscall 0.8.1",
"redox_syscall 0.9.0",
]
[[package]]
@@ -1660,7 +1661,7 @@ dependencies = [
"libredox",
"redox-scheme",
"redox_event",
"redox_syscall 0.8.1",
"redox_syscall 0.9.0",
"redox_termios",
"scheme-utils",
]
@@ -1694,7 +1695,7 @@ dependencies = [
"indexmap",
"libredox",
"redox-scheme",
"redox_syscall 0.8.1",
"redox_syscall 0.9.0",
"scheme-utils",
"slab",
]
@@ -1800,7 +1801,7 @@ dependencies = [
"rand_core 0.5.1",
"raw-cpuid",
"redox-scheme",
"redox_syscall 0.8.1",
"redox_syscall 0.9.0",
"scheme-utils",
"sha2",
]
@@ -1862,10 +1863,10 @@ dependencies = [
[[package]]
name = "redox-ioctl"
version = "0.1.0"
source = "git+https://gitlab.redox-os.org/redox-os/relibc.git#0813a23294ba082037cf09d0afd2643e9e77b4ba"
source = "git+https://gitlab.redox-os.org/redox-os/relibc.git#e8d4ce4822d721d4dafaafa8c04dcbfe626622e7"
dependencies = [
"drm-sys",
"redox_syscall 0.8.1",
"redox_syscall 0.9.0",
]
[[package]]
@@ -1881,19 +1882,19 @@ dependencies = [
[[package]]
name = "redox-scheme"
version = "0.11.1"
version = "0.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ecd26e368655cb4fdda914512c46c5640221ebe5fa6df5da19c941b9f06ed153"
checksum = "5928b2f572e06a74e9c210fcacf15b70b8ffa6fdb3d8650f4601b83c12fe194b"
dependencies = [
"libredox",
"redox_syscall 0.8.1",
"redox_syscall 0.9.0",
]
[[package]]
name = "redox_event"
version = "0.4.7"
version = "0.4.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8c07d0d6d291e3a951bd847b1cd4af32fc6243d64116cf7702838c02797688b7"
checksum = "c5018d583d6d2f5499352aea8d177e9067d1eb03ab17c78169d5ba7a30001b15"
dependencies = [
"bitflags 2.11.1",
"libredox",
@@ -1910,8 +1911,9 @@ dependencies = [
[[package]]
name = "redox_syscall"
version = "0.8.1"
source = "git+https://gitlab.redox-os.org/redox-os/syscall.git#79cb6d9057642be31623677458a93aa88145864f"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c5102a6aaa05aa011a238e178e6bca86d2cb56fc9f586d37cb80f5bca6e07759"
dependencies = [
"bitflags 2.11.1",
]
@@ -1931,7 +1933,7 @@ dependencies = [
"libredox",
"qemu-exit",
"redox_event",
"redox_syscall 0.8.1",
"redox_syscall 0.9.0",
"redox_termios",
]
@@ -2007,7 +2009,7 @@ dependencies = [
"log",
"pcid",
"redox_event",
"redox_syscall 0.8.1",
"redox_syscall 0.9.0",
]
[[package]]
@@ -2022,7 +2024,7 @@ dependencies = [
"log",
"pcid",
"redox_event",
"redox_syscall 0.8.1",
"redox_syscall 0.9.0",
]
[[package]]
@@ -2061,7 +2063,7 @@ dependencies = [
"log",
"redox-scheme",
"redox_event",
"redox_syscall 0.8.1",
"redox_syscall 0.9.0",
"scheme-utils",
"spin",
]
@@ -2072,7 +2074,7 @@ version = "0.0.0"
dependencies = [
"libredox",
"redox-scheme",
"redox_syscall 0.8.1",
"redox_syscall 0.9.0",
]
[[package]]
@@ -2462,7 +2464,7 @@ dependencies = [
"log",
"orbclient",
"plain",
"redox_syscall 0.8.1",
"redox_syscall 0.9.0",
"rehid",
"smallvec 1.15.1",
"xhcid",
@@ -2474,7 +2476,7 @@ version = "0.1.0"
dependencies = [
"common",
"log",
"redox_syscall 0.8.1",
"redox_syscall 0.9.0",
"xhcid",
]
@@ -2488,7 +2490,7 @@ dependencies = [
"libredox",
"plain",
"redox_event",
"redox_syscall 0.8.1",
"redox_syscall 0.9.0",
"thiserror 2.0.18",
"xhcid",
]
@@ -2526,7 +2528,7 @@ dependencies = [
"orbclient",
"pcid",
"redox_event",
"redox_syscall 0.8.1",
"redox_syscall 0.9.0",
]
[[package]]
@@ -2553,7 +2555,7 @@ dependencies = [
"orbclient",
"ransid",
"redox_event",
"redox_syscall 0.8.1",
"redox_syscall 0.9.0",
]
[[package]]
@@ -2569,7 +2571,7 @@ dependencies = [
"log",
"pcid",
"redox_event",
"redox_syscall 0.8.1",
"redox_syscall 0.9.0",
"spin",
"static_assertions",
"thiserror 2.0.18",
@@ -2588,7 +2590,7 @@ dependencies = [
"log",
"pcid",
"redox_event",
"redox_syscall 0.8.1",
"redox_syscall 0.9.0",
"static_assertions",
"thiserror 2.0.18",
]
@@ -2608,7 +2610,7 @@ dependencies = [
"orbclient",
"pcid",
"redox_event",
"redox_syscall 0.8.1",
"redox_syscall 0.9.0",
"spin",
"static_assertions",
"virtio-core",
@@ -2625,7 +2627,7 @@ dependencies = [
"libredox",
"log",
"pcid",
"redox_syscall 0.8.1",
"redox_syscall 0.9.0",
"static_assertions",
"virtio-core",
]
@@ -2965,7 +2967,7 @@ dependencies = [
"plain",
"redox-scheme",
"redox_event",
"redox_syscall 0.8.1",
"redox_syscall 0.9.0",
"regex",
"scheme-utils",
"serde",
@@ -3002,7 +3004,7 @@ dependencies = [
"daemon",
"libredox",
"redox-scheme",
"redox_syscall 0.8.1",
"redox_syscall 0.9.0",
"scheme-utils",
]
+4 -7
View File
@@ -85,19 +85,19 @@ edid = "0.3.0" #TODO: edid is abandoned, fork it and maintain?
fdt = "0.1.5"
libc = "0.2.181"
log = "0.4"
libredox = "0.1.17"
libredox = "0.1.18"
orbclient = "0.4.1"
psf-rs = "2.2.0"
parking_lot = "0.12"
pico-args = "0.5"
plain = "0.2.3"
ransid = "0.4"
redox_event = "0.4.7"
redox_event = "0.4.8"
redox-ioctl = { git = "https://gitlab.redox-os.org/redox-os/relibc.git" }
redox-log = { git = "https://gitlab.redox-os.org/redox-os/redox-log.git" }
redox-rt = { git = "https://gitlab.redox-os.org/redox-os/relibc.git", default-features = false }
redox-scheme = "0.11.1"
redox_syscall = { version = "0.8.1", features = ["std"] }
redox-scheme = { version = "0.11.2", default-features = false }
redox_syscall = { version = "0.9.0", features = ["std"] }
redox_termios = "0.1.3"
ron = "0.8.1"
serde = { version = "1", features = ["derive"] }
@@ -117,8 +117,5 @@ missing_safety_doc = "warn" #TODO: set to deny when all safety documentation is
precedence = "deny"
unused_io_amount = "deny"
[patch.crates-io]
redox_syscall = { git = "https://gitlab.redox-os.org/redox-os/syscall.git" }
[patch."https://gitlab.redox-os.org/redox-os/relibc.git"]
#redox-ioctl = { path = "../../relibc/source/redox-ioctl" }
+8 -8
View File
@@ -41,7 +41,7 @@ checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2"
[[package]]
name = "generic-rt"
version = "0.1.0"
source = "git+https://gitlab.redox-os.org/redox-os/relibc.git#0813a23294ba082037cf09d0afd2643e9e77b4ba"
source = "git+https://gitlab.redox-os.org/redox-os/relibc.git#e8d4ce4822d721d4dafaafa8c04dcbfe626622e7"
[[package]]
name = "goblin"
@@ -77,9 +77,9 @@ checksum = "459427e2af2b9c839b132acb702a1c654d95e10f8c326bfc2ad11310e458b1c5"
[[package]]
name = "libredox"
version = "0.1.17"
version = "0.1.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f02ab6bace2054fb888a3c16f990117b579d14a3088e472d63c6011fa185c9d3"
checksum = "c943259e342f1e06ff2da7a83eabdfe7f92ce10262688dbf1895ff0b3e6e4652"
dependencies = [
"bitflags",
"libc",
@@ -151,7 +151,7 @@ checksum = "436d45c2b6a5b159d43da708e62b25be3a4a3d5550d654b72216ade4c4bfd717"
[[package]]
name = "redox-rt"
version = "0.1.0"
source = "git+https://gitlab.redox-os.org/redox-os/relibc.git#0813a23294ba082037cf09d0afd2643e9e77b4ba"
source = "git+https://gitlab.redox-os.org/redox-os/relibc.git#e8d4ce4822d721d4dafaafa8c04dcbfe626622e7"
dependencies = [
"bitflags",
"generic-rt",
@@ -165,9 +165,9 @@ dependencies = [
[[package]]
name = "redox-scheme"
version = "0.11.1"
version = "0.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ecd26e368655cb4fdda914512c46c5640221ebe5fa6df5da19c941b9f06ed153"
checksum = "5928b2f572e06a74e9c210fcacf15b70b8ffa6fdb3d8650f4601b83c12fe194b"
dependencies = [
"libredox",
"redox_syscall",
@@ -175,9 +175,9 @@ dependencies = [
[[package]]
name = "redox_syscall"
version = "0.8.0"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7c7591fa2c6b601dfcfe5f043f65a1c39fcdf50efefcd7f1572e538c1f4b398d"
checksum = "c5102a6aaa05aa011a238e178e6bca86d2cb56fc9f586d37cb80f5bca6e07759"
dependencies = [
"bitflags",
]
+3 -3
View File
@@ -12,12 +12,12 @@ hashbrown = { version = "0.15", default-features = false, features = [
"default-hasher",
] }
linked_list_allocator = "0.10"
libredox = { version = "0.1.17", default-features = false, features = ["protocol"] }
libredox = { version = "0.1.18", default-features = false, features = ["protocol"] }
log = { version = "0.4", default-features = false }
plain = "0.2"
redox-initfs = { path = "../initfs", default-features = false }
redox_syscall = "0.8.0"
redox-scheme = { version = "0.11.1", default-features = false }
redox_syscall = "0.9.0"
redox-scheme = { version = "0.11.2", default-features = false }
redox-path = "0.3.1"
slab = { version = "0.4.9", default-features = false }
arrayvec = { version = "0.7.6", default-features = false }
+45 -25
View File
@@ -6,10 +6,11 @@ use core::str::FromStr;
use hashbrown::HashMap;
use redox_scheme::Socket;
use syscall::CallFlags;
use libredox::protocol::O_CLOEXEC;
use syscall::data::{GlobalSchemes, KernelSchemeInfo};
use syscall::flag::{O_CLOEXEC, O_RDONLY, O_STAT};
use syscall::{EINTR, Error};
use syscall::flag::{O_DIRECTORY, O_RDONLY, O_STAT};
use syscall::CallFlags;
use syscall::{Error, EINTR};
use redox_rt::proc::*;
@@ -53,6 +54,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 +63,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();
@@ -70,7 +73,7 @@ pub fn main() -> ! {
let mut env_bytes = [0_u8; 4096];
let mut envs = {
let fd = FdGuard::new(
syscall::openat(
redox_rt::sys::openat(
kernel_schemes
.get(GlobalSchemes::Sys)
.expect("failed to get sys fd")
@@ -205,12 +208,16 @@ pub fn main() -> ! {
// from this point, this_thr_fd is no longer valid
const CWD: &[u8] = b"/scheme/initfs";
let cwd_fd = FdGuard::new(
syscall::openat(initns_fd.as_raw_fd(), "/scheme/initfs", O_STAT, 0)
.expect("failed to open cwd fd"),
)
.to_upper()
.unwrap();
let initfs_root_fd = initns_fd
.openat_into_upper("/scheme/initfs", O_DIRECTORY, 0)
.expect("failed to open initfs root fd");
let cwd_fd = initfs_root_fd
.openat_into_upper("", O_STAT, 0)
.expect("failed to open cwd fd");
let filetable_binary_fd = init_thr_fd
.dup_into_upper(b"filetable-binary")
.expect("faild to create filetable-binary fd");
let extrainfo = ExtraInfo {
cwd: Some(CWD),
sigprocmask: 0,
@@ -220,16 +227,18 @@ pub fn main() -> ! {
proc_fd: init_proc_fd.as_raw_fd(),
ns_fd: Some(initns_fd.take()),
cwd_fd: Some(cwd_fd.as_raw_fd()),
filetable_fd: Some(filetable_binary_fd.as_raw_fd()),
same_process: true,
};
let exe_path = "/scheme/initfs/bin/init";
let exe_reference = "bin/init";
let image_file = FdGuard::new(
syscall::openat(extrainfo.ns_fd.unwrap(), exe_path, O_RDONLY | O_CLOEXEC, 0)
.expect("failed to open init"),
)
.to_upper()
.unwrap();
let image_file = initfs_root_fd
.openat_into_upper(exe_reference, O_RDONLY | O_CLOEXEC, 0)
.expect("failed to open init");
drop(initfs_root_fd);
let FexecResult::Interp {
path: interp_path,
@@ -244,22 +253,33 @@ pub fn main() -> ! {
&extrainfo,
None,
)
.ok()
.flatten()
.expect("failed to execute init");
// According to elf(5), PT_INTERP requires that the interpreter path be
// null-terminated. Violating this should therefore give the "format error" ENOEXEC.
let interp_cstr = CStr::from_bytes_with_nul(&interp_path).expect("interpreter not valid C str");
let interp_file = FdGuard::new(
syscall::openat(
let interp_path = interp_cstr.to_str().expect("interpreter not UTF-8");
let root_fd = FdGuard::new(
redox_rt::sys::openat_into_upper(
extrainfo.ns_fd.unwrap(), // initns, not initfs!
interp_cstr.to_str().expect("interpreter not UTF-8"),
interp_path,
O_RDONLY | O_CLOEXEC,
0,
)
.expect("failed to open dynamic linker"),
.expect("failed to open root fd"),
)
.to_upper()
.unwrap();
let redox_path = redox_path::RedoxPath::from_absolute(interp_path)
.expect("interpreter path is not a Scheme-rooted path");
let (_, reference) = redox_path
.as_parts()
.expect("redox_path is not scheme root path");
let interp_file = root_fd
.openat_into_upper(reference.as_ref(), O_RDONLY | O_CLOEXEC, 0)
.expect("failed to open dynamic linker");
fexec_impl(
interp_file,
@@ -286,7 +306,7 @@ pub(crate) fn spawn(
inner: impl FnOnce(FdGuard, Socket, FdGuard, KernelSchemeMap) -> !,
) -> (FdGuard, FdGuard, KernelSchemeMap, FdGuard) {
let read = FdGuard::new(
syscall::openat(
redox_rt::sys::openat(
kernel_schemes
.get(GlobalSchemes::Pipe)
.expect("failed to get pipe fd")
@@ -300,7 +320,7 @@ pub(crate) fn spawn(
// The write pipe will not inherit O_CLOEXEC, but is closed by the daemon later.
let write = FdGuard::new(
syscall::dup(read.as_raw_fd(), b"write").expect("failed to open sync write pipe"),
redox_rt::sys::dup(read.as_raw_fd(), b"write").expect("failed to open sync write pipe"),
);
match fork_impl(&ForkArgs::Init {
@@ -332,7 +352,7 @@ pub(crate) fn spawn(
)
};
loop {
match syscall::call_ro(
match redox_rt::sys::sys_call_ro(
read.as_raw_fd(),
fd_bytes,
CallFlags::FD | CallFlags::FD_UPPER,
+20 -20
View File
@@ -10,12 +10,11 @@ use redox_initfs::{InitFs, Inode, InodeDir, InodeKind, InodeStruct};
use redox_rt::proc::FdGuard;
use redox_scheme::{
CallerCtx, OpenResult, RequestKind,
scheme::{SchemeState, SchemeSync},
CallerCtx, OpenResult, RequestKind,
};
use redox_scheme::{SignalBehavior, Socket};
use syscall::PAGE_SIZE;
use syscall::data::Stat;
use syscall::dirent::DirEntry;
use syscall::dirent::DirentBuf;
@@ -23,6 +22,7 @@ use syscall::dirent::DirentKind;
use syscall::error::*;
use syscall::flag::*;
use syscall::schemev2::NewFdFlags;
use syscall::PAGE_SIZE;
enum Handle {
Node(Node),
@@ -391,9 +391,9 @@ pub fn run(bytes: &'static [u8], sync_pipe: FdGuard, socket: Socket) -> ! {
let cap_fd = socket
.create_this_scheme_fd(0, new_id, 0, 0)
.expect("failed to issue initfs root fd");
let _ = syscall::call_rw(
let _ = redox_rt::sys::sys_call_wo(
sync_pipe.as_raw_fd(),
&mut cap_fd.to_ne_bytes(),
&cap_fd.to_ne_bytes(),
CallFlags::FD,
&[],
);
@@ -446,14 +446,19 @@ pub unsafe extern "C" fn redox_write_v1(fd: usize, ptr: *const u8, len: usize) -
#[unsafe(no_mangle)]
pub unsafe fn redox_dup_v1(fd: usize, buf: *const u8, len: usize) -> isize {
Error::mux(syscall::dup(fd, unsafe {
Error::mux(redox_rt::sys::dup(fd, unsafe {
core::slice::from_raw_parts(buf, len)
})) as isize
}
#[unsafe(no_mangle)]
pub unsafe fn redox_fcntl_v0(fd: usize, cmd: usize, arg: usize) -> isize {
Error::mux(redox_rt::sys::fcntl(fd, cmd, arg)) as isize
}
#[unsafe(no_mangle)]
pub extern "C" fn redox_close_v1(fd: usize) -> isize {
Error::mux(syscall::close(fd)) as isize
Error::mux(redox_rt::sys::close(fd)) as isize
}
#[unsafe(no_mangle)]
@@ -466,20 +471,15 @@ pub unsafe extern "C" fn redox_sys_call_v0(
metadata_len: usize,
) -> isize {
let flags = CallFlags::from_bits_retain(flags);
let read = flags.contains(syscall::CallFlags::READ);
let write = flags.contains(syscall::CallFlags::WRITE);
let payload = unsafe { core::slice::from_raw_parts_mut(payload, payload_len) };
let metadata = unsafe { core::slice::from_raw_parts(metadata, metadata_len) };
let result = if flags.contains(CallFlags::READ) {
let payload = unsafe { core::slice::from_raw_parts_mut(payload, payload_len) };
if flags.contains(CallFlags::WRITE) {
syscall::call_rw(fd, payload, flags, metadata)
} else {
syscall::call_ro(fd, payload, flags, metadata)
}
} else {
let payload = unsafe { core::slice::from_raw_parts(payload, payload_len) };
syscall::call_wo(fd, payload, flags, metadata)
};
Error::mux(result) as isize
Error::mux(match (read, write) {
(true, true) => redox_rt::sys::sys_call_rw(fd, payload, flags, metadata),
(true, false) => redox_rt::sys::sys_call_ro(fd, payload, flags, metadata),
(false, true) => redox_rt::sys::sys_call_wo(fd, payload, flags, metadata),
(false, false) => redox_rt::sys::sys_call(fd, payload, flags, metadata),
}) as isize
}
+146 -99
View File
@@ -10,14 +10,14 @@ use libredox::protocol::{NsDup, NsPermissions};
use log::{error, warn};
use redox_path::RedoxPath;
use redox_path::RedoxScheme;
use redox_rt::proc::FdGuard;
use redox_rt::proc::{FdGuard, FdGuardUpper};
use redox_scheme::{
CallerCtx, OpenResult, RequestKind, Response, SendFdRequest, SignalBehavior, Socket,
scheme::{SchemeState, SchemeSync},
CallerCtx, OpenResult, RequestKind, Response, SendFdRequest, SignalBehavior, Socket,
};
use syscall::Stat;
use syscall::dirent::{DirEntry, DirentBuf, DirentKind};
use syscall::{CallFlags, FobtainFdFlags, error::*, schemev2::NewFdFlags};
use syscall::Stat;
use syscall::{error::*, schemev2::NewFdFlags, CallFlags, FobtainFdFlags};
#[derive(Debug, Clone)]
struct Namespace {
@@ -92,6 +92,7 @@ impl SchemeRegister {
enum Handle {
Access(NamespaceAccess),
Register(SchemeRegister),
OtherScheme { name: String, fd: Rc<FdGuard> },
List(NamespaceAccess),
}
@@ -100,7 +101,7 @@ pub struct NamespaceScheme<'sock> {
handles: HashMap<usize, Handle>,
root_namespace: Namespace,
next_id: usize,
scheme_creation_cap: FdGuard,
scheme_creation_cap: Rc<FdGuardUpper>,
}
const HIGH_PERMISSIONS: NsPermissions = NsPermissions::SCHEME_CREATE;
@@ -109,14 +110,14 @@ impl<'sock> NamespaceScheme<'sock> {
pub fn new(
socket: &'sock Socket,
schemes: HashMap<String, Arc<FdGuard>>,
scheme_creation_cap: FdGuard,
scheme_creation_cap: FdGuardUpper,
) -> Self {
Self {
socket,
handles: HashMap::new(),
root_namespace: Namespace { schemes },
next_id: 0,
scheme_creation_cap,
scheme_creation_cap: Rc::new(scheme_creation_cap),
}
}
@@ -137,23 +138,55 @@ impl<'sock> NamespaceScheme<'sock> {
}
fn open_namespace_resource(
&self,
&mut self,
ns_access: &NamespaceAccess,
reference: &str,
redox_path: RedoxPath<'_>,
_flags: usize,
_fcntl_flags: u32,
_ctx: &CallerCtx,
) -> Result<usize> {
match reference {
let (_scheme, reference) = redox_path.as_parts().ok_or(Error::new(EINVAL))?;
match reference.as_ref() {
"scheme-creation-cap" => {
if !ns_access.has_permission(NsPermissions::SCHEME_CREATE) {
error!("Permission denied to get scheme creation capability");
return Err(Error::new(EACCES));
}
Ok(syscall::dup(self.scheme_creation_cap.as_raw_fd(), &[])?)
let new_id = self.next_id;
self.next_id += 1;
self.handles.insert(new_id, Handle::List(ns_access.clone()));
let resource_id = self.next_id;
self.next_id += 1;
let dup_fd = self.scheme_creation_cap.dup(&[])?;
self.handles.insert(
resource_id,
Handle::OtherScheme {
name: redox_path.to_string(),
fd: Rc::new(dup_fd),
},
);
Ok(resource_id)
}
"" => {
if !ns_access.has_permission(NsPermissions::LIST) {
error!("Permission denied to list schemes in namespace root");
return Err(Error::new(EACCES));
}
let new_id = self.next_id;
self.next_id += 1;
self.handles.insert(new_id, Handle::List(ns_access.clone()));
Ok(new_id)
}
_ => {
error!("Unknown special reference: {}", reference);
error!("Unknown special reference: {}", reference.as_ref());
return Err(Error::new(EINVAL));
}
}
@@ -163,26 +196,19 @@ impl<'sock> NamespaceScheme<'sock> {
&self,
ns: &Namespace,
scheme: &str,
reference: &str,
flags: usize,
fcntl_flags: u32,
ctx: &CallerCtx,
) -> Result<usize> {
_ctx: &CallerCtx,
) -> Result<FdGuard> {
let Some(cap_fd) = ns.get_scheme_fd(scheme) else {
log::info!("Scheme {:?} not found in namespace", scheme);
return Err(Error::new(ENODEV));
};
let scheme_fd = syscall::openat_with_filter(
cap_fd.as_raw_fd(),
reference,
flags,
fcntl_flags as usize,
ctx.uid,
ctx.gid,
)?;
if flags & syscall::O_DIRECTORY == 0 {
return Err(Error::new(EISDIR));
}
Ok(scheme_fd)
cap_fd.dup(&[])
}
fn fork_namespace(&mut self, namespace: Rc<RefCell<Namespace>>, names: &[u8]) -> Result<usize> {
@@ -211,6 +237,10 @@ impl<'sock> NamespaceScheme<'sock> {
self.next_id += 1;
Ok(next_id)
}
fn on_close(&mut self, id: usize) {
let _ = self.handles.remove(&id);
}
}
impl<'sock> SchemeSync for NamespaceScheme<'sock> {
@@ -222,55 +252,83 @@ impl<'sock> SchemeSync for NamespaceScheme<'sock> {
fcntl_flags: u32,
ctx: &CallerCtx,
) -> Result<OpenResult> {
let ns_access = {
let handle = self.handles.get(&fd);
match handle {
Some(Handle::Access(access)) => Some(access),
_ => None,
}
}
.ok_or_else(|| {
error!("Namespace with ID {} not found", fd);
let handle = self.handles.get(&fd).cloned().ok_or_else(|| {
error!("Handle with ID {} not found", fd);
Error::new(ENOENT)
})?;
let redox_path = RedoxPath::from_absolute(path).ok_or(Error::new(EINVAL))?;
let (scheme, reference) = redox_path.as_parts().ok_or(Error::new(EINVAL))?;
let res_fd = match scheme.as_ref() {
"namespace" => self.open_namespace_resource(
ns_access,
reference.as_ref(),
flags,
fcntl_flags,
ctx,
)?,
"" => {
if !ns_access.has_permission(NsPermissions::LIST) {
error!("Permission denied to list schemes in namespace {}", fd);
return Err(Error::new(EACCES));
match handle {
Handle::Access(ns_access) => {
let redox_path = RedoxPath::from_absolute(path).ok_or(Error::new(EINVAL))?;
let (scheme, _reference) = redox_path.as_parts().ok_or(Error::new(EINVAL))?;
match scheme.as_ref() {
"namespace" | "" => {
let new_id = self.open_namespace_resource(
&ns_access,
redox_path,
flags,
fcntl_flags,
ctx,
)?;
Ok(OpenResult::ThisScheme {
number: new_id,
flags: NewFdFlags::empty(),
})
}
_ => {
let res_fd = self.open_scheme_resource(
&ns_access.namespace.borrow(),
scheme.as_ref(),
flags,
ctx,
)?;
Ok(OpenResult::OtherScheme { fd: res_fd.take() })
}
}
let new_id = self.next_id;
self.next_id += 1;
self.handles.insert(new_id, Handle::List(ns_access.clone()));
return Ok(OpenResult::ThisScheme {
number: new_id,
flags: NewFdFlags::empty(),
});
}
_ => self.open_scheme_resource(
&ns_access.namespace.borrow(),
scheme.as_ref(),
reference.as_ref(),
flags,
fcntl_flags,
ctx,
)?,
};
Handle::List(ns_access) => {
if path.is_empty() || path == "." {
let new_id = self.next_id;
self.next_id += 1;
Ok(OpenResult::OtherScheme { fd: res_fd })
self.handles.insert(new_id, Handle::List(ns_access.clone()));
Ok(OpenResult::ThisScheme {
number: new_id,
flags: NewFdFlags::empty(),
})
} else {
error!("Cannot open a path under List handle: {}", path);
Err(Error::new(EINVAL))
}
}
Handle::OtherScheme {
name: saved_path_str,
fd: target_fd,
} => {
let saved_path =
RedoxPath::from_absolute(&saved_path_str).ok_or(Error::new(syscall::EPROTO))?;
let (_scheme, reference) =
saved_path.as_parts().ok_or(Error::new(syscall::EPROTO))?;
if reference.as_ref() == path {
Ok(OpenResult::OtherScheme {
fd: target_fd.dup(&[])?.take(),
})
} else {
error!(
"Resource path mismatch: expected {}, got {}",
reference.as_ref(),
path,
);
Err(Error::new(EINVAL))
}
}
_ => {
error!("Handle {} is not accessible for openat", fd);
Err(Error::new(EBADF))
}
}
}
fn dup(&mut self, id: usize, buf: &[u8], _ctx: &CallerCtx) -> Result<OpenResult> {
@@ -288,7 +346,6 @@ impl<'sock> SchemeSync for NamespaceScheme<'sock> {
let new_id = match kind {
NsDup::ForkNs => {
let ns = ns_access.namespace.clone();
let _ = ns_access;
self.fork_namespace(ns, payload)?
}
NsDup::ShrinkPermissions => self.shrink_permissions(
@@ -326,7 +383,7 @@ impl<'sock> SchemeSync for NamespaceScheme<'sock> {
})
}
fn unlinkat(&mut self, fd: usize, path: &str, flags: usize, ctx: &CallerCtx) -> Result<()> {
fn unlinkat(&mut self, fd: usize, path: &str, _flags: usize, _ctx: &CallerCtx) -> Result<()> {
let ns_access = self.get_ns_access(fd).ok_or_else(|| {
error!("Namespace with ID {} not found", fd);
Error::new(ENOENT)
@@ -335,31 +392,20 @@ impl<'sock> SchemeSync for NamespaceScheme<'sock> {
let redox_path = RedoxPath::from_absolute(path).ok_or(Error::new(EINVAL))?;
let (scheme, reference) = redox_path.as_parts().ok_or(Error::new(EINVAL))?;
if reference.as_ref().is_empty() {
if !ns_access.has_permission(NsPermissions::DELETE) {
error!("Permission denied to remove scheme for namespace {}", fd);
return Err(Error::new(EACCES));
}
match ns.remove_scheme(scheme.as_ref()) {
Some(_) => return Ok(()),
None => {
error!("Scheme {} not found in namespace", scheme);
return Err(Error::new(ENODEV));
}
if !reference.as_ref().is_empty() {
return Err(Error::new(EXDEV));
}
if !ns_access.has_permission(NsPermissions::DELETE) {
error!("Permission denied to remove scheme for namespace {}", fd);
return Err(Error::new(EACCES));
}
match ns.remove_scheme(scheme.as_ref()) {
Some(_) => Ok(()),
None => {
error!("Scheme {} not found in namespace", scheme);
Err(Error::new(ENODEV))
}
}
let Some(cap_fd) = ns.get_scheme_fd(scheme.as_ref()) else {
error!("Scheme {} not found in namespace", scheme);
return Err(Error::new(ENODEV));
};
syscall::unlinkat_with_filter(cap_fd.as_raw_fd(), reference, flags, ctx.uid, ctx.gid)?;
Ok(())
}
fn on_close(&mut self, id: usize) {
self.handles.remove(&id);
}
fn on_sendfd(&mut self, sendfd_request: &SendFdRequest) -> Result<usize> {
@@ -387,7 +433,7 @@ impl<'sock> SchemeSync for NamespaceScheme<'sock> {
}
let mut new_fd = usize::MAX;
if let Err(e) = sendfd_request.obtain_fd(
&self.socket,
self.socket,
FobtainFdFlags::UPPER_TBL,
core::slice::from_mut(&mut new_fd),
) {
@@ -422,12 +468,11 @@ impl<'sock> SchemeSync for NamespaceScheme<'sock> {
}
if let Err(err) = buf.entry(DirEntry {
kind: DirentKind::Unspecified,
name: &name.clone(),
name: name,
inode: 0,
next_opaque_id: i as u64 + 1,
}) {
if err.errno == EINVAL && i > opaque_offset {
// POSIX allows partial result of getdents
break;
} else {
return Err(err);
@@ -440,7 +485,7 @@ impl<'sock> SchemeSync for NamespaceScheme<'sock> {
fn fstat(&mut self, id: usize, stat: &mut Stat, _ctx: &CallerCtx) -> Result<()> {
let resource_stat = match self.handles.get(&id).ok_or(Error::new(EBADF))? {
Handle::List(_) => Stat {
Handle::List(_) | Handle::OtherScheme { .. } => Stat {
st_mode: 0o444 | syscall::MODE_DIR,
st_uid: 0,
st_gid: 0,
@@ -502,6 +547,9 @@ pub fn run(
schemes: HashMap<String, Arc<FdGuard>>,
scheme_creation_cap: FdGuard,
) -> ! {
let scheme_creation_cap = scheme_creation_cap
.to_upper()
.expect("Failed to move scheme creation cap into upper");
let mut state = SchemeState::new();
let mut scheme = NamespaceScheme::new(&socket, schemes, scheme_creation_cap);
@@ -513,7 +561,7 @@ pub fn run(
.socket
.create_this_scheme_fd(0, new_id, 0, 0)
.expect("nsmgr: failed to create namespace fd");
let _ = syscall::call_wo(
let _ = redox_rt::sys::sys_call_wo(
sync_pipe.as_raw_fd(),
&cap_fd.to_ne_bytes(),
CallFlags::FD,
@@ -551,7 +599,6 @@ pub fn run(
break;
}
}
_ => (),
}
}
+4 -4
View File
@@ -65,7 +65,7 @@ pub fn run(write_fd: FdGuard, socket: Socket, auth: FdGuard, event: FdGuard) ->
.expect("failed to issue procmgr root fd");
log::debug!("process manager started");
let _ = syscall::call_wo(
let _ = redox_rt::sys::sys_call_wo(
write_fd.as_raw_fd(),
&cap_fd.to_ne_bytes(),
CallFlags::FD,
@@ -549,7 +549,7 @@ enum WaitpidTarget {
struct RawEventQueue(FdGuard);
impl RawEventQueue {
pub fn new(cap_fd: usize) -> Result<Self> {
syscall::openat(cap_fd, "", O_CREAT, 0)
redox_rt::sys::openat(cap_fd, "", O_CREAT, 0)
.map(FdGuard::new)
.map(Self)
}
@@ -2541,8 +2541,8 @@ impl<'a> ProcScheme<'a> {
// Useful for debugging memory leaks.
log::trace!("NEXT FD: {}", {
let nextfd = syscall::dup(0, &[]).unwrap();
let _ = syscall::close(nextfd);
let nextfd = redox_rt::sys::dup(0, &[]).unwrap();
let _ = redox_rt::sys::close(nextfd);
nextfd
});
log::trace!("{} processes", self.processes.len());
+3 -3
View File
@@ -48,9 +48,9 @@ pub unsafe extern "C" fn start() -> ! {
// NOTE: Assuming the debug scheme root fd is always placed at this position
let debug_fd = syscall::UPPER_FDTBL_TAG + syscall::data::GlobalSchemes::Debug as usize;
let _ = syscall::openat(debug_fd, "", syscall::O_RDONLY, 0); // stdin
let _ = syscall::openat(debug_fd, "", syscall::O_WRONLY, 0); // stdout
let _ = syscall::openat(debug_fd, "", syscall::O_WRONLY, 0); // stderr
let _ = syscall::openat_into(debug_fd, 0, "", syscall::O_RDONLY, 0); // stdin
let _ = syscall::openat_into(debug_fd, 1, "", syscall::O_WRONLY, 0); // stdout
let _ = syscall::openat_into(debug_fd, 2, "", syscall::O_WRONLY, 0); // stderr
unsafe {
let _ = syscall::mprotect(4096, 4096, MapFlags::PROT_READ | MapFlags::MAP_PRIVATE)
+2 -2
View File
@@ -7,8 +7,8 @@ use std::os::unix::process::CommandExt;
use std::process::Command;
use libredox::Fd;
use redox_scheme::Socket;
use redox_scheme::scheme::{SchemeAsync, SchemeSync};
use redox_scheme::Socket;
unsafe fn get_fd(var: &str) -> RawFd {
let fd: RawFd = std::env::var(var).unwrap().parse().unwrap();
@@ -98,7 +98,7 @@ impl SchemeDaemon {
/// Notify the process that the scheme daemon is ready to accept requests.
pub fn ready_with_fd(self, cap_fd: Fd) -> syscall::Result<()> {
syscall::call_wo(
libredox::call::call_wo(
self.write_pipe.as_raw_fd() as usize,
&cap_fd.into_raw().to_ne_bytes(),
syscall::CallFlags::FD,
+2 -2
View File
@@ -295,14 +295,14 @@ pub fn acquire_port_io_rights() -> Result<()> {
extern "C" {
fn redox_cur_thrfd_v0() -> usize;
}
let kernel_fd = syscall::dup(unsafe { redox_cur_thrfd_v0() }, b"open_via_dup")?;
let kernel_fd = libredox::call::dup(unsafe { redox_cur_thrfd_v0() }, b"open_via_dup")?;
let res = libredox::call::call_wo(
kernel_fd,
&[],
syscall::CallFlags::empty(),
&[ProcSchemeVerb::Iopl as u64],
);
let _ = syscall::close(kernel_fd);
let _ = libredox::call::close(kernel_fd);
res?;
Ok(())
}
+1 -1
View File
@@ -8,12 +8,12 @@ edition = "2018"
fdt.workspace = true
log.workspace = true
ron.workspace = true
redox_syscall.workspace = true
libredox = { workspace = true, default-features = false, features = ["std", "call"] }
amlserde = { path = "../amlserde" }
common = { path = "../common" }
daemon = { path = "../../daemon" }
redox_syscall = "0.8.1"
[lints]
workspace = true
+1
View File
@@ -13,6 +13,7 @@ pico-args.workspace = true
redox_syscall.workspace = true
serde.workspace = true
toml.workspace = true
libredox.workspace = true
config = { path = "../../config" }
common = { path = "../common" }
+1 -1
View File
@@ -94,7 +94,7 @@ fn main() -> Result<()> {
#[allow(deprecated, reason = "we can't yet move this to init")]
daemon::Daemon::spawn(command);
syscall::close(channel_fd as usize).unwrap();
libredox::call::close(channel_fd as usize).unwrap();
}
Ok(())
+3 -4
View File
@@ -70,16 +70,15 @@ impl Service {
},
ServiceType::Scheme(scheme) => {
let mut new_fd = usize::MAX;
loop {
match syscall::call_ro(
match libredox::call::call_ro(
read_pipe.as_raw_fd() as usize,
unsafe { plain::as_mut_bytes(&mut new_fd) },
syscall::CallFlags::FD | syscall::CallFlags::FD_UPPER,
&[],
) {
Err(syscall::Error {
errno: syscall::EINTR,
}) => continue,
Err(err) if err.is_interrupt() => continue,
Ok(0) => {
eprintln!("init: {command:?} exited without notifying readiness");
return;
+2 -1
View File
@@ -229,7 +229,8 @@ impl RandScheme {
}
#[test]
fn test_scheme_perms() {
use syscall::{O_CLOEXEC, O_STAT};
use libredox::protocol::O_CLOEXEC;
use syscall::O_STAT;
let mut ctx = CallerCtx {
pid: 0,