From c574eda94a9b2f5b7368ecda069e57c091e07b04 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sat, 13 Dec 2025 12:53:03 +0100 Subject: [PATCH] randd: Update to redox-scheme 0.8 --- Cargo.lock | 2 +- randd/Cargo.toml | 2 +- randd/src/main.rs | 162 +++++++++++++++++++++++++++++++--------------- 3 files changed, 112 insertions(+), 54 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 787f1dfceb..967e94379a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1539,7 +1539,7 @@ dependencies = [ "rand_chacha 0.2.2", "rand_core 0.5.1", "raw-cpuid", - "redox-scheme 0.2.4", + "redox-scheme 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", "redox_syscall", "sha2", ] diff --git a/randd/Cargo.toml b/randd/Cargo.toml index 5a5c35f2b1..aecd92388a 100644 --- a/randd/Cargo.toml +++ b/randd/Cargo.toml @@ -10,7 +10,7 @@ daemon = { path = "../daemon" } redox_syscall = "0.5" libredox = "0.1.3" sha2 = "0.8" -redox-scheme = "0.2.1" +redox-scheme = "0.8.2" [target.'cfg(target_arch = "x86_64")'.dependencies] raw-cpuid = "11.0.1" diff --git a/randd/src/main.rs b/randd/src/main.rs index 569d33c38a..45bf7129c8 100644 --- a/randd/src/main.rs +++ b/randd/src/main.rs @@ -13,12 +13,14 @@ pub const MODE_READ: u16 = 0o4; #[cfg(target_arch = "x86_64")] use raw_cpuid::CpuId; -use redox_scheme::{RequestKind, SchemeMut, SignalBehavior, Socket, V2}; +use redox_scheme::scheme::SchemeSync; +use redox_scheme::{CallerCtx, OpenResult, RequestKind, SignalBehavior, Socket}; use syscall::data::Stat; use syscall::flag::EventFlags; +use syscall::schemev2::NewFdFlags; use syscall::{ - Error, Result, EBADF, EBADFD, EEXIST, ENOENT, EPERM, MODE_CHR, O_CREAT, O_EXCL, O_RDONLY, - O_RDWR, O_WRONLY, + Error, Result, EBADF, EEXIST, ENOENT, EPERM, MODE_CHR, O_CREAT, O_EXCL, O_RDONLY, O_RDWR, + O_WRONLY, }; // Create an RNG Seed to create initial seed from the rdrand intel instruction @@ -166,65 +168,104 @@ impl RandScheme { fn test_scheme_perms() { use syscall::{O_CLOEXEC, O_STAT}; + let mut ctx = CallerCtx { + pid: 0, + uid: 1, + gid: 1, + id: unsafe { std::mem::zeroed() }, // Id doesn't have a public constructor + }; + let mut scheme = RandScheme::new(); scheme.prng_stat.st_mode = MODE_CHR | 0o200; scheme.prng_stat.st_uid = 1; scheme.prng_stat.st_gid = 1; - assert!(scheme.open("/", O_RDWR, 1, 1).is_err()); - assert!(scheme.open("/", O_RDONLY, 1, 1).is_err()); + assert!(scheme.open("/", O_RDWR, &ctx).is_err()); + assert!(scheme.open("/", O_RDONLY, &ctx).is_err()); scheme.prng_stat.st_mode = MODE_CHR | 0o400; - let mut fd = scheme.open("", O_RDONLY, 1, 1).unwrap(); + let mut fd = match scheme.open("", O_RDONLY, &ctx).unwrap() { + OpenResult::ThisScheme { number, .. } => number, + _ => panic!(), + }; assert!(scheme.can_perform_op_on_fd(fd, MODE_READ).is_ok()); assert!(scheme.can_perform_op_on_fd(fd, MODE_WRITE).is_err()); - assert!(scheme.close(fd).is_ok()); + scheme.on_close(fd); - assert!(scheme.open("", O_WRONLY, 1, 1).is_err()); - assert!(scheme.open("", O_RDWR, 1, 1).is_err()); + assert!(scheme.open("", O_WRONLY, &ctx).is_err()); + assert!(scheme.open("", O_RDWR, &ctx).is_err()); scheme.prng_stat.st_mode = MODE_CHR | 0o600; - fd = scheme.open("", O_RDWR, 1, 1).unwrap(); + fd = match scheme.open("", O_RDWR, &ctx).unwrap() { + OpenResult::ThisScheme { number, .. } => number, + _ => panic!(), + }; assert!(scheme.can_perform_op_on_fd(fd, MODE_READ).is_ok()); assert!(scheme.can_perform_op_on_fd(fd, MODE_WRITE).is_ok()); - assert!(scheme.close(fd).is_ok()); + scheme.on_close(fd); - fd = scheme.open("", O_STAT, 2, 2).unwrap(); + ctx.uid = 2; + ctx.gid = 2; + fd = match scheme.open("", O_STAT, &ctx).unwrap() { + OpenResult::ThisScheme { number, .. } => number, + _ => panic!(), + }; assert!(scheme.can_perform_op_on_fd(fd, MODE_READ).is_err()); assert!(scheme.can_perform_op_on_fd(fd, MODE_WRITE).is_err()); - assert!(scheme.close(fd).is_ok()); - fd = scheme.open("", O_STAT | O_CLOEXEC, 2, 2).unwrap(); + scheme.on_close(fd); + fd = match scheme.open("", O_STAT | O_CLOEXEC, &ctx).unwrap() { + OpenResult::ThisScheme { number, .. } => number, + _ => panic!(), + }; assert!(scheme.can_perform_op_on_fd(fd, MODE_READ).is_err()); assert!(scheme.can_perform_op_on_fd(fd, MODE_WRITE).is_err()); - assert!(scheme.close(fd).is_ok()); + scheme.on_close(fd); // Try another user in group (no group perms) - fd = scheme.open("", O_STAT | O_CLOEXEC, 2, 1).unwrap(); + ctx.uid = 2; + ctx.gid = 1; + fd = match scheme.open("", O_STAT | O_CLOEXEC, &ctx).unwrap() { + OpenResult::ThisScheme { number, .. } => number, + _ => panic!(), + }; assert!(scheme.can_perform_op_on_fd(fd, MODE_READ).is_err()); assert!(scheme.can_perform_op_on_fd(fd, MODE_WRITE).is_err()); - assert!(scheme.close(fd).is_ok()); + scheme.on_close(fd); scheme.prng_stat.st_mode = MODE_CHR | 0o660; - fd = scheme.open("", O_STAT | O_CLOEXEC, 2, 1).unwrap(); + fd = match scheme.open("", O_STAT | O_CLOEXEC, &ctx).unwrap() { + OpenResult::ThisScheme { number, .. } => number, + _ => panic!(), + }; assert!(scheme.can_perform_op_on_fd(fd, MODE_READ).is_ok()); assert!(scheme.can_perform_op_on_fd(fd, MODE_WRITE).is_ok()); - assert!(scheme.close(fd).is_ok()); + scheme.on_close(fd); // Check root can do anything scheme.prng_stat.st_mode = MODE_CHR | 0o000; - fd = scheme.open("", O_STAT | O_CLOEXEC, 0, 0).unwrap(); + ctx.uid = 0; + ctx.gid = 0; + fd = match scheme.open("", O_STAT | O_CLOEXEC, &ctx).unwrap() { + OpenResult::ThisScheme { number, .. } => number, + _ => panic!(), + }; assert!(scheme.can_perform_op_on_fd(fd, MODE_READ).is_ok()); assert!(scheme.can_perform_op_on_fd(fd, MODE_WRITE).is_ok()); - assert!(scheme.close(fd).is_ok()); + scheme.on_close(fd); // Check the rand:/urandom URL (Equivalent to rand:/) scheme.prng_stat.st_mode = MODE_CHR | 0o660; - fd = scheme.open("/urandom", O_STAT | O_CLOEXEC, 2, 1).unwrap(); + ctx.uid = 2; + ctx.gid = 1; + fd = match scheme.open("/urandom", O_STAT | O_CLOEXEC, &ctx).unwrap() { + OpenResult::ThisScheme { number, .. } => number, + _ => panic!(), + }; assert!(scheme.can_perform_op_on_fd(fd, MODE_READ).is_ok()); assert!(scheme.can_perform_op_on_fd(fd, MODE_WRITE).is_ok()); - assert!(scheme.close(fd).is_ok()); + scheme.on_close(fd); } -impl SchemeMut for RandScheme { - fn open(&mut self, path: &str, flags: usize, uid: u32, gid: u32) -> Result { +impl SchemeSync for RandScheme { + fn open(&mut self, path: &str, flags: usize, ctx: &CallerCtx) -> Result { // We are only allowing // reads/writes from rand:/ and rand:/urandom - the root directory on its own is passed as an empty slice if path != "" && path != "/urandom" { @@ -238,8 +279,8 @@ impl SchemeMut for RandScheme { let open_file_info = OpenFileInfo { o_flags: flags, file_stat: self.prng_stat, - uid, - gid, + uid: ctx.uid, + gid: ctx.gid, }; if (open_file_info.o_flag_set(O_RDONLY) || open_file_info.o_flag_set(O_RDWR)) @@ -263,11 +304,21 @@ impl SchemeMut for RandScheme { self.next_fd += Wrapping(1); } } - Ok(fd.0) + Ok(OpenResult::ThisScheme { + number: fd.0, + flags: NewFdFlags::empty(), + }) } /* Resource operations */ - fn read(&mut self, file: usize, buf: &mut [u8], _offset: u64, _flags: u32) -> Result { + fn read( + &mut self, + file: usize, + buf: &mut [u8], + _offset: u64, + _flags: u32, + _ctx: &CallerCtx, + ) -> Result { // Check fd and permissions self.can_perform_op_on_fd(file, MODE_READ)?; @@ -279,7 +330,14 @@ impl SchemeMut for RandScheme { Ok(buf.len()) } - fn write(&mut self, file: usize, buf: &[u8], _offset: u64, _flags: u32) -> Result { + fn write( + &mut self, + file: usize, + buf: &[u8], + _offset: u64, + _flags: u32, + _ctx: &CallerCtx, + ) -> Result { // Check fd and permissions self.can_perform_op_on_fd(file, MODE_WRITE)?; @@ -299,7 +357,7 @@ impl SchemeMut for RandScheme { Ok(buf.len()) } - fn fchmod(&mut self, file: usize, mode: u16) -> Result { + fn fchmod(&mut self, file: usize, mode: u16, _ctx: &CallerCtx) -> Result<()> { // Check fd and permissions let file_info = self.get_fd(file)?; // only root and owner can chmod @@ -308,10 +366,10 @@ impl SchemeMut for RandScheme { } self.prng_stat.st_mode = MODE_CHR | mode; - Ok(0) + Ok(()) } - fn fchown(&mut self, file: usize, uid: u32, gid: u32) -> Result { + fn fchown(&mut self, file: usize, uid: u32, gid: u32, _ctx: &CallerCtx) -> Result<()> { // Check fd and permissions let file_info = self.get_fd(file)?; // only root and owner can chmod @@ -321,18 +379,18 @@ impl SchemeMut for RandScheme { self.prng_stat.st_uid = uid; self.prng_stat.st_gid = gid; - Ok(0) + Ok(()) } - fn fcntl(&mut self, _id: usize, _cmd: usize, _arg: usize) -> Result { + fn fcntl(&mut self, _id: usize, _cmd: usize, _arg: usize, _ctx: &CallerCtx) -> Result { // Just ignore this. Ok(0) } - fn fevent(&mut self, _id: usize, _flags: EventFlags) -> Result { + fn fevent(&mut self, _id: usize, _flags: EventFlags, _ctx: &CallerCtx) -> Result { Ok(EventFlags::EVENT_READ) } - fn fpath(&mut self, _file: usize, buf: &mut [u8]) -> Result { + fn fpath(&mut self, _file: usize, buf: &mut [u8], _ctx: &CallerCtx) -> Result { let mut i = 0; let scheme_path = b"rand"; while i < buf.len() && i < scheme_path.len() { @@ -342,26 +400,23 @@ impl SchemeMut for RandScheme { Ok(i) } - fn fstat(&mut self, file: usize, stat: &mut Stat) -> Result { + fn fstat(&mut self, file: usize, stat: &mut Stat, _ctx: &CallerCtx) -> Result<()> { // Check fd and permissions self.can_perform_op_on_fd(file, MODE_READ)?; *stat = self.prng_stat.clone(); - Ok(0) + Ok(()) } - fn close(&mut self, file: usize) -> Result { + fn on_close(&mut self, file: usize) { // just remove the file descriptor from the open descriptors - match self.open_descriptors.remove(&file) { - Some(_) => Ok(0), - None => Err(Error::new(EBADFD)), - } + self.open_descriptors.remove(&file); } } fn daemon(daemon: daemon::Daemon) -> ! { - let socket = Socket::::create("rand").expect("randd: failed to create rand scheme"); + let socket = Socket::create("rand").expect("randd: failed to create rand scheme"); let mut scheme = RandScheme::new(); @@ -373,13 +428,16 @@ fn daemon(daemon: daemon::Daemon) -> ! { .next_request(SignalBehavior::Restart) .expect("error reading packet") { - let RequestKind::Call(call) = request.kind() else { - continue; - }; - let response = call.handle_scheme_mut(&mut scheme); - socket - .write_responses(&[response], SignalBehavior::Restart) - .expect("error writing packet"); + match request.kind() { + RequestKind::Call(call) => { + let response = call.handle_sync(&mut scheme); + socket + .write_response(response, SignalBehavior::Restart) + .expect("error writing packet"); + } + RequestKind::OnClose { id } => scheme.on_close(id), + _ => {} + } } process::exit(0);