1 //! 这个文件用于放置一些内核态访问用户态数据的函数 2 3 use core::{ 4 mem::size_of, 5 num::NonZero, 6 slice::{from_raw_parts, from_raw_parts_mut}, 7 }; 8 9 use alloc::{ffi::CString, vec::Vec}; 10 11 use crate::mm::{verify_area, VirtAddr}; 12 13 use super::SystemError; 14 15 /// 清空用户空间指定范围内的数据 16 /// 17 /// ## 参数 18 /// 19 /// - `dest`:用户空间的目标地址 20 /// - `len`:要清空的数据长度 21 /// 22 /// ## 返回值 23 /// 24 /// 返回清空的数据长度 25 /// 26 /// ## 错误 27 /// 28 /// - `EFAULT`:目标地址不合法 29 pub unsafe fn clear_user(dest: VirtAddr, len: usize) -> Result<usize, SystemError> { 30 verify_area(dest, len).map_err(|_| SystemError::EFAULT)?; 31 32 let p = dest.data() as *mut u8; 33 // 清空用户空间的数据 34 p.write_bytes(0, len); 35 return Ok(len); 36 } 37 38 pub unsafe fn copy_to_user(dest: VirtAddr, src: &[u8]) -> Result<usize, SystemError> { 39 verify_area(dest, src.len()).map_err(|_| SystemError::EFAULT)?; 40 41 let p = dest.data() as *mut u8; 42 // 拷贝数据 43 p.copy_from_nonoverlapping(src.as_ptr(), src.len()); 44 return Ok(src.len()); 45 } 46 47 /// 从用户空间拷贝数据到内核空间 48 pub unsafe fn copy_from_user(dst: &mut [u8], src: VirtAddr) -> Result<usize, SystemError> { 49 verify_area(src, dst.len()).map_err(|_| SystemError::EFAULT)?; 50 51 let src: &[u8] = core::slice::from_raw_parts(src.data() as *const u8, dst.len()); 52 // 拷贝数据 53 dst.copy_from_slice(src); 54 55 return Ok(dst.len()); 56 } 57 58 /// 检查并从用户态拷贝一个 C 字符串。 59 /// 60 /// 一旦遇到非法地址,就会返回错误 61 /// 62 /// ## 参数 63 /// 64 /// - `user`:用户态的 C 字符串指针 65 /// - `max_length`:最大拷贝长度 66 /// 67 /// ## 返回值 68 /// 69 /// 返回拷贝的 C 字符串 70 /// 71 /// ## 错误 72 /// 73 /// - `EFAULT`:用户态地址不合法 74 /// - `EINVAL`:字符串不是合法的 C 字符串 75 pub fn check_and_clone_cstr( 76 user: *const u8, 77 max_length: Option<usize>, 78 ) -> Result<CString, SystemError> { 79 if user.is_null() { 80 return Err(SystemError::EFAULT); 81 } 82 83 // 从用户态读取,直到遇到空字符 '\0' 或者达到最大长度 84 let mut buffer = Vec::new(); 85 for i in 0.. { 86 if max_length.is_some() && max_length.as_ref().unwrap() <= &i { 87 break; 88 } 89 90 let addr = unsafe { user.add(i) }; 91 let mut c = [0u8; 1]; 92 unsafe { 93 copy_from_user(&mut c, VirtAddr::new(addr as usize))?; 94 } 95 if c[0] == 0 { 96 break; 97 } 98 buffer.push(NonZero::new(c[0]).ok_or(SystemError::EINVAL)?); 99 } 100 101 let cstr = CString::from(buffer); 102 103 return Ok(cstr); 104 } 105 106 /// 检查并从用户态拷贝一个 C 字符串数组 107 /// 108 /// 一旦遇到空指针,就会停止拷贝. 一旦遇到非法地址,就会返回错误 109 /// ## 参数 110 /// 111 /// - `user`:用户态的 C 字符串指针数组 112 /// 113 /// ## 返回值 114 /// 115 /// 返回拷贝的 C 字符串数组 116 /// 117 /// ## 错误 118 /// 119 /// - `EFAULT`:用户态地址不合法 120 pub fn check_and_clone_cstr_array(user: *const *const u8) -> Result<Vec<CString>, SystemError> { 121 if user.is_null() { 122 Ok(Vec::new()) 123 } else { 124 // debug!("check_and_clone_cstr_array: {:p}\n", user); 125 let mut buffer = Vec::new(); 126 for i in 0.. { 127 let addr = unsafe { user.add(i) }; 128 let str_ptr: *const u8; 129 // 读取这个地址的值(这个值也是一个指针) 130 unsafe { 131 let dst = [0usize; 1]; 132 let mut dst = core::mem::transmute::<[usize; 1], [u8; size_of::<usize>()]>(dst); 133 copy_from_user(&mut dst, VirtAddr::new(addr as usize))?; 134 let dst = core::mem::transmute::<[u8; size_of::<usize>()], [usize; 1]>(dst); 135 str_ptr = dst[0] as *const u8; 136 137 // debug!("str_ptr: {:p}, addr:{addr:?}\n", str_ptr); 138 } 139 140 if str_ptr.is_null() { 141 break; 142 } 143 // 读取这个指针指向的字符串 144 let string = check_and_clone_cstr(str_ptr, None)?; 145 // 将字符串放入 buffer 中 146 buffer.push(string); 147 } 148 return Ok(buffer); 149 } 150 } 151 152 #[derive(Debug)] 153 pub struct UserBufferWriter<'a> { 154 buffer: &'a mut [u8], 155 } 156 157 #[derive(Debug)] 158 pub struct UserBufferReader<'a> { 159 buffer: &'a [u8], 160 } 161 162 #[allow(dead_code)] 163 impl<'a> UserBufferReader<'a> { 164 /// 构造一个指向用户空间位置的BufferReader,为了兼容类似传入 *const u8 的情况,使用单独的泛型来进行初始化 165 /// 166 /// @param addr 用户空间指针 167 /// @param len 缓冲区的字节长度 168 /// @param frm_user 代表是否要检验地址来自用户空间 169 /// @return 构造成功返回UserbufferReader实例,否则返回错误码 170 /// 171 pub fn new<U>(addr: *const U, len: usize, from_user: bool) -> Result<Self, SystemError> { 172 if from_user && verify_area(VirtAddr::new(addr as usize), len).is_err() { 173 return Err(SystemError::EFAULT); 174 } 175 return Ok(Self { 176 buffer: unsafe { core::slice::from_raw_parts(addr as *const u8, len) }, 177 }); 178 } 179 180 pub fn size(&self) -> usize { 181 return self.buffer.len(); 182 } 183 184 /// 从用户空间读取数据(到变量中) 185 /// 186 /// @param offset 字节偏移量 187 /// @return 返回用户空间数据的切片(对单个结构体就返回长度为一的切片) 188 /// 189 pub fn read_from_user<T>(&self, offset: usize) -> Result<&[T], SystemError> { 190 return self.convert_with_offset(self.buffer, offset); 191 } 192 /// 从用户空间读取一个指定偏移量的数据(到变量中) 193 /// 194 /// @param offset 字节偏移量 195 /// @return 返回用户空间数据的引用 196 /// 197 pub fn read_one_from_user<T>(&self, offset: usize) -> Result<&T, SystemError> { 198 return self.convert_one_with_offset(self.buffer, offset); 199 } 200 201 /// 从用户空间拷贝数据(到指定地址中) 202 /// 203 /// @param dst 目标地址指针 204 /// @return 拷贝成功的话返回拷贝的元素数量 205 /// 206 pub fn copy_from_user<T: core::marker::Copy>( 207 &self, 208 dst: &mut [T], 209 offset: usize, 210 ) -> Result<usize, SystemError> { 211 let data = self.convert_with_offset(self.buffer, offset)?; 212 dst.copy_from_slice(data); 213 return Ok(dst.len()); 214 } 215 216 /// 从用户空间拷贝数据(到指定地址中) 217 /// 218 /// @param dst 目标地址指针 219 /// @return 拷贝成功的话返回拷贝的元素数量 220 /// 221 pub fn copy_one_from_user<T: core::marker::Copy>( 222 &self, 223 dst: &mut T, 224 offset: usize, 225 ) -> Result<(), SystemError> { 226 let data = self.convert_one_with_offset::<T>(self.buffer, offset)?; 227 dst.clone_from(data); 228 return Ok(()); 229 } 230 231 /// 把用户空间的数据转换成指定类型的切片 232 /// 233 /// ## 参数 234 /// 235 /// - `offset`:字节偏移量 236 pub fn buffer<T>(&self, offset: usize) -> Result<&[T], SystemError> { 237 self.convert_with_offset::<T>(self.buffer, offset) 238 .map_err(|_| SystemError::EINVAL) 239 } 240 241 fn convert_with_offset<T>(&self, src: &[u8], offset: usize) -> Result<&[T], SystemError> { 242 if offset >= src.len() { 243 return Err(SystemError::EINVAL); 244 } 245 let byte_buffer: &[u8] = &src[offset..]; 246 if byte_buffer.len() % core::mem::size_of::<T>() != 0 || byte_buffer.is_empty() { 247 return Err(SystemError::EINVAL); 248 } 249 250 let chunks = unsafe { 251 from_raw_parts( 252 byte_buffer.as_ptr() as *const T, 253 byte_buffer.len() / core::mem::size_of::<T>(), 254 ) 255 }; 256 return Ok(chunks); 257 } 258 259 fn convert_one_with_offset<T>(&self, src: &[u8], offset: usize) -> Result<&T, SystemError> { 260 if offset + core::mem::size_of::<T>() > src.len() { 261 return Err(SystemError::EINVAL); 262 } 263 let byte_buffer: &[u8] = &src[offset..offset + core::mem::size_of::<T>()]; 264 265 let chunks = unsafe { from_raw_parts(byte_buffer.as_ptr() as *const T, 1) }; 266 let data = &chunks[0]; 267 return Ok(data); 268 } 269 } 270 271 #[allow(dead_code)] 272 impl<'a> UserBufferWriter<'a> { 273 /// 构造一个指向用户空间位置的BufferWriter 274 /// 275 /// @param addr 用户空间指针 276 /// @param len 缓冲区的字节长度 277 /// @return 构造成功返回UserbufferWriter实例,否则返回错误码 278 /// 279 pub fn new<U>(addr: *mut U, len: usize, from_user: bool) -> Result<Self, SystemError> { 280 if from_user && verify_area(VirtAddr::new(addr as usize), len).is_err() { 281 return Err(SystemError::EFAULT); 282 } 283 return Ok(Self { 284 buffer: unsafe { core::slice::from_raw_parts_mut(addr as *mut u8, len) }, 285 }); 286 } 287 288 pub fn size(&self) -> usize { 289 return self.buffer.len(); 290 } 291 292 /// 从指定地址写入数据到用户空间 293 /// 294 /// @param data 要写入的数据地址 295 /// @param offset 在UserBuffer中的字节偏移量 296 /// @return 返回写入元素的数量 297 /// 298 pub fn copy_to_user<T: core::marker::Copy>( 299 &'a mut self, 300 src: &[T], 301 offset: usize, 302 ) -> Result<usize, SystemError> { 303 let dst = Self::convert_with_offset(self.buffer, offset)?; 304 dst.copy_from_slice(src); 305 return Ok(src.len()); 306 } 307 308 /// 从指定地址写入一个数据到用户空间 309 /// 310 /// @param data 要写入的数据地址 311 /// @param offset 在UserBuffer中的字节偏移量 312 /// @return Ok/Err 313 /// 314 pub fn copy_one_to_user<T: core::marker::Copy>( 315 &'a mut self, 316 src: &T, 317 offset: usize, 318 ) -> Result<(), SystemError> { 319 let dst = Self::convert_one_with_offset::<T>(self.buffer, offset)?; 320 dst.clone_from(src); 321 return Ok(()); 322 } 323 324 pub fn buffer<T>(&'a mut self, offset: usize) -> Result<&mut [T], SystemError> { 325 Self::convert_with_offset::<T>(self.buffer, offset).map_err(|_| SystemError::EINVAL) 326 } 327 328 fn convert_with_offset<T>(src: &mut [u8], offset: usize) -> Result<&mut [T], SystemError> { 329 if offset >= src.len() { 330 return Err(SystemError::EINVAL); 331 } 332 let byte_buffer: &mut [u8] = &mut src[offset..]; 333 if byte_buffer.len() % core::mem::size_of::<T>() != 0 || byte_buffer.is_empty() { 334 return Err(SystemError::EINVAL); 335 } 336 337 let chunks = unsafe { 338 from_raw_parts_mut( 339 byte_buffer.as_mut_ptr() as *mut T, 340 byte_buffer.len() / core::mem::size_of::<T>(), 341 ) 342 }; 343 return Ok(chunks); 344 } 345 346 fn convert_one_with_offset<T>(src: &mut [u8], offset: usize) -> Result<&mut T, SystemError> { 347 if offset + core::mem::size_of::<T>() > src.len() { 348 return Err(SystemError::EINVAL); 349 } 350 let byte_buffer: &mut [u8] = &mut src[offset..offset + core::mem::size_of::<T>()]; 351 352 let chunks = unsafe { from_raw_parts_mut(byte_buffer.as_mut_ptr() as *mut T, 1) }; 353 let data = &mut chunks[0]; 354 return Ok(data); 355 } 356 } 357