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`:目标地址不合法
clear_user(dest: VirtAddr, len: usize) -> Result<usize, SystemError>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
copy_to_user(dest: VirtAddr, src: &[u8]) -> Result<usize, SystemError>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 /// 从用户空间拷贝数据到内核空间
copy_from_user(dst: &mut [u8], src: VirtAddr) -> Result<usize, SystemError>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 字符串
check_and_clone_cstr( user: *const u8, max_length: Option<usize>, ) -> Result<CString, SystemError>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`:用户态地址不合法
check_and_clone_cstr_array(user: *const *const u8) -> Result<Vec<CString>, SystemError>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 UserBufferReader<'_> {
164 /// 构造一个指向用户空间位置的BufferReader,为了兼容类似传入 *const u8 的情况,使用单独的泛型来进行初始化
165 ///
166 /// @param addr 用户空间指针
167 /// @param len 缓冲区的字节长度
168 /// @param frm_user 代表是否要检验地址来自用户空间
169 /// @return 构造成功返回UserbufferReader实例,否则返回错误码
170 ///
new<U>(addr: *const U, len: usize, from_user: bool) -> Result<Self, SystemError>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
size(&self) -> usize180 pub fn size(&self) -> usize {
181 return self.buffer.len();
182 }
183
184 /// 从用户空间读取数据(到变量中)
185 ///
186 /// @param offset 字节偏移量
187 /// @return 返回用户空间数据的切片(对单个结构体就返回长度为一的切片)
188 ///
read_from_user<T>(&self, offset: usize) -> Result<&[T], SystemError>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 ///
read_one_from_user<T>(&self, offset: usize) -> Result<&T, SystemError>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 ///
copy_from_user<T: core::marker::Copy>( &self, dst: &mut [T], offset: usize, ) -> Result<usize, SystemError>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 ///
copy_one_from_user<T: core::marker::Copy>( &self, dst: &mut T, offset: usize, ) -> Result<(), SystemError>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`:字节偏移量
buffer<T>(&self, offset: usize) -> Result<&[T], SystemError>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
convert_with_offset<T>(&self, src: &[u8], offset: usize) -> Result<&[T], SystemError>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
convert_one_with_offset<T>(&self, src: &[u8], offset: usize) -> Result<&T, SystemError>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 ///
new<U>(addr: *mut U, len: usize, from_user: bool) -> Result<Self, SystemError>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
size(&self) -> usize288 pub fn size(&self) -> usize {
289 return self.buffer.len();
290 }
291
292 /// 从指定地址写入数据到用户空间
293 ///
294 /// @param data 要写入的数据地址
295 /// @param offset 在UserBuffer中的字节偏移量
296 /// @return 返回写入元素的数量
297 ///
copy_to_user<T: core::marker::Copy>( &'a mut self, src: &[T], offset: usize, ) -> Result<usize, SystemError>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 ///
copy_one_to_user<T: core::marker::Copy>( &'a mut self, src: &T, offset: usize, ) -> Result<(), SystemError>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
buffer<T>(&'a mut self, offset: usize) -> Result<&'a mut [T], SystemError>324 pub fn buffer<T>(&'a mut self, offset: usize) -> Result<&'a mut [T], SystemError> {
325 Self::convert_with_offset::<T>(self.buffer, offset).map_err(|_| SystemError::EINVAL)
326 }
327
convert_with_offset<T>(src: &mut [u8], offset: usize) -> Result<&mut [T], SystemError>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
convert_one_with_offset<T>(src: &mut [u8], offset: usize) -> Result<&mut T, SystemError>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