From b1c82bb07c91939214df96b1d70dc86214c0cc0e Mon Sep 17 00:00:00 2001 From: ChiChen <2531693734@qq.com> Date: Thu, 10 Aug 2023 00:15:59 +0800 Subject: [PATCH 01/11] =?UTF-8?q?=E6=9E=84=E5=BB=BA=E4=BA=86=20Userbuffer?= =?UTF-8?q?=20=E5=AF=B9=E7=94=A8=E6=88=B7=E7=A9=BA=E9=97=B4=E4=BC=A0?= =?UTF-8?q?=E5=85=A5=E7=9A=84=E6=8C=87=E9=92=88=E8=BF=9B=E8=A1=8C=E4=BA=86?= =?UTF-8?q?=E6=8A=BD=E8=B1=A1=EF=BC=8C=E5=B9=B6=E6=8F=90=E4=BE=9B=E4=BA=86?= =?UTF-8?q?=E8=AF=BB=E5=86=99=E6=93=8D=E4=BD=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel/src/libs/mod.rs | 1 + kernel/src/libs/userbuffer.rs | 138 ++++++++++++++++++++++++++++++++++ 2 files changed, 139 insertions(+) create mode 100644 kernel/src/libs/userbuffer.rs diff --git a/kernel/src/libs/mod.rs b/kernel/src/libs/mod.rs index 46e83fba6..556dea041 100644 --- a/kernel/src/libs/mod.rs +++ b/kernel/src/libs/mod.rs @@ -22,3 +22,4 @@ pub mod vec_cursor; pub mod volatile; pub mod notifier; pub mod wait_queue; +pub mod userbuffer; diff --git a/kernel/src/libs/userbuffer.rs b/kernel/src/libs/userbuffer.rs new file mode 100644 index 000000000..8a0b7f939 --- /dev/null +++ b/kernel/src/libs/userbuffer.rs @@ -0,0 +1,138 @@ +use crate::{include::bindings::bindings::verify_area, syscall::SystemError}; + + + +#[derive(Debug)] +pub struct UserBuffer{ + addr: *const T, + len : usize, +} + +impl UserBuffer +{ + /// 构造一个指向用户空间位置的Buffer + /// + /// @param addr 用户空间指针 + /// @param len 是元素数量,不是byte长度 + /// @return 构造成功返回Userbuffer实例,否则返回错误码 + /// + pub fn new(addr: *const T,len:usize)->Result + { + if unsafe{!verify_area(addr as u64, (len* core::mem::size_of::()) as u64)}{ + return Err(SystemError::EFAULT); + } + return Ok(Self {addr,len}) + } + + pub fn read_from_user(&self)->Result<&[T],SystemError> + { + let items: &[T] = unsafe{core::slice::from_raw_parts(self.addr, self.len)}; + return Ok(items); + } + + pub fn write_to_user(&self,data: &[T])->Result<(),SystemError> + { + let buf = unsafe{core::slice::from_raw_parts_mut(self.addr as *mut T,self.len)}; + buf.copy_from_slice(data); + return Ok(()); + } + + + + +} + + +// 调用方式一:数组 +// pub unsafe fn write_to_user( +// &self, +// addr: *mut SockAddr, +// addr_len: *mut u32, +// ) -> Result { +// // 当用户传入的地址或者长度为空时,直接返回0 +// if addr.is_null() || addr_len.is_null() { +// return Ok(0); +// } +// // 检查用户传入的地址是否合法 +// if !verify_area( +// addr as usize as u64, +// core::mem::size_of::() as u64, +// ) || !verify_area(addr_len as usize as u64, core::mem::size_of::() as u64) +// { +// return Err(SystemError::EFAULT); +// } + +// let to_write = min(self.len()?, *addr_len as usize); +// if to_write > 0 { +// let buf = core::slice::from_raw_parts_mut(addr as *mut u8, to_write); +// buf.copy_from_slice(core::slice::from_raw_parts( +// self as *const SockAddr as *const u8, +// to_write, +// )); +// } +// *addr_len = self.len()? as u32; +// return Ok(to_write); +// } +// } + +// 调用方式二:结构体(Cstr->str) +// SYS_UNLINK_AT => { +// let dirfd = args[0] as i32; +// let pathname = args[1] as *const c_char; +// let flags = args[2] as u32; +// if from_user && unsafe { !verify_area(pathname as u64, PAGE_4K_SIZE as u64) } { +// Err(SystemError::EFAULT) +// } else if pathname.is_null() { +// Err(SystemError::EFAULT) +// } else { +// let get_path = || { +// let pathname: &CStr = unsafe { CStr::from_ptr(pathname) }; +// let pathname: &str = pathname.to_str().map_err(|_| SystemError::EINVAL)?; +// if pathname.len() >= MAX_PATHLEN { +// return Err(SystemError::ENAMETOOLONG); +// } +// return Ok(pathname.trim()); +// }; +// let pathname = get_path(); +// if pathname.is_err() { +// Err(pathname.unwrap_err()) +// } else { +// Self::unlinkat(dirfd, pathname.unwrap(), flags) +// } +// } +// } + +//调用方式二:结构体 Iovec +// pub unsafe fn from_user( +// iov: *const IoVec, +// iovcnt: usize, +// _readv: bool, +// ) -> Result { +// // 检查iov指针所在空间是否合法 +// if !verify_area( +// iov as usize as u64, +// (iovcnt * core::mem::size_of::()) as u64, +// ) { +// return Err(SystemError::EFAULT); +// } + +// // 将用户空间的IoVec转换为引用(注意:这里的引用是静态的,因为用户空间的IoVec不会被释放) +// let iovs: &[IoVec] = core::slice::from_raw_parts(iov, iovcnt); + +// let mut slices: Vec<&mut [u8]> = vec![]; +// slices.reserve(iovs.len()); + +// for iov in iovs.iter() { +// if iov.iov_len == 0 { +// continue; +// } + +// if !verify_area(iov.iov_base as usize as u64, iov.iov_len as u64) { +// return Err(SystemError::EFAULT); +// } + +// slices.push(core::slice::from_raw_parts_mut(iov.iov_base, iov.iov_len)); +// } + +// return Ok(Self(slices)); +// } From ccea25ec065be02be502ee6bdfe3399cb153fbfa Mon Sep 17 00:00:00 2001 From: ChiChen <2531693734@qq.com> Date: Fri, 11 Aug 2023 20:40:49 +0800 Subject: [PATCH 02/11] =?UTF-8?q?=E5=88=86=E6=88=90=E4=BA=86Reader?= =?UTF-8?q?=E5=92=8CWriter=EF=BC=8C=E5=A2=9E=E5=8A=A0=E4=BA=86=E4=BB=8E?= =?UTF-8?q?=E5=9C=B0=E5=9D=80=E8=AF=BB=E5=92=8C=E5=86=99=E5=85=A5=E5=88=B0?= =?UTF-8?q?=E6=8C=87=E5=AE=9A=E5=9C=B0=E5=9D=80=E7=9A=84=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel/src/libs/mod.rs | 2 +- kernel/src/libs/userbuffer.rs | 84 ++++++++++++++++++++++++++--------- 2 files changed, 63 insertions(+), 23 deletions(-) diff --git a/kernel/src/libs/mod.rs b/kernel/src/libs/mod.rs index 556dea041..1a4e2cdb8 100644 --- a/kernel/src/libs/mod.rs +++ b/kernel/src/libs/mod.rs @@ -21,5 +21,5 @@ pub mod vec_cursor; #[macro_use] pub mod volatile; pub mod notifier; -pub mod wait_queue; pub mod userbuffer; +pub mod wait_queue; diff --git a/kernel/src/libs/userbuffer.rs b/kernel/src/libs/userbuffer.rs index 8a0b7f939..8b7e3b5ba 100644 --- a/kernel/src/libs/userbuffer.rs +++ b/kernel/src/libs/userbuffer.rs @@ -1,48 +1,88 @@ use crate::{include::bindings::bindings::verify_area, syscall::SystemError}; - +#[derive(Debug)] +pub struct UserBufferWriter { + addr: *mut T, + len: usize, +} #[derive(Debug)] -pub struct UserBuffer{ +pub struct UserBufferReader { addr: *const T, - len : usize, + len: usize, } -impl UserBuffer -{ - /// 构造一个指向用户空间位置的Buffer +impl UserBufferReader { + /// 构造一个指向用户空间位置的BufferReader /// /// @param addr 用户空间指针 /// @param len 是元素数量,不是byte长度 - /// @return 构造成功返回Userbuffer实例,否则返回错误码 + /// @return 构造成功返回UserbufferReader实例,否则返回错误码 /// - pub fn new(addr: *const T,len:usize)->Result - { - if unsafe{!verify_area(addr as u64, (len* core::mem::size_of::()) as u64)}{ + pub fn new(addr: *const T, len: usize) -> Result { + if unsafe { !verify_area(addr as u64, (len * core::mem::size_of::()) as u64) } { return Err(SystemError::EFAULT); } - return Ok(Self {addr,len}) + return Ok(Self { addr, len }); } - pub fn read_from_user(&self)->Result<&[T],SystemError> - { - let items: &[T] = unsafe{core::slice::from_raw_parts(self.addr, self.len)}; + /// 从用户空间读取数据(到变量中) + /// + /// @return 返回用户空间数据的切片(对单个结构体就返回长度为一的切片) + /// + pub fn read_from_user(&self) -> Result<&[T], SystemError> { + let items: &[T] = unsafe { core::slice::from_raw_parts(self.addr, self.len) }; return Ok(items); } - pub fn write_to_user(&self,data: &[T])->Result<(),SystemError> - { - let buf = unsafe{core::slice::from_raw_parts_mut(self.addr as *mut T,self.len)}; - buf.copy_from_slice(data); - return Ok(()); + /// 从用户空间拷贝数据(到指定地址中) + /// + /// @param dst 目标地址指针 + /// @return 拷贝成功的话返回拷贝的元素数量 + /// + pub fn copy_from_user(&self, dst: &mut [T]) -> Result { + let src: &[T] = unsafe { core::slice::from_raw_parts(self.addr, self.len) }; + dst.copy_from_slice(&src); + return Ok(src.len()); } +} +impl UserBufferWriter { + /// 构造一个指向用户空间位置的BufferWriter + /// + /// @param addr 用户空间指针 + /// @param len 是元素数量,不是byte长度 + /// @return 构造成功返回UserbufferWriter实例,否则返回错误码 + /// + pub fn new(addr: *mut T, len: usize) -> Result { + if unsafe { !verify_area(addr as u64, (len * core::mem::size_of::()) as u64) } { + return Err(SystemError::EFAULT); + } + return Ok(Self { addr, len }); + } + /// 从结构体写入数据到用户空间 + /// + /// @param data 要写入的数据(如果是单个对象,也封装成只有一个元素的切片) + /// @return Result<(), SystemError> + /// + pub fn write_to_user(&self, data: &[T]) -> Result<(), SystemError> { + let buf = unsafe { core::slice::from_raw_parts_mut(self.addr, self.len) }; + buf.copy_from_slice(data); + return Ok(()); + } - + /// 从指定地址写入数据到用户空间 + /// + /// @param data 要写入的数据地址 + /// @return 返回写入元素的数量 + /// + pub fn copy_to_user(&self, src: &[T]) -> Result { + let dst: &mut [T] = unsafe { core::slice::from_raw_parts_mut(self.addr, self.len) }; + dst.copy_from_slice(&src); + return Ok(src.len()); + } } - - // 调用方式一:数组 // pub unsafe fn write_to_user( // &self, From 2994e79cd04e28b6eccfe2c286ec309390cac9dc Mon Sep 17 00:00:00 2001 From: ChiChen <2531693734@qq.com> Date: Fri, 11 Aug 2023 20:58:34 +0800 Subject: [PATCH 03/11] =?UTF-8?q?=E5=88=A0=E9=99=A4=E4=BA=86=E5=A4=9A?= =?UTF-8?q?=E4=BD=99=E7=9A=84=E6=B3=A8=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel/src/libs/userbuffer.rs | 93 ----------------------------------- 1 file changed, 93 deletions(-) diff --git a/kernel/src/libs/userbuffer.rs b/kernel/src/libs/userbuffer.rs index 8b7e3b5ba..7239c835d 100644 --- a/kernel/src/libs/userbuffer.rs +++ b/kernel/src/libs/userbuffer.rs @@ -83,96 +83,3 @@ impl UserBufferWriter { return Ok(src.len()); } } -// 调用方式一:数组 -// pub unsafe fn write_to_user( -// &self, -// addr: *mut SockAddr, -// addr_len: *mut u32, -// ) -> Result { -// // 当用户传入的地址或者长度为空时,直接返回0 -// if addr.is_null() || addr_len.is_null() { -// return Ok(0); -// } -// // 检查用户传入的地址是否合法 -// if !verify_area( -// addr as usize as u64, -// core::mem::size_of::() as u64, -// ) || !verify_area(addr_len as usize as u64, core::mem::size_of::() as u64) -// { -// return Err(SystemError::EFAULT); -// } - -// let to_write = min(self.len()?, *addr_len as usize); -// if to_write > 0 { -// let buf = core::slice::from_raw_parts_mut(addr as *mut u8, to_write); -// buf.copy_from_slice(core::slice::from_raw_parts( -// self as *const SockAddr as *const u8, -// to_write, -// )); -// } -// *addr_len = self.len()? as u32; -// return Ok(to_write); -// } -// } - -// 调用方式二:结构体(Cstr->str) -// SYS_UNLINK_AT => { -// let dirfd = args[0] as i32; -// let pathname = args[1] as *const c_char; -// let flags = args[2] as u32; -// if from_user && unsafe { !verify_area(pathname as u64, PAGE_4K_SIZE as u64) } { -// Err(SystemError::EFAULT) -// } else if pathname.is_null() { -// Err(SystemError::EFAULT) -// } else { -// let get_path = || { -// let pathname: &CStr = unsafe { CStr::from_ptr(pathname) }; -// let pathname: &str = pathname.to_str().map_err(|_| SystemError::EINVAL)?; -// if pathname.len() >= MAX_PATHLEN { -// return Err(SystemError::ENAMETOOLONG); -// } -// return Ok(pathname.trim()); -// }; -// let pathname = get_path(); -// if pathname.is_err() { -// Err(pathname.unwrap_err()) -// } else { -// Self::unlinkat(dirfd, pathname.unwrap(), flags) -// } -// } -// } - -//调用方式二:结构体 Iovec -// pub unsafe fn from_user( -// iov: *const IoVec, -// iovcnt: usize, -// _readv: bool, -// ) -> Result { -// // 检查iov指针所在空间是否合法 -// if !verify_area( -// iov as usize as u64, -// (iovcnt * core::mem::size_of::()) as u64, -// ) { -// return Err(SystemError::EFAULT); -// } - -// // 将用户空间的IoVec转换为引用(注意:这里的引用是静态的,因为用户空间的IoVec不会被释放) -// let iovs: &[IoVec] = core::slice::from_raw_parts(iov, iovcnt); - -// let mut slices: Vec<&mut [u8]> = vec![]; -// slices.reserve(iovs.len()); - -// for iov in iovs.iter() { -// if iov.iov_len == 0 { -// continue; -// } - -// if !verify_area(iov.iov_base as usize as u64, iov.iov_len as u64) { -// return Err(SystemError::EFAULT); -// } - -// slices.push(core::slice::from_raw_parts_mut(iov.iov_base, iov.iov_len)); -// } - -// return Ok(Self(slices)); -// } From 39addb7e37c2cb707992bb0a26f1e241bf1e3851 Mon Sep 17 00:00:00 2001 From: ChiChen <2531693734@qq.com> Date: Fri, 11 Aug 2023 21:44:22 +0800 Subject: [PATCH 04/11] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E4=BA=86=E7=9B=B4?= =?UTF-8?q?=E6=8E=A5=E8=8E=B7=E5=8F=96BufferWriter=E5=88=87=E7=89=87?= =?UTF-8?q?=E7=9A=84=E5=87=BD=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel/src/libs/userbuffer.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/kernel/src/libs/userbuffer.rs b/kernel/src/libs/userbuffer.rs index 7239c835d..7a10eb4fc 100644 --- a/kernel/src/libs/userbuffer.rs +++ b/kernel/src/libs/userbuffer.rs @@ -82,4 +82,8 @@ impl UserBufferWriter { dst.copy_from_slice(&src); return Ok(src.len()); } + + pub fn get_buffer(&self) -> &mut [T] { + unsafe { core::slice::from_raw_parts_mut(self.addr, self.len) } + } } From b64efceb69f3c294ae3fba6b24208f91ef11ad20 Mon Sep 17 00:00:00 2001 From: ChiChen <2531693734@qq.com> Date: Thu, 17 Aug 2023 15:40:22 +0800 Subject: [PATCH 05/11] =?UTF-8?q?=E9=80=9A=E8=BF=87=20where=20=E7=9A=84?= =?UTF-8?q?=E4=B8=80=E4=B8=AA=20Trick=20=E5=AE=9E=E7=8E=B0=E4=BA=86=20cons?= =?UTF-8?q?t=20generic=20=E5=92=8C=E5=90=8E=E7=BB=AD=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel/src/syscall/user_access.rs | 196 ++++++++++++++++++++++++++++++ 1 file changed, 196 insertions(+) diff --git a/kernel/src/syscall/user_access.rs b/kernel/src/syscall/user_access.rs index 1078e4171..6014903b9 100644 --- a/kernel/src/syscall/user_access.rs +++ b/kernel/src/syscall/user_access.rs @@ -1,4 +1,5 @@ //! 这个文件用于放置一些内核态访问用户态数据的函数 + use core::mem::size_of; use alloc::{string::String, vec::Vec}; @@ -139,3 +140,198 @@ pub fn check_and_clone_cstr_array(user: *const *const u8) -> Result, return Ok(buffer); } } + +#[derive(Debug)] +pub struct UserBufferWriter<'a> { + buffer: &'a mut [u8], + len: usize, +} + +#[derive(Debug)] +pub struct UserBufferReader<'a> { + buffer: &'a [u8], + len: usize, +} + +impl<'a> UserBufferReader<'a> { + /// 构造一个指向用户空间位置的BufferReader,为了兼容类似传入 *const u8 的情况,使用单独的泛型来进行初始化 + /// + /// @param addr 用户空间指针 + /// @param len 缓冲区的字节长度 + /// @param frm_user 代表是否要检验地址来自用户空间 + /// @return 构造成功返回UserbufferReader实例,否则返回错误码 + /// + pub fn new(addr: *const U, len: usize, from_user: bool) -> Result { + if from_user && verify_area(VirtAddr::new(addr as usize), len).is_err() { + return Err(SystemError::EFAULT); + } + return Ok(Self { + buffer: unsafe { core::slice::from_raw_parts(addr as *const u8, len) }, + len, + }); + } + + /// 从用户空间读取数据(到变量中) + /// + /// @return 返回用户空间数据的切片(对单个结构体就返回长度为一的切片) + /// + pub fn read_from_user(&self, offset: usize) -> Result<&[T], SystemError> + where + [u8; core::mem::size_of::()]:, + { + match self.convert_with_offset(&self.buffer, offset) { + Err(e) => return Err(e), + Ok(data) => return Ok(data), + } + } + + /// 从用户空间拷贝数据(到指定地址中) + /// + /// @param dst 目标地址指针 + /// @return 拷贝成功的话返回拷贝的元素数量 + /// + pub fn copy_from_user( + &self, + dst: &mut [T], + offset: usize, + ) -> Result + where + [u8; core::mem::size_of::()]:, + { + match self.convert_with_offset(&self.buffer, offset) { + Err(e) => return Err(e), + Ok(data) => { + dst.copy_from_slice(data); + } + } + return Ok(dst.len()); + } + + fn convert_with_offset(&self, src: &'a [u8], offset: usize) -> Result<&'a [T], SystemError> + where + [u8; core::mem::size_of::()]:, + { + if offset >= src.len() { + return Err(SystemError::EINVAL); + } + let byte_buffer: &[u8] = &src[offset..]; + if byte_buffer.len() % core::mem::size_of::() != 0 { + return Err(SystemError::EINVAL); + } + // let size :usize= core::mem::size_of::(); + // let chunks = src.chunks_exact(size); + // self.data = chunks.map(|chunk| { + // let array: [u8;core::mem::size_of::()] = chunk.try_into().unwrap(); + // unsafe{core::mem::transmute_copy::<[u8;core::mem::size_of::()],T>(&array)} + // }).collect(); + let (prefix, chunks, suffix) = unsafe { byte_buffer.align_to::() }; + if !prefix.is_empty() || !suffix.is_empty() { + return Err(SystemError::EINVAL); + } + return Ok(chunks); + } +} + +impl<'a> UserBufferWriter<'a> { + /// 构造一个指向用户空间位置的BufferWriter + /// + /// @param addr 用户空间指针 + /// @param len 缓冲区的字节长度 + /// @return 构造成功返回UserbufferWriter实例,否则返回错误码 + /// + pub fn new(addr: *mut U, len: usize, from_user: bool) -> Result { + if from_user + && verify_area( + VirtAddr::new(addr as usize), + (len * core::mem::size_of::()) as usize, + ) + .is_err() + { + return Err(SystemError::EFAULT); + } + return Ok(Self { + buffer: unsafe { + core::slice::from_raw_parts_mut(addr as *mut u8, len * core::mem::size_of::()) + }, + len, + }); + } + + /// 从结构体写入数据到用户空间 + /// + /// @param data 要写入的数据(如果是单个对象,也封装成只有一个元素的切片) + /// @return Result<(), SystemError> + /// + pub fn write_to_user( + &'a mut self, + data: &'a [T], + offset: usize, + ) -> Result<(), SystemError> + where + [u8; core::mem::size_of::()]:, + { + match Self::convert_with_offset(self.buffer, offset) { + Err(e) => Err(e), + Ok(dst) => { + dst.copy_from_slice(data); + return Ok(()); + } + } + } + + /// 从指定地址写入数据到用户空间 + /// + /// @param data 要写入的数据地址 + /// @return 返回写入元素的数量 + /// + pub fn copy_to_user( + &'a mut self, + src: &'a [T], + offset: usize, + ) -> Result + where + [u8; core::mem::size_of::()]:, + { + match Self::convert_with_offset(self.buffer, offset) { + Err(_) => return Err(SystemError::EINVAL), + Ok(dst) => { + dst.copy_from_slice(&src); + return Ok(src.len()); + } + } + } + + pub fn get_buffer(&'a mut self, offset: usize) -> Result<&mut [T], SystemError> + where + [u8; core::mem::size_of::()]:, + { + match Self::convert_with_offset(self.buffer, offset) { + Err(_) => return Err(SystemError::EINVAL), + Ok(buffer) => return Ok(buffer), + } + } + + fn convert_with_offset(src: &'a mut [u8], offset: usize) -> Result<&'a mut [T], SystemError> + where + [u8; core::mem::size_of::()]:, + { + if offset >= src.len() { + return Err(SystemError::EINVAL); + } + let byte_buffer: &mut [u8] = &mut src[offset..]; + if byte_buffer.len() % core::mem::size_of::() != 0 { + return Err(SystemError::EINVAL); + } + // let size :usize= core::mem::size_of::(); + // let chunks = src.chunks_exact(size); + // self.data = chunks.map(|chunk| { + // let array: [u8;core::mem::size_of::()] = chunk.try_into().unwrap(); + // unsafe{core::mem::transmute_copy::<[u8;core::mem::size_of::()],T>(&array)} + // }).collect(); + let (prefix, chunks, suffix) = unsafe { byte_buffer.align_to_mut::() }; + if !prefix.is_empty() || !suffix.is_empty() { + return Err(SystemError::EINVAL); + } + return Ok(chunks); + } +} From 7839046c613339fadb544f3ce881ae766ce0b0ed Mon Sep 17 00:00:00 2001 From: ChiChen <2531693734@qq.com> Date: Thu, 17 Aug 2023 15:44:16 +0800 Subject: [PATCH 06/11] =?UTF-8?q?=E6=9B=BF=E6=8D=A2=E4=B8=BA=E4=BA=86=20co?= =?UTF-8?q?re::slice::align=5Fto=20=E5=AE=9E=E7=8E=B0&[u8}=E8=BD=AC&[T]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel/src/syscall/user_access.rs | 50 +++++++------------------------ 1 file changed, 10 insertions(+), 40 deletions(-) diff --git a/kernel/src/syscall/user_access.rs b/kernel/src/syscall/user_access.rs index 6014903b9..9cad73eeb 100644 --- a/kernel/src/syscall/user_access.rs +++ b/kernel/src/syscall/user_access.rs @@ -175,10 +175,7 @@ impl<'a> UserBufferReader<'a> { /// /// @return 返回用户空间数据的切片(对单个结构体就返回长度为一的切片) /// - pub fn read_from_user(&self, offset: usize) -> Result<&[T], SystemError> - where - [u8; core::mem::size_of::()]:, - { + pub fn read_from_user(&self, offset: usize) -> Result<&[T], SystemError> { match self.convert_with_offset(&self.buffer, offset) { Err(e) => return Err(e), Ok(data) => return Ok(data), @@ -194,10 +191,7 @@ impl<'a> UserBufferReader<'a> { &self, dst: &mut [T], offset: usize, - ) -> Result - where - [u8; core::mem::size_of::()]:, - { + ) -> Result { match self.convert_with_offset(&self.buffer, offset) { Err(e) => return Err(e), Ok(data) => { @@ -207,10 +201,7 @@ impl<'a> UserBufferReader<'a> { return Ok(dst.len()); } - fn convert_with_offset(&self, src: &'a [u8], offset: usize) -> Result<&'a [T], SystemError> - where - [u8; core::mem::size_of::()]:, - { + fn convert_with_offset(&self, src: &'a [u8], offset: usize) -> Result<&'a [T], SystemError> { if offset >= src.len() { return Err(SystemError::EINVAL); } @@ -218,12 +209,6 @@ impl<'a> UserBufferReader<'a> { if byte_buffer.len() % core::mem::size_of::() != 0 { return Err(SystemError::EINVAL); } - // let size :usize= core::mem::size_of::(); - // let chunks = src.chunks_exact(size); - // self.data = chunks.map(|chunk| { - // let array: [u8;core::mem::size_of::()] = chunk.try_into().unwrap(); - // unsafe{core::mem::transmute_copy::<[u8;core::mem::size_of::()],T>(&array)} - // }).collect(); let (prefix, chunks, suffix) = unsafe { byte_buffer.align_to::() }; if !prefix.is_empty() || !suffix.is_empty() { return Err(SystemError::EINVAL); @@ -266,10 +251,7 @@ impl<'a> UserBufferWriter<'a> { &'a mut self, data: &'a [T], offset: usize, - ) -> Result<(), SystemError> - where - [u8; core::mem::size_of::()]:, - { + ) -> Result<(), SystemError> { match Self::convert_with_offset(self.buffer, offset) { Err(e) => Err(e), Ok(dst) => { @@ -288,10 +270,7 @@ impl<'a> UserBufferWriter<'a> { &'a mut self, src: &'a [T], offset: usize, - ) -> Result - where - [u8; core::mem::size_of::()]:, - { + ) -> Result { match Self::convert_with_offset(self.buffer, offset) { Err(_) => return Err(SystemError::EINVAL), Ok(dst) => { @@ -301,20 +280,17 @@ impl<'a> UserBufferWriter<'a> { } } - pub fn get_buffer(&'a mut self, offset: usize) -> Result<&mut [T], SystemError> - where - [u8; core::mem::size_of::()]:, - { + pub fn get_buffer(&'a mut self, offset: usize) -> Result<&mut [T], SystemError> { match Self::convert_with_offset(self.buffer, offset) { Err(_) => return Err(SystemError::EINVAL), Ok(buffer) => return Ok(buffer), } } - fn convert_with_offset(src: &'a mut [u8], offset: usize) -> Result<&'a mut [T], SystemError> - where - [u8; core::mem::size_of::()]:, - { + fn convert_with_offset( + src: &'a mut [u8], + offset: usize, + ) -> Result<&'a mut [T], SystemError> { if offset >= src.len() { return Err(SystemError::EINVAL); } @@ -322,12 +298,6 @@ impl<'a> UserBufferWriter<'a> { if byte_buffer.len() % core::mem::size_of::() != 0 { return Err(SystemError::EINVAL); } - // let size :usize= core::mem::size_of::(); - // let chunks = src.chunks_exact(size); - // self.data = chunks.map(|chunk| { - // let array: [u8;core::mem::size_of::()] = chunk.try_into().unwrap(); - // unsafe{core::mem::transmute_copy::<[u8;core::mem::size_of::()],T>(&array)} - // }).collect(); let (prefix, chunks, suffix) = unsafe { byte_buffer.align_to_mut::() }; if !prefix.is_empty() || !suffix.is_empty() { return Err(SystemError::EINVAL); From 030fd05a5db754b6c548abdadaac05b20cadca7b Mon Sep 17 00:00:00 2001 From: ChiChen <2531693734@qq.com> Date: Fri, 18 Aug 2023 11:26:11 +0800 Subject: [PATCH 07/11] =?UTF-8?q?=E7=A7=BB=E9=99=A4=E4=BA=86=20userbuffer.?= =?UTF-8?q?rs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel/src/libs/mod.rs | 1 - kernel/src/libs/userbuffer.rs | 89 ----------------------------------- kernel/src/syscall/mod.rs | 24 +++++----- 3 files changed, 13 insertions(+), 101 deletions(-) delete mode 100644 kernel/src/libs/userbuffer.rs diff --git a/kernel/src/libs/mod.rs b/kernel/src/libs/mod.rs index 1a4e2cdb8..46e83fba6 100644 --- a/kernel/src/libs/mod.rs +++ b/kernel/src/libs/mod.rs @@ -21,5 +21,4 @@ pub mod vec_cursor; #[macro_use] pub mod volatile; pub mod notifier; -pub mod userbuffer; pub mod wait_queue; diff --git a/kernel/src/libs/userbuffer.rs b/kernel/src/libs/userbuffer.rs deleted file mode 100644 index 7a10eb4fc..000000000 --- a/kernel/src/libs/userbuffer.rs +++ /dev/null @@ -1,89 +0,0 @@ -use crate::{include::bindings::bindings::verify_area, syscall::SystemError}; - -#[derive(Debug)] -pub struct UserBufferWriter { - addr: *mut T, - len: usize, -} - -#[derive(Debug)] -pub struct UserBufferReader { - addr: *const T, - len: usize, -} - -impl UserBufferReader { - /// 构造一个指向用户空间位置的BufferReader - /// - /// @param addr 用户空间指针 - /// @param len 是元素数量,不是byte长度 - /// @return 构造成功返回UserbufferReader实例,否则返回错误码 - /// - pub fn new(addr: *const T, len: usize) -> Result { - if unsafe { !verify_area(addr as u64, (len * core::mem::size_of::()) as u64) } { - return Err(SystemError::EFAULT); - } - return Ok(Self { addr, len }); - } - - /// 从用户空间读取数据(到变量中) - /// - /// @return 返回用户空间数据的切片(对单个结构体就返回长度为一的切片) - /// - pub fn read_from_user(&self) -> Result<&[T], SystemError> { - let items: &[T] = unsafe { core::slice::from_raw_parts(self.addr, self.len) }; - return Ok(items); - } - - /// 从用户空间拷贝数据(到指定地址中) - /// - /// @param dst 目标地址指针 - /// @return 拷贝成功的话返回拷贝的元素数量 - /// - pub fn copy_from_user(&self, dst: &mut [T]) -> Result { - let src: &[T] = unsafe { core::slice::from_raw_parts(self.addr, self.len) }; - dst.copy_from_slice(&src); - return Ok(src.len()); - } -} - -impl UserBufferWriter { - /// 构造一个指向用户空间位置的BufferWriter - /// - /// @param addr 用户空间指针 - /// @param len 是元素数量,不是byte长度 - /// @return 构造成功返回UserbufferWriter实例,否则返回错误码 - /// - pub fn new(addr: *mut T, len: usize) -> Result { - if unsafe { !verify_area(addr as u64, (len * core::mem::size_of::()) as u64) } { - return Err(SystemError::EFAULT); - } - return Ok(Self { addr, len }); - } - - /// 从结构体写入数据到用户空间 - /// - /// @param data 要写入的数据(如果是单个对象,也封装成只有一个元素的切片) - /// @return Result<(), SystemError> - /// - pub fn write_to_user(&self, data: &[T]) -> Result<(), SystemError> { - let buf = unsafe { core::slice::from_raw_parts_mut(self.addr, self.len) }; - buf.copy_from_slice(data); - return Ok(()); - } - - /// 从指定地址写入数据到用户空间 - /// - /// @param data 要写入的数据地址 - /// @return 返回写入元素的数量 - /// - pub fn copy_to_user(&self, src: &[T]) -> Result { - let dst: &mut [T] = unsafe { core::slice::from_raw_parts_mut(self.addr, self.len) }; - dst.copy_from_slice(&src); - return Ok(src.len()); - } - - pub fn get_buffer(&self) -> &mut [T] { - unsafe { core::slice::from_raw_parts_mut(self.addr, self.len) } - } -} diff --git a/kernel/src/syscall/mod.rs b/kernel/src/syscall/mod.rs index ee12c2e7e..4090dd141 100644 --- a/kernel/src/syscall/mod.rs +++ b/kernel/src/syscall/mod.rs @@ -25,6 +25,8 @@ use crate::{ }, }; +use self::user_access::UserBufferWriter; + pub mod user_access; #[repr(i32)] @@ -651,17 +653,17 @@ impl Syscall { SYS_CLOCK => Self::clock(), SYS_PIPE => { let pipefd = args[0] as *mut c_int; - let virt_pipefd = VirtAddr::new(pipefd as usize); - if from_user - && verify_area(virt_pipefd, core::mem::size_of::<[c_int; 2]>() as usize) - .is_err() - { - Err(SystemError::EFAULT) - } else if pipefd.is_null() { - Err(SystemError::EFAULT) - } else { - let pipefd = unsafe { core::slice::from_raw_parts_mut(pipefd, 2) }; - Self::pipe(pipefd) + + match UserBufferWriter::new(pipefd,core::mem::size_of::<[c_int; 2]>() as usize,from_user){ + Err(e)=>Err(e), + Ok(mut user_buffer)=> + { + match user_buffer.get_buffer::(0) + { + Err(e)=>Err(e), + Ok(pipefd)=>Self::pipe(pipefd) + } + } } } From 3fd562717f10ec2d926b71247d6bf49bb759ec3d Mon Sep 17 00:00:00 2001 From: ChiChen <2531693734@qq.com> Date: Sat, 19 Aug 2023 11:47:35 +0800 Subject: [PATCH 08/11] =?UTF-8?q?=E6=8F=90=E4=BE=9B=E4=BA=86=E7=8B=AC?= =?UTF-8?q?=E7=AB=8B=E8=8E=B7=E5=8F=96=E7=BC=93=E5=86=B2=E5=8C=BA=E4=B8=AD?= =?UTF-8?q?=E4=B8=8D=E5=90=8C=E5=81=8F=E7=A7=BB=E9=87=8F=E4=BD=8D=E7=BD=AE?= =?UTF-8?q?=E7=9A=84=E6=95=B0=E6=8D=AE=E7=9A=84=E5=87=BD=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel/src/syscall/user_access.rs | 145 +++++++++++++++++++++++++++--- 1 file changed, 131 insertions(+), 14 deletions(-) diff --git a/kernel/src/syscall/user_access.rs b/kernel/src/syscall/user_access.rs index 9cad73eeb..41183c2e0 100644 --- a/kernel/src/syscall/user_access.rs +++ b/kernel/src/syscall/user_access.rs @@ -1,6 +1,9 @@ //! 这个文件用于放置一些内核态访问用户态数据的函数 -use core::mem::size_of; +use core::{ + mem::size_of, + slice::{from_raw_parts, from_raw_parts_mut}, +}; use alloc::{string::String, vec::Vec}; @@ -173,6 +176,7 @@ impl<'a> UserBufferReader<'a> { /// 从用户空间读取数据(到变量中) /// + /// @param offset 字节偏移量 /// @return 返回用户空间数据的切片(对单个结构体就返回长度为一的切片) /// pub fn read_from_user(&self, offset: usize) -> Result<&[T], SystemError> { @@ -181,6 +185,17 @@ impl<'a> UserBufferReader<'a> { Ok(data) => return Ok(data), } } + /// 从用户空间读取一个指定偏移量的数据(到变量中) + /// + /// @param offset 字节偏移量 + /// @return 返回用户空间数据的引用 + /// + pub fn read_one_from_user(&self, offset: usize) -> Result<&T, SystemError> { + match self.convert_one_with_offset(&self.buffer, offset) { + Err(e) => Err(e), + Ok(data) => Ok(data), + } + } /// 从用户空间拷贝数据(到指定地址中) /// @@ -201,7 +216,26 @@ impl<'a> UserBufferReader<'a> { return Ok(dst.len()); } - fn convert_with_offset(&self, src: &'a [u8], offset: usize) -> Result<&'a [T], SystemError> { + /// 从用户空间拷贝数据(到指定地址中) + /// + /// @param dst 目标地址指针 + /// @return 拷贝成功的话返回拷贝的元素数量 + /// + pub fn copy_one_from_user( + &self, + dst: &mut T, + offset: usize, + ) -> Result<(), SystemError> { + match self.convert_one_with_offset::(&self.buffer, offset) { + Err(e) => return Err(e), + Ok(data) => { + dst.clone_from(data); + return Ok(()); + } + } + } + + fn convert_with_offset(&self, src: &[u8], offset: usize) -> Result<&[T], SystemError> { if offset >= src.len() { return Err(SystemError::EINVAL); } @@ -209,11 +243,34 @@ impl<'a> UserBufferReader<'a> { if byte_buffer.len() % core::mem::size_of::() != 0 { return Err(SystemError::EINVAL); } - let (prefix, chunks, suffix) = unsafe { byte_buffer.align_to::() }; - if !prefix.is_empty() || !suffix.is_empty() { + // let (prefix, chunks, suffix) = unsafe { byte_buffer.align_to::() }; + // if !prefix.is_empty() || !suffix.is_empty() { + // return Err(SystemError::EINVAL); + // } + let chunks = unsafe { + from_raw_parts( + byte_buffer.as_ptr() as *const T, + byte_buffer.len() / core::mem::size_of::(), + ) + }; + return Ok(chunks); + } + + fn convert_one_with_offset(&self, src: &[u8], offset: usize) -> Result<&T, SystemError> { + if offset >= src.len() { return Err(SystemError::EINVAL); } - return Ok(chunks); + let byte_buffer: &[u8] = &src[offset..]; + if byte_buffer.len() % core::mem::size_of::() != 0 { + return Err(SystemError::EINVAL); + } + // let (prefix, chunks, suffix) = unsafe { byte_buffer.align_to::() }; + // if !prefix.is_empty() || !suffix.is_empty() { + // return Err(SystemError::EINVAL); + // } + let chunks = unsafe { from_raw_parts(byte_buffer.as_ptr() as *const T, 1) }; + let data = &chunks[0]; + return Ok(data); } } @@ -248,8 +305,8 @@ impl<'a> UserBufferWriter<'a> { /// @return Result<(), SystemError> /// pub fn write_to_user( - &'a mut self, - data: &'a [T], + &mut self, + data: &[T], offset: usize, ) -> Result<(), SystemError> { match Self::convert_with_offset(self.buffer, offset) { @@ -261,9 +318,30 @@ impl<'a> UserBufferWriter<'a> { } } + /// 从结构体写入单个数据到用户空间 + /// + /// @param data 要写入的数据 + /// @param offset 在UserBuffer中的字节偏移量 + /// @return Result<(), SystemError> + /// + pub fn write_one_to_user( + &'a mut self, + data: &T, + offset: usize, + ) -> Result<(), SystemError> { + match Self::convert_one_with_offset::(self.buffer, offset) { + Err(e) => Err(e), + Ok(dst) => { + dst.clone_from(data); + return Ok(()); + } + } + } + /// 从指定地址写入数据到用户空间 /// /// @param data 要写入的数据地址 + /// @param offset 在UserBuffer中的字节偏移量 /// @return 返回写入元素的数量 /// pub fn copy_to_user( @@ -280,6 +358,26 @@ impl<'a> UserBufferWriter<'a> { } } + /// 从指定地址写入一个数据到用户空间 + /// + /// @param data 要写入的数据地址 + /// @param offset 在UserBuffer中的字节偏移量 + /// @return 返回写入元素的数量 + /// + pub fn copy_one_to_user( + &'a mut self, + src: &'a T, + offset: usize, + ) -> Result<(), SystemError> { + match Self::convert_one_with_offset::(self.buffer, offset) { + Err(_) => return Err(SystemError::EINVAL), + Ok(dst) => { + dst.clone_from(src); + return Ok(()); + } + } + } + pub fn get_buffer(&'a mut self, offset: usize) -> Result<&mut [T], SystemError> { match Self::convert_with_offset(self.buffer, offset) { Err(_) => return Err(SystemError::EINVAL), @@ -287,10 +385,7 @@ impl<'a> UserBufferWriter<'a> { } } - fn convert_with_offset( - src: &'a mut [u8], - offset: usize, - ) -> Result<&'a mut [T], SystemError> { + fn convert_with_offset(src: &mut [u8], offset: usize) -> Result<&mut [T], SystemError> { if offset >= src.len() { return Err(SystemError::EINVAL); } @@ -298,10 +393,32 @@ impl<'a> UserBufferWriter<'a> { if byte_buffer.len() % core::mem::size_of::() != 0 { return Err(SystemError::EINVAL); } - let (prefix, chunks, suffix) = unsafe { byte_buffer.align_to_mut::() }; - if !prefix.is_empty() || !suffix.is_empty() { + // let (prefix, chunks, suffix) = unsafe { byte_buffer.align_to_mut::() }; + // if !prefix.is_empty() || !suffix.is_empty() { + // return Err(SystemError::EINVAL); + // } + let chunks = unsafe { + from_raw_parts_mut( + byte_buffer.as_mut_ptr() as *mut T, + byte_buffer.len() / core::mem::size_of::(), + ) + }; + return Ok(chunks); + } + fn convert_one_with_offset(src: &mut [u8], offset: usize) -> Result<&mut T, SystemError> { + if offset >= src.len() { + return Err(SystemError::EINVAL); + } + let byte_buffer: &mut [u8] = &mut src[offset..]; + if byte_buffer.len() % core::mem::size_of::() != 0 { return Err(SystemError::EINVAL); } - return Ok(chunks); + // let (prefix, chunks, suffix) = unsafe { byte_buffer.align_to_mut::() }; + // if !prefix.is_empty() || !suffix.is_empty() { + // return Err(SystemError::EINVAL); + // } + let chunks = unsafe { from_raw_parts_mut(byte_buffer.as_mut_ptr() as *mut T, 1) }; + let data = &mut chunks[0]; + return Ok(data); } } From 9e01cefe9c7f1a1739bbd36ae74824253fd182b2 Mon Sep 17 00:00:00 2001 From: ChiChen <2531693734@qq.com> Date: Sat, 19 Aug 2023 14:41:23 +0800 Subject: [PATCH 09/11] =?UTF-8?q?=E6=9B=BF=E6=8D=A2=E4=BA=86=E9=83=A8?= =?UTF-8?q?=E5=88=86=E7=B3=BB=E7=BB=9F=E8=B0=83=E7=94=A8(=E8=BF=98?= =?UTF-8?q?=E6=9C=AA=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel/src/syscall/mod.rs | 97 +++++++++++++++++---------------------- 1 file changed, 41 insertions(+), 56 deletions(-) diff --git a/kernel/src/syscall/mod.rs b/kernel/src/syscall/mod.rs index 4090dd141..d9932418b 100644 --- a/kernel/src/syscall/mod.rs +++ b/kernel/src/syscall/mod.rs @@ -654,16 +654,16 @@ impl Syscall { SYS_PIPE => { let pipefd = args[0] as *mut c_int; - match UserBufferWriter::new(pipefd,core::mem::size_of::<[c_int; 2]>() as usize,from_user){ - Err(e)=>Err(e), - Ok(mut user_buffer)=> - { - match user_buffer.get_buffer::(0) - { - Err(e)=>Err(e), - Ok(pipefd)=>Self::pipe(pipefd) - } - } + match UserBufferWriter::new( + pipefd, + core::mem::size_of::<[c_int; 2]>() as usize, + from_user, + ) { + Err(e) => Err(e), + Ok(mut user_buffer) => match user_buffer.get_buffer::(0) { + Err(e) => Err(e), + Ok(pipefd) => Self::pipe(pipefd), + }, } } @@ -855,27 +855,21 @@ impl Syscall { SYS_RECVMSG => { let msg = args[1] as *mut crate::net::syscall::MsgHdr; let flags = args[2] as u32; - let virt_msg = VirtAddr::new(msg as usize); - let security_check = || { - // 验证msg的地址是否合法 - if verify_area( - virt_msg, - core::mem::size_of::() as usize, - ) - .is_err() - { - // 地址空间超出了用户空间的范围,不合法 - return Err(SystemError::EFAULT); + match UserBufferWriter::new( + msg, + core::mem::size_of::(), + true, + ) { + Err(e) => Err(e), + Ok(mut user_buffer_writer) => { + match user_buffer_writer.get_buffer::(0) { + Err(e) => Err(e), + Ok(buffer) => { + let msg = &mut buffer[0]; + Self::recvmsg(args[0], msg, flags) + } + } } - let msg = unsafe { msg.as_mut() }.ok_or(SystemError::EFAULT)?; - return Ok(msg); - }; - let r = security_check(); - if r.is_err() { - Err(r.unwrap_err()) - } else { - let msg = r.unwrap(); - Self::recvmsg(args[0], msg, flags) } } @@ -891,32 +885,23 @@ impl Syscall { SYS_GETTIMEOFDAY => { let timeval = args[0] as *mut PosixTimeval; let timezone_ptr = args[1] as *mut PosixTimeZone; - let virt_timeval = VirtAddr::new(timeval as usize); - let virt_timezone_ptr = VirtAddr::new(timezone_ptr as usize); - let security_check = || { - if verify_area(virt_timeval, core::mem::size_of::() as usize) - .is_err() - { - return Err(SystemError::EFAULT); - } - if verify_area( - virt_timezone_ptr, - core::mem::size_of::() as usize, - ) - .is_err() - { - return Err(SystemError::EFAULT); - } - return Ok(()); - }; - let r = security_check(); - if r.is_err() { - Err(r.unwrap_err()) - } else { - if !timeval.is_null() { - Self::gettimeofday(timeval, timezone_ptr) - } else { - Err(SystemError::EFAULT) + match UserBufferWriter::new(timeval, core::mem::size_of::(), true) { + Err(e) => Err(e), + Ok(_) => { + match UserBufferWriter::new( + timezone_ptr, + core::mem::size_of::(), + true, + ) { + Err(e) => Err(e), + Ok(_) => { + if !timeval.is_null() { + Self::gettimeofday(timeval, timezone_ptr) + } else { + Err(SystemError::EFAULT) + } + } + } } } } From d7f9a5427dafcad0ebf3d65b21dce78b14f7751a Mon Sep 17 00:00:00 2001 From: ChiChen <2531693734@qq.com> Date: Sun, 20 Aug 2023 14:22:54 +0800 Subject: [PATCH 10/11] =?UTF-8?q?=E7=AE=80=E5=8C=96=E4=BA=86=E4=BB=A3?= =?UTF-8?q?=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel/src/syscall/mod.rs | 6 +++--- kernel/src/syscall/user_access.rs | 16 +++++----------- 2 files changed, 8 insertions(+), 14 deletions(-) diff --git a/kernel/src/syscall/mod.rs b/kernel/src/syscall/mod.rs index d9932418b..20d7a5ef4 100644 --- a/kernel/src/syscall/mod.rs +++ b/kernel/src/syscall/mod.rs @@ -653,18 +653,18 @@ impl Syscall { SYS_CLOCK => Self::clock(), SYS_PIPE => { let pipefd = args[0] as *mut c_int; - match UserBufferWriter::new( pipefd, core::mem::size_of::<[c_int; 2]>() as usize, from_user, ) { Err(e) => Err(e), - Ok(mut user_buffer) => match user_buffer.get_buffer::(0) { + Ok(mut user_buffer) => match user_buffer.buffer::(0) { Err(e) => Err(e), Ok(pipefd) => Self::pipe(pipefd), }, } + } SYS_UNLINK_AT => { @@ -862,7 +862,7 @@ impl Syscall { ) { Err(e) => Err(e), Ok(mut user_buffer_writer) => { - match user_buffer_writer.get_buffer::(0) { + match user_buffer_writer.buffer::(0) { Err(e) => Err(e), Ok(buffer) => { let msg = &mut buffer[0]; diff --git a/kernel/src/syscall/user_access.rs b/kernel/src/syscall/user_access.rs index 41183c2e0..b87bdd0c4 100644 --- a/kernel/src/syscall/user_access.rs +++ b/kernel/src/syscall/user_access.rs @@ -147,13 +147,11 @@ pub fn check_and_clone_cstr_array(user: *const *const u8) -> Result, #[derive(Debug)] pub struct UserBufferWriter<'a> { buffer: &'a mut [u8], - len: usize, } #[derive(Debug)] pub struct UserBufferReader<'a> { buffer: &'a [u8], - len: usize, } impl<'a> UserBufferReader<'a> { @@ -169,8 +167,7 @@ impl<'a> UserBufferReader<'a> { return Err(SystemError::EFAULT); } return Ok(Self { - buffer: unsafe { core::slice::from_raw_parts(addr as *const u8, len) }, - len, + buffer: unsafe { core::slice::from_raw_parts(addr as *const u8, len) } }); } @@ -294,8 +291,7 @@ impl<'a> UserBufferWriter<'a> { return Ok(Self { buffer: unsafe { core::slice::from_raw_parts_mut(addr as *mut u8, len * core::mem::size_of::()) - }, - len, + } }); } @@ -378,11 +374,9 @@ impl<'a> UserBufferWriter<'a> { } } - pub fn get_buffer(&'a mut self, offset: usize) -> Result<&mut [T], SystemError> { - match Self::convert_with_offset(self.buffer, offset) { - Err(_) => return Err(SystemError::EINVAL), - Ok(buffer) => return Ok(buffer), - } + pub fn buffer(&'a mut self, offset: usize) -> Result<&mut [T], SystemError> { + Ok(Self::convert_with_offset::(self.buffer, offset).map_err(|e|SystemError::EINVAL)?) + } fn convert_with_offset(src: &mut [u8], offset: usize) -> Result<&mut [T], SystemError> { From 9203b3bee27edf984a34559c267b71848733550b Mon Sep 17 00:00:00 2001 From: longjin Date: Mon, 21 Aug 2023 10:30:55 +0000 Subject: [PATCH 11/11] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=86=85=E5=AD=98?= =?UTF-8?q?=E8=B6=8A=E7=95=8C=E7=9A=84bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel/src/syscall/user_access.rs | 135 +++++++----------------------- 1 file changed, 29 insertions(+), 106 deletions(-) diff --git a/kernel/src/syscall/user_access.rs b/kernel/src/syscall/user_access.rs index b87bdd0c4..006a30e0a 100644 --- a/kernel/src/syscall/user_access.rs +++ b/kernel/src/syscall/user_access.rs @@ -154,6 +154,7 @@ pub struct UserBufferReader<'a> { buffer: &'a [u8], } +#[allow(dead_code)] impl<'a> UserBufferReader<'a> { /// 构造一个指向用户空间位置的BufferReader,为了兼容类似传入 *const u8 的情况,使用单独的泛型来进行初始化 /// @@ -167,7 +168,7 @@ impl<'a> UserBufferReader<'a> { return Err(SystemError::EFAULT); } return Ok(Self { - buffer: unsafe { core::slice::from_raw_parts(addr as *const u8, len) } + buffer: unsafe { core::slice::from_raw_parts(addr as *const u8, len) }, }); } @@ -177,10 +178,7 @@ impl<'a> UserBufferReader<'a> { /// @return 返回用户空间数据的切片(对单个结构体就返回长度为一的切片) /// pub fn read_from_user(&self, offset: usize) -> Result<&[T], SystemError> { - match self.convert_with_offset(&self.buffer, offset) { - Err(e) => return Err(e), - Ok(data) => return Ok(data), - } + return self.convert_with_offset(&self.buffer, offset); } /// 从用户空间读取一个指定偏移量的数据(到变量中) /// @@ -188,10 +186,7 @@ impl<'a> UserBufferReader<'a> { /// @return 返回用户空间数据的引用 /// pub fn read_one_from_user(&self, offset: usize) -> Result<&T, SystemError> { - match self.convert_one_with_offset(&self.buffer, offset) { - Err(e) => Err(e), - Ok(data) => Ok(data), - } + return self.convert_one_with_offset(&self.buffer, offset); } /// 从用户空间拷贝数据(到指定地址中) @@ -204,12 +199,8 @@ impl<'a> UserBufferReader<'a> { dst: &mut [T], offset: usize, ) -> Result { - match self.convert_with_offset(&self.buffer, offset) { - Err(e) => return Err(e), - Ok(data) => { - dst.copy_from_slice(data); - } - } + let data = self.convert_with_offset(&self.buffer, offset)?; + dst.copy_from_slice(data); return Ok(dst.len()); } @@ -223,13 +214,9 @@ impl<'a> UserBufferReader<'a> { dst: &mut T, offset: usize, ) -> Result<(), SystemError> { - match self.convert_one_with_offset::(&self.buffer, offset) { - Err(e) => return Err(e), - Ok(data) => { - dst.clone_from(data); - return Ok(()); - } - } + let data = self.convert_one_with_offset::(&self.buffer, offset)?; + dst.clone_from(data); + return Ok(()); } fn convert_with_offset(&self, src: &[u8], offset: usize) -> Result<&[T], SystemError> { @@ -237,13 +224,10 @@ impl<'a> UserBufferReader<'a> { return Err(SystemError::EINVAL); } let byte_buffer: &[u8] = &src[offset..]; - if byte_buffer.len() % core::mem::size_of::() != 0 { + if byte_buffer.len() % core::mem::size_of::() != 0 || byte_buffer.is_empty() { return Err(SystemError::EINVAL); } - // let (prefix, chunks, suffix) = unsafe { byte_buffer.align_to::() }; - // if !prefix.is_empty() || !suffix.is_empty() { - // return Err(SystemError::EINVAL); - // } + let chunks = unsafe { from_raw_parts( byte_buffer.as_ptr() as *const T, @@ -254,23 +238,18 @@ impl<'a> UserBufferReader<'a> { } fn convert_one_with_offset(&self, src: &[u8], offset: usize) -> Result<&T, SystemError> { - if offset >= src.len() { - return Err(SystemError::EINVAL); - } - let byte_buffer: &[u8] = &src[offset..]; - if byte_buffer.len() % core::mem::size_of::() != 0 { + if offset + core::mem::size_of::() > src.len() { return Err(SystemError::EINVAL); } - // let (prefix, chunks, suffix) = unsafe { byte_buffer.align_to::() }; - // if !prefix.is_empty() || !suffix.is_empty() { - // return Err(SystemError::EINVAL); - // } + let byte_buffer: &[u8] = &src[offset..offset + core::mem::size_of::()]; + let chunks = unsafe { from_raw_parts(byte_buffer.as_ptr() as *const T, 1) }; let data = &chunks[0]; return Ok(data); } } +#[allow(dead_code)] impl<'a> UserBufferWriter<'a> { /// 构造一个指向用户空间位置的BufferWriter /// @@ -291,49 +270,10 @@ impl<'a> UserBufferWriter<'a> { return Ok(Self { buffer: unsafe { core::slice::from_raw_parts_mut(addr as *mut u8, len * core::mem::size_of::()) - } + }, }); } - /// 从结构体写入数据到用户空间 - /// - /// @param data 要写入的数据(如果是单个对象,也封装成只有一个元素的切片) - /// @return Result<(), SystemError> - /// - pub fn write_to_user( - &mut self, - data: &[T], - offset: usize, - ) -> Result<(), SystemError> { - match Self::convert_with_offset(self.buffer, offset) { - Err(e) => Err(e), - Ok(dst) => { - dst.copy_from_slice(data); - return Ok(()); - } - } - } - - /// 从结构体写入单个数据到用户空间 - /// - /// @param data 要写入的数据 - /// @param offset 在UserBuffer中的字节偏移量 - /// @return Result<(), SystemError> - /// - pub fn write_one_to_user( - &'a mut self, - data: &T, - offset: usize, - ) -> Result<(), SystemError> { - match Self::convert_one_with_offset::(self.buffer, offset) { - Err(e) => Err(e), - Ok(dst) => { - dst.clone_from(data); - return Ok(()); - } - } - } - /// 从指定地址写入数据到用户空间 /// /// @param data 要写入的数据地址 @@ -345,13 +285,9 @@ impl<'a> UserBufferWriter<'a> { src: &'a [T], offset: usize, ) -> Result { - match Self::convert_with_offset(self.buffer, offset) { - Err(_) => return Err(SystemError::EINVAL), - Ok(dst) => { - dst.copy_from_slice(&src); - return Ok(src.len()); - } - } + let dst = Self::convert_with_offset(self.buffer, offset)?; + dst.copy_from_slice(&src); + return Ok(src.len()); } /// 从指定地址写入一个数据到用户空间 @@ -365,18 +301,13 @@ impl<'a> UserBufferWriter<'a> { src: &'a T, offset: usize, ) -> Result<(), SystemError> { - match Self::convert_one_with_offset::(self.buffer, offset) { - Err(_) => return Err(SystemError::EINVAL), - Ok(dst) => { - dst.clone_from(src); - return Ok(()); - } - } + let dst = Self::convert_one_with_offset::(self.buffer, offset)?; + dst.clone_from(src); + return Ok(()); } pub fn buffer(&'a mut self, offset: usize) -> Result<&mut [T], SystemError> { - Ok(Self::convert_with_offset::(self.buffer, offset).map_err(|e|SystemError::EINVAL)?) - + Ok(Self::convert_with_offset::(self.buffer, offset).map_err(|_| SystemError::EINVAL)?) } fn convert_with_offset(src: &mut [u8], offset: usize) -> Result<&mut [T], SystemError> { @@ -384,13 +315,10 @@ impl<'a> UserBufferWriter<'a> { return Err(SystemError::EINVAL); } let byte_buffer: &mut [u8] = &mut src[offset..]; - if byte_buffer.len() % core::mem::size_of::() != 0 { + if byte_buffer.len() % core::mem::size_of::() != 0 || byte_buffer.is_empty() { return Err(SystemError::EINVAL); } - // let (prefix, chunks, suffix) = unsafe { byte_buffer.align_to_mut::() }; - // if !prefix.is_empty() || !suffix.is_empty() { - // return Err(SystemError::EINVAL); - // } + let chunks = unsafe { from_raw_parts_mut( byte_buffer.as_mut_ptr() as *mut T, @@ -399,18 +327,13 @@ impl<'a> UserBufferWriter<'a> { }; return Ok(chunks); } + fn convert_one_with_offset(src: &mut [u8], offset: usize) -> Result<&mut T, SystemError> { - if offset >= src.len() { + if offset + core::mem::size_of::() > src.len() { return Err(SystemError::EINVAL); } - let byte_buffer: &mut [u8] = &mut src[offset..]; - if byte_buffer.len() % core::mem::size_of::() != 0 { - return Err(SystemError::EINVAL); - } - // let (prefix, chunks, suffix) = unsafe { byte_buffer.align_to_mut::() }; - // if !prefix.is_empty() || !suffix.is_empty() { - // return Err(SystemError::EINVAL); - // } + let byte_buffer: &mut [u8] = &mut src[offset..offset + core::mem::size_of::()]; + let chunks = unsafe { from_raw_parts_mut(byte_buffer.as_mut_ptr() as *mut T, 1) }; let data = &mut chunks[0]; return Ok(data);