From c1aa76bf3c952a63685ec7e743f8eea30afb2e67 Mon Sep 17 00:00:00 2001 From: Jeremy Soller <jackpot51@gmail.com> Date: Mon, 14 Feb 2022 09:57:24 -0700 Subject: [PATCH] Fill in st_dev in fstat --- src/syscall/fs.rs | 21 +++++++++++++++++++++ src/syscall/mod.rs | 7 +++++-- src/syscall/validate.rs | 10 ++++++++++ 3 files changed, 36 insertions(+), 2 deletions(-) diff --git a/src/syscall/fs.rs b/src/syscall/fs.rs index a271e5d3..0dee4987 100644 --- a/src/syscall/fs.rs +++ b/src/syscall/fs.rs @@ -448,6 +448,27 @@ pub fn frename(fd: FileHandle, path: &str) -> Result<usize> { } } +/// File status +pub fn fstat(fd: FileHandle, stat: &mut Stat) -> Result<usize> { + let file = { + let contexts = context::contexts(); + let context_lock = contexts.current().ok_or(Error::new(ESRCH))?; + let context = context_lock.read(); + context.get_file(fd).ok_or(Error::new(EBADF))? + }; + + let description = file.description.read(); + + let scheme = { + let schemes = scheme::schemes(); + let scheme = schemes.get(description.scheme).ok_or(Error::new(EBADF))?; + Arc::clone(&scheme) + }; + // Fill in scheme number as device number + stat.st_dev = description.scheme.into() as u64; + scheme.fstat(description.number, stat) +} + pub fn funmap_old(virtual_address: usize) -> Result<usize> { if virtual_address == 0 { Ok(0) diff --git a/src/syscall/mod.rs b/src/syscall/mod.rs index 3955af57..cb64c4c1 100644 --- a/src/syscall/mod.rs +++ b/src/syscall/mod.rs @@ -25,7 +25,7 @@ pub use self::process::*; pub use self::time::*; pub use self::validate::*; -use self::data::{Map, SigAction, TimeSpec}; +use self::data::{Map, SigAction, Stat, TimeSpec}; use self::error::{Error, Result, ENOSYS}; use self::flag::{CloneFlags, MapFlags, PhysmapFlags, WaitFlags}; use self::number::*; @@ -74,7 +74,10 @@ pub fn syscall(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize, bp: u }, _ => file_op_slice(a, fd, validate_slice(c as *const u8, d)?), } - SYS_ARG_MSLICE => file_op_mut_slice(a, fd, validate_slice_mut(c as *mut u8, d)?), + SYS_ARG_MSLICE => match a { + SYS_FSTAT => fstat(fd, unsafe { validate_ref_mut(c as *mut Stat, d)? }), + _ => file_op_mut_slice(a, fd, validate_slice_mut(c as *mut u8, d)?), + }, _ => match a { SYS_CLOSE => close(fd), SYS_DUP => dup(fd, validate_slice(c as *const u8, d)?).map(FileHandle::into), diff --git a/src/syscall/validate.rs b/src/syscall/validate.rs index c5f3e23e..2aac27a4 100644 --- a/src/syscall/validate.rs +++ b/src/syscall/validate.rs @@ -41,6 +41,16 @@ pub unsafe fn validate_ref<T>(ptr: *const T, size: usize) -> Result<&'static T> } } +/// Convert a pointer and length to mutable reference, if valid +pub unsafe fn validate_ref_mut<T>(ptr: *mut T, size: usize) -> Result<&'static mut T> { + if size == mem::size_of::<T>() { + validate(ptr as usize, mem::size_of::<T>(), false)?; + Ok(&mut *ptr) + } else { + Err(Error::new(EINVAL)) + } +} + /// Convert a pointer and length to slice, if valid //TODO: Mark unsafe pub fn validate_slice<T>(ptr: *const T, len: usize) -> Result<&'static [T]> { -- GitLab