user_access.rs 11 KB

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