1 //! 这个文件用于放置一些内核态访问用户态数据的函数 2 use core::mem::size_of; 3 4 use alloc::{string::String, vec::Vec}; 5 6 use crate::mm::{verify_area, VirtAddr}; 7 8 use super::SystemError; 9 10 /// 清空用户空间指定范围内的数据 11 /// 12 /// ## 参数 13 /// 14 /// - `dest`:用户空间的目标地址 15 /// - `len`:要清空的数据长度 16 /// 17 /// ## 返回值 18 /// 19 /// 返回清空的数据长度 20 /// 21 /// ## 错误 22 /// 23 /// - `EFAULT`:目标地址不合法 24 pub unsafe fn clear_user(dest: VirtAddr, len: usize) -> Result<usize, SystemError> { 25 verify_area(dest, len).map_err(|_| SystemError::EFAULT)?; 26 27 let p = dest.data() as *mut u8; 28 // 清空用户空间的数据 29 p.write_bytes(0, len); 30 return Ok(len); 31 } 32 33 pub unsafe fn copy_to_user(dest: VirtAddr, src: &[u8]) -> Result<usize, SystemError> { 34 verify_area(dest, src.len()).map_err(|_| SystemError::EFAULT)?; 35 36 let p = dest.data() as *mut u8; 37 // 拷贝数据 38 p.copy_from_nonoverlapping(src.as_ptr(), src.len()); 39 return Ok(src.len()); 40 } 41 42 /// 从用户空间拷贝数据到内核空间 43 pub unsafe fn copy_from_user(dst: &mut [u8], src: VirtAddr) -> Result<usize, SystemError> { 44 verify_area(src, dst.len()).map_err(|_| SystemError::EFAULT)?; 45 46 let src: &[u8] = core::slice::from_raw_parts(src.data() as *const u8, dst.len()); 47 // 拷贝数据 48 dst.copy_from_slice(&src); 49 50 return Ok(dst.len()); 51 } 52 53 /// 检查并从用户态拷贝一个 C 字符串。 54 /// 55 /// 一旦遇到非法地址,就会返回错误 56 /// 57 /// ## 参数 58 /// 59 /// - `user`:用户态的 C 字符串指针 60 /// - `max_length`:最大拷贝长度 61 /// 62 /// ## 返回值 63 /// 64 /// 返回拷贝的 C 字符串 65 /// 66 /// ## 错误 67 /// 68 /// - `EFAULT`:用户态地址不合法 69 pub fn check_and_clone_cstr( 70 user: *const u8, 71 max_length: Option<usize>, 72 ) -> Result<String, SystemError> { 73 if user.is_null() { 74 return Ok(String::new()); 75 } 76 77 // 从用户态读取,直到遇到空字符 '\0' 或者达到最大长度 78 let mut buffer = Vec::new(); 79 for i in 0.. { 80 if max_length.is_some() && max_length.as_ref().unwrap() <= &i { 81 break; 82 } 83 84 let addr = unsafe { user.add(i) }; 85 let mut c = [0u8; 1]; 86 unsafe { 87 copy_from_user(&mut c, VirtAddr::new(addr as usize))?; 88 } 89 if c[0] == 0 { 90 break; 91 } 92 buffer.push(c[0]); 93 } 94 return Ok(String::from_utf8(buffer).map_err(|_| SystemError::EFAULT)?); 95 } 96 97 /// 检查并从用户态拷贝一个 C 字符串数组 98 /// 99 /// 一旦遇到空指针,就会停止拷贝. 一旦遇到非法地址,就会返回错误 100 /// ## 参数 101 /// 102 /// - `user`:用户态的 C 字符串指针数组 103 /// 104 /// ## 返回值 105 /// 106 /// 返回拷贝的 C 字符串数组 107 /// 108 /// ## 错误 109 /// 110 /// - `EFAULT`:用户态地址不合法 111 pub fn check_and_clone_cstr_array(user: *const *const u8) -> Result<Vec<String>, SystemError> { 112 if user.is_null() { 113 Ok(Vec::new()) 114 } else { 115 // kdebug!("check_and_clone_cstr_array: {:p}\n", user); 116 let mut buffer = Vec::new(); 117 for i in 0.. { 118 let addr = unsafe { user.add(i) }; 119 let str_ptr: *const u8; 120 // 读取这个地址的值(这个值也是一个指针) 121 unsafe { 122 let dst = [0usize; 1]; 123 let mut dst = core::mem::transmute::<[usize; 1], [u8; size_of::<usize>()]>(dst); 124 copy_from_user(&mut dst, VirtAddr::new(addr as usize))?; 125 let dst = core::mem::transmute::<[u8; size_of::<usize>()], [usize; 1]>(dst); 126 str_ptr = dst[0] as *const u8; 127 128 // kdebug!("str_ptr: {:p}, addr:{addr:?}\n", str_ptr); 129 } 130 131 if str_ptr.is_null() { 132 break; 133 } 134 // 读取这个指针指向的字符串 135 let string = check_and_clone_cstr(str_ptr, None)?; 136 // 将字符串放入 buffer 中 137 buffer.push(string); 138 } 139 return Ok(buffer); 140 } 141 } 142