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