diff --git a/kernel-hal/src/common/user.rs b/kernel-hal/src/common/user.rs index 987a736d..42ebd929 100644 --- a/kernel-hal/src/common/user.rs +++ b/kernel-hal/src/common/user.rs @@ -6,6 +6,8 @@ use core::fmt::{Debug, Formatter}; use core::marker::PhantomData; use core::ops::{Deref, DerefMut}; +use crate::VirtAddr; + /// Wapper of raw pointer from user space. #[repr(C)] pub struct UserPtr { @@ -78,10 +80,11 @@ impl UserPtr { /// Checks if `size` is enough to save a value of `T`, /// then constructs a user pointer from its value `addr`. pub fn from_addr_size(addr: usize, size: usize) -> Result { - if size < core::mem::size_of::() { - return Err(Error::BufferTooSmall); + if size >= core::mem::size_of::() { + Ok(Self::from(addr)) + } else { + Err(Error::BufferTooSmall) } - Ok(Self::from(addr)) } /// Returns true if the pointer is null. @@ -100,21 +103,19 @@ impl UserPtr { } /// Returns the raw pointer. - pub fn as_ptr(&self) -> *mut T { - self.ptr + pub fn as_addr(&self) -> VirtAddr { + self.ptr as _ } /// Checks avaliability of the user pointer. /// /// Returns [`Ok(())`] if it is neither null nor unaligned, pub fn check(&self) -> Result<()> { - if self.ptr.is_null() { - return Err(Error::InvalidPointer); + if !self.ptr.is_null() && (self.ptr as usize) % core::mem::align_of::() == 0 { + Ok(()) + } else { + Err(Error::InvalidPointer) } - if (self.ptr as usize) % core::mem::align_of::() != 0 { - return Err(Error::InvalidPointer); - } - Ok(()) } } @@ -134,11 +135,11 @@ impl UserPtr { /// Same as [`read`](Self::read), /// but returns [`None`] when pointer is null. pub fn read_if_not_null(&self) -> Result> { - if self.ptr.is_null() { - return Ok(None); + if !self.ptr.is_null() { + Ok(Some(self.read()?)) + } else { + Ok(None) } - let value = self.read()?; - Ok(Some(value)) } /// Copies elements into a new [`Vec`]. @@ -206,23 +207,23 @@ impl UserPtr { /// Same as [`write`](Self::write), /// but does nothing and returns [`Ok`] when pointer is null. pub fn write_if_not_null(&mut self, value: T) -> Result<()> { - if self.ptr.is_null() { - return Ok(()); + if !self.ptr.is_null() { + self.write(value) + } else { + Ok(()) } - self.write(value) } /// Copies `values.len() * size_of` bytes from `values` to `self`. /// The source and destination may not overlap. pub fn write_array(&mut self, values: &[T]) -> Result<()> { - if values.is_empty() { - return Ok(()); + if !values.is_empty() { + self.check()?; + unsafe { + self.ptr + .copy_from_nonoverlapping(values.as_ptr(), values.len()) + }; } - self.check()?; - unsafe { - self.ptr - .copy_from_nonoverlapping(values.as_ptr(), values.len()) - }; Ok(()) } } @@ -337,20 +338,14 @@ impl IoVec

{ } pub fn as_slice(&self) -> Result<&[u8]> { - if self.ptr.is_null() { - return Err(Error::InvalidVectorAddress); - } - let slice = unsafe { core::slice::from_raw_parts(self.ptr.as_ptr(), self.len) }; - Ok(slice) + self.as_mut_slice().map(|s| &*s) } -} -impl IoVec

{ - pub fn as_mut_slice(&mut self) -> Result<&mut [u8]> { - if self.ptr.is_null() { - return Err(Error::InvalidVectorAddress); + pub fn as_mut_slice(&self) -> Result<&mut [u8]> { + if !self.ptr.is_null() { + Ok(unsafe { core::slice::from_raw_parts_mut(self.ptr.ptr, self.len) }) + } else { + Err(Error::InvalidVectorAddress) } - let slice = unsafe { core::slice::from_raw_parts_mut(self.ptr.as_ptr(), self.len) }; - Ok(slice) } } diff --git a/linux-object/src/thread.rs b/linux-object/src/thread.rs index bd22e51b..86eb6a01 100644 --- a/linux-object/src/thread.rs +++ b/linux-object/src/thread.rs @@ -4,7 +4,6 @@ use crate::process::ProcessExt; use crate::signal::{SignalStack, Sigset}; use alloc::sync::Arc; use kernel_hal::user::{Out, UserOutPtr, UserPtr}; -use kernel_hal::VirtAddr; use spin::{Mutex, MutexGuard}; use zircon_object::task::{CurrentThread, Process, Thread}; use zircon_object::ZxResult; @@ -58,7 +57,7 @@ impl CurrentThreadExt for CurrentThread { if !clear_child_tid.is_null() { info!("exit: do futex {:?} wake 1", clear_child_tid); clear_child_tid.write(0).unwrap(); - let uaddr = clear_child_tid.as_ptr() as VirtAddr; + let uaddr = clear_child_tid.as_addr(); let futex = self.proc().linux().get_futex(uaddr); futex.wake(1); } diff --git a/linux-syscall/src/file/dir.rs b/linux-syscall/src/file/dir.rs index ef200801..ef420dc5 100644 --- a/linux-syscall/src/file/dir.rs +++ b/linux-syscall/src/file/dir.rs @@ -28,7 +28,7 @@ impl Syscall<'_> { return Err(LxError::ERANGE); } buf.write_cstring(&cwd)?; - Ok(buf.as_ptr() as usize) + Ok(buf.as_addr()) } /// Change the current directory.