user_access.rs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352
  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. pub fn size(&self) -> usize {
  155. return self.buffer.len();
  156. }
  157. /// 从用户空间读取数据(到变量中)
  158. ///
  159. /// @param offset 字节偏移量
  160. /// @return 返回用户空间数据的切片(对单个结构体就返回长度为一的切片)
  161. ///
  162. pub fn read_from_user<T>(&self, offset: usize) -> Result<&[T], SystemError> {
  163. return self.convert_with_offset(&self.buffer, offset);
  164. }
  165. /// 从用户空间读取一个指定偏移量的数据(到变量中)
  166. ///
  167. /// @param offset 字节偏移量
  168. /// @return 返回用户空间数据的引用
  169. ///
  170. pub fn read_one_from_user<T>(&self, offset: usize) -> Result<&T, SystemError> {
  171. return self.convert_one_with_offset(&self.buffer, offset);
  172. }
  173. /// 从用户空间拷贝数据(到指定地址中)
  174. ///
  175. /// @param dst 目标地址指针
  176. /// @return 拷贝成功的话返回拷贝的元素数量
  177. ///
  178. pub fn copy_from_user<T: core::marker::Copy>(
  179. &self,
  180. dst: &mut [T],
  181. offset: usize,
  182. ) -> Result<usize, SystemError> {
  183. let data = self.convert_with_offset(&self.buffer, offset)?;
  184. dst.copy_from_slice(data);
  185. return Ok(dst.len());
  186. }
  187. /// 从用户空间拷贝数据(到指定地址中)
  188. ///
  189. /// @param dst 目标地址指针
  190. /// @return 拷贝成功的话返回拷贝的元素数量
  191. ///
  192. pub fn copy_one_from_user<T: core::marker::Copy>(
  193. &self,
  194. dst: &mut T,
  195. offset: usize,
  196. ) -> Result<(), SystemError> {
  197. let data = self.convert_one_with_offset::<T>(&self.buffer, offset)?;
  198. dst.clone_from(data);
  199. return Ok(());
  200. }
  201. /// 把用户空间的数据转换成指定类型的切片
  202. ///
  203. /// ## 参数
  204. ///
  205. /// - `offset`:字节偏移量
  206. pub fn buffer<T>(&self, offset: usize) -> Result<&[T], SystemError> {
  207. Ok(self
  208. .convert_with_offset::<T>(self.buffer, offset)
  209. .map_err(|_| SystemError::EINVAL)?)
  210. }
  211. fn convert_with_offset<T>(&self, src: &[u8], offset: usize) -> Result<&[T], SystemError> {
  212. if offset >= src.len() {
  213. return Err(SystemError::EINVAL);
  214. }
  215. let byte_buffer: &[u8] = &src[offset..];
  216. if byte_buffer.len() % core::mem::size_of::<T>() != 0 || byte_buffer.is_empty() {
  217. return Err(SystemError::EINVAL);
  218. }
  219. let chunks = unsafe {
  220. from_raw_parts(
  221. byte_buffer.as_ptr() as *const T,
  222. byte_buffer.len() / core::mem::size_of::<T>(),
  223. )
  224. };
  225. return Ok(chunks);
  226. }
  227. fn convert_one_with_offset<T>(&self, src: &[u8], offset: usize) -> Result<&T, SystemError> {
  228. if offset + core::mem::size_of::<T>() > src.len() {
  229. return Err(SystemError::EINVAL);
  230. }
  231. let byte_buffer: &[u8] = &src[offset..offset + core::mem::size_of::<T>()];
  232. let chunks = unsafe { from_raw_parts(byte_buffer.as_ptr() as *const T, 1) };
  233. let data = &chunks[0];
  234. return Ok(data);
  235. }
  236. }
  237. #[allow(dead_code)]
  238. impl<'a> UserBufferWriter<'a> {
  239. /// 构造一个指向用户空间位置的BufferWriter
  240. ///
  241. /// @param addr 用户空间指针
  242. /// @param len 缓冲区的字节长度
  243. /// @return 构造成功返回UserbufferWriter实例,否则返回错误码
  244. ///
  245. pub fn new<U>(addr: *mut U, len: usize, from_user: bool) -> Result<Self, SystemError> {
  246. if from_user && verify_area(VirtAddr::new(addr as usize), len).is_err() {
  247. return Err(SystemError::EFAULT);
  248. }
  249. return Ok(Self {
  250. buffer: unsafe { core::slice::from_raw_parts_mut(addr as *mut u8, len) },
  251. });
  252. }
  253. pub fn size(&self) -> usize {
  254. return self.buffer.len();
  255. }
  256. /// 从指定地址写入数据到用户空间
  257. ///
  258. /// @param data 要写入的数据地址
  259. /// @param offset 在UserBuffer中的字节偏移量
  260. /// @return 返回写入元素的数量
  261. ///
  262. pub fn copy_to_user<T: core::marker::Copy>(
  263. &'a mut self,
  264. src: &[T],
  265. offset: usize,
  266. ) -> Result<usize, SystemError> {
  267. let dst = Self::convert_with_offset(self.buffer, offset)?;
  268. dst.copy_from_slice(&src);
  269. return Ok(src.len());
  270. }
  271. /// 从指定地址写入一个数据到用户空间
  272. ///
  273. /// @param data 要写入的数据地址
  274. /// @param offset 在UserBuffer中的字节偏移量
  275. /// @return Ok/Err
  276. ///
  277. pub fn copy_one_to_user<T: core::marker::Copy>(
  278. &'a mut self,
  279. src: &T,
  280. offset: usize,
  281. ) -> Result<(), SystemError> {
  282. let dst = Self::convert_one_with_offset::<T>(self.buffer, offset)?;
  283. dst.clone_from(src);
  284. return Ok(());
  285. }
  286. pub fn buffer<T>(&'a mut self, offset: usize) -> Result<&mut [T], SystemError> {
  287. Ok(Self::convert_with_offset::<T>(self.buffer, offset).map_err(|_| SystemError::EINVAL)?)
  288. }
  289. fn convert_with_offset<T>(src: &mut [u8], offset: usize) -> Result<&mut [T], SystemError> {
  290. if offset >= src.len() {
  291. return Err(SystemError::EINVAL);
  292. }
  293. let byte_buffer: &mut [u8] = &mut src[offset..];
  294. if byte_buffer.len() % core::mem::size_of::<T>() != 0 || byte_buffer.is_empty() {
  295. return Err(SystemError::EINVAL);
  296. }
  297. let chunks = unsafe {
  298. from_raw_parts_mut(
  299. byte_buffer.as_mut_ptr() as *mut T,
  300. byte_buffer.len() / core::mem::size_of::<T>(),
  301. )
  302. };
  303. return Ok(chunks);
  304. }
  305. fn convert_one_with_offset<T>(src: &mut [u8], offset: usize) -> Result<&mut T, SystemError> {
  306. if offset + core::mem::size_of::<T>() > src.len() {
  307. return Err(SystemError::EINVAL);
  308. }
  309. let byte_buffer: &mut [u8] = &mut src[offset..offset + core::mem::size_of::<T>()];
  310. let chunks = unsafe { from_raw_parts_mut(byte_buffer.as_mut_ptr() as *mut T, 1) };
  311. let data = &mut chunks[0];
  312. return Ok(data);
  313. }
  314. }