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`:目标地址不合法
clear_user(dest: VirtAddr, len: usize) -> Result<usize, SystemError>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
copy_to_user(dest: VirtAddr, src: &[u8]) -> Result<usize, SystemError>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 /// 从用户空间拷贝数据到内核空间
copy_from_user(dst: &mut [u8], src: VirtAddr) -> Result<usize, SystemError>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`:用户态地址不合法
check_and_clone_cstr( user: *const u8, max_length: Option<usize>, ) -> Result<String, SystemError>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`:用户态地址不合法
check_and_clone_cstr_array(user: *const *const u8) -> Result<Vec<String>, SystemError>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