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`:目标地址不合法
clear_user(dest: VirtAddr, len: usize) -> Result<usize, SystemError>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
copy_to_user(dest: VirtAddr, src: &[u8]) -> Result<usize, SystemError>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 /// 从用户空间拷贝数据到内核空间
copy_from_user(dst: &mut [u8], src: VirtAddr) -> Result<usize, SystemError>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`:用户态地址不合法
check_and_clone_cstr( user: *const u8, max_length: Option<usize>, ) -> Result<String, SystemError>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 Err(SystemError::EFAULT);
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 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`:用户态地址不合法
check_and_clone_cstr_array(user: *const *const u8) -> Result<Vec<String>, SystemError>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 // debug!("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 // debug!("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 ///
new<U>(addr: *const U, len: usize, from_user: bool) -> Result<Self, SystemError>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
size(&self) -> usize175 pub fn size(&self) -> usize {
176 return self.buffer.len();
177 }
178
179 /// 从用户空间读取数据(到变量中)
180 ///
181 /// @param offset 字节偏移量
182 /// @return 返回用户空间数据的切片(对单个结构体就返回长度为一的切片)
183 ///
read_from_user<T>(&self, offset: usize) -> Result<&[T], SystemError>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 ///
read_one_from_user<T>(&self, offset: usize) -> Result<&T, SystemError>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 ///
copy_from_user<T: core::marker::Copy>( &self, dst: &mut [T], offset: usize, ) -> Result<usize, SystemError>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 ///
copy_one_from_user<T: core::marker::Copy>( &self, dst: &mut T, offset: usize, ) -> Result<(), SystemError>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`:字节偏移量
buffer<T>(&self, offset: usize) -> Result<&[T], SystemError>231 pub fn buffer<T>(&self, offset: usize) -> Result<&[T], SystemError> {
232 self.convert_with_offset::<T>(self.buffer, offset)
233 .map_err(|_| SystemError::EINVAL)
234 }
235
convert_with_offset<T>(&self, src: &[u8], offset: usize) -> Result<&[T], SystemError>236 fn convert_with_offset<T>(&self, src: &[u8], offset: usize) -> Result<&[T], SystemError> {
237 if offset >= src.len() {
238 return Err(SystemError::EINVAL);
239 }
240 let byte_buffer: &[u8] = &src[offset..];
241 if byte_buffer.len() % core::mem::size_of::<T>() != 0 || byte_buffer.is_empty() {
242 return Err(SystemError::EINVAL);
243 }
244
245 let chunks = unsafe {
246 from_raw_parts(
247 byte_buffer.as_ptr() as *const T,
248 byte_buffer.len() / core::mem::size_of::<T>(),
249 )
250 };
251 return Ok(chunks);
252 }
253
convert_one_with_offset<T>(&self, src: &[u8], offset: usize) -> Result<&T, SystemError>254 fn convert_one_with_offset<T>(&self, src: &[u8], offset: usize) -> Result<&T, SystemError> {
255 if offset + core::mem::size_of::<T>() > src.len() {
256 return Err(SystemError::EINVAL);
257 }
258 let byte_buffer: &[u8] = &src[offset..offset + core::mem::size_of::<T>()];
259
260 let chunks = unsafe { from_raw_parts(byte_buffer.as_ptr() as *const T, 1) };
261 let data = &chunks[0];
262 return Ok(data);
263 }
264 }
265
266 #[allow(dead_code)]
267 impl<'a> UserBufferWriter<'a> {
268 /// 构造一个指向用户空间位置的BufferWriter
269 ///
270 /// @param addr 用户空间指针
271 /// @param len 缓冲区的字节长度
272 /// @return 构造成功返回UserbufferWriter实例,否则返回错误码
273 ///
new<U>(addr: *mut U, len: usize, from_user: bool) -> Result<Self, SystemError>274 pub fn new<U>(addr: *mut U, len: usize, from_user: bool) -> Result<Self, SystemError> {
275 if from_user && verify_area(VirtAddr::new(addr as usize), len).is_err() {
276 return Err(SystemError::EFAULT);
277 }
278 return Ok(Self {
279 buffer: unsafe { core::slice::from_raw_parts_mut(addr as *mut u8, len) },
280 });
281 }
282
size(&self) -> usize283 pub fn size(&self) -> usize {
284 return self.buffer.len();
285 }
286
287 /// 从指定地址写入数据到用户空间
288 ///
289 /// @param data 要写入的数据地址
290 /// @param offset 在UserBuffer中的字节偏移量
291 /// @return 返回写入元素的数量
292 ///
copy_to_user<T: core::marker::Copy>( &'a mut self, src: &[T], offset: usize, ) -> Result<usize, SystemError>293 pub fn copy_to_user<T: core::marker::Copy>(
294 &'a mut self,
295 src: &[T],
296 offset: usize,
297 ) -> Result<usize, SystemError> {
298 let dst = Self::convert_with_offset(self.buffer, offset)?;
299 dst.copy_from_slice(src);
300 return Ok(src.len());
301 }
302
303 /// 从指定地址写入一个数据到用户空间
304 ///
305 /// @param data 要写入的数据地址
306 /// @param offset 在UserBuffer中的字节偏移量
307 /// @return Ok/Err
308 ///
copy_one_to_user<T: core::marker::Copy>( &'a mut self, src: &T, offset: usize, ) -> Result<(), SystemError>309 pub fn copy_one_to_user<T: core::marker::Copy>(
310 &'a mut self,
311 src: &T,
312 offset: usize,
313 ) -> Result<(), SystemError> {
314 let dst = Self::convert_one_with_offset::<T>(self.buffer, offset)?;
315 dst.clone_from(src);
316 return Ok(());
317 }
318
buffer<T>(&'a mut self, offset: usize) -> Result<&mut [T], SystemError>319 pub fn buffer<T>(&'a mut self, offset: usize) -> Result<&mut [T], SystemError> {
320 Self::convert_with_offset::<T>(self.buffer, offset).map_err(|_| SystemError::EINVAL)
321 }
322
convert_with_offset<T>(src: &mut [u8], offset: usize) -> Result<&mut [T], SystemError>323 fn convert_with_offset<T>(src: &mut [u8], offset: usize) -> Result<&mut [T], SystemError> {
324 if offset >= src.len() {
325 return Err(SystemError::EINVAL);
326 }
327 let byte_buffer: &mut [u8] = &mut src[offset..];
328 if byte_buffer.len() % core::mem::size_of::<T>() != 0 || byte_buffer.is_empty() {
329 return Err(SystemError::EINVAL);
330 }
331
332 let chunks = unsafe {
333 from_raw_parts_mut(
334 byte_buffer.as_mut_ptr() as *mut T,
335 byte_buffer.len() / core::mem::size_of::<T>(),
336 )
337 };
338 return Ok(chunks);
339 }
340
convert_one_with_offset<T>(src: &mut [u8], offset: usize) -> Result<&mut T, SystemError>341 fn convert_one_with_offset<T>(src: &mut [u8], offset: usize) -> Result<&mut T, SystemError> {
342 if offset + core::mem::size_of::<T>() > src.len() {
343 return Err(SystemError::EINVAL);
344 }
345 let byte_buffer: &mut [u8] = &mut src[offset..offset + core::mem::size_of::<T>()];
346
347 let chunks = unsafe { from_raw_parts_mut(byte_buffer.as_mut_ptr() as *mut T, 1) };
348 let data = &mut chunks[0];
349 return Ok(data);
350 }
351 }
352