Check userspace NULL pointers without triggering kernel page faults

This commit is contained in:
Zhang Junyang
2024-07-26 22:45:05 +08:00
committed by Tate, Hongliang Tian
parent 91d524c19a
commit 460234a18b
4 changed files with 96 additions and 20 deletions

View File

@ -1,5 +1,7 @@
// SPDX-License-Identifier: MPL-2.0
use core::cmp::min;
use super::SyscallReturn;
use crate::{fs::file_table::FileDesc, prelude::*, util::write_bytes_to_user};
@ -15,8 +17,20 @@ pub fn sys_read(fd: FileDesc, user_buf_addr: Vaddr, buf_len: usize) -> Result<Sy
file_table.get_file(fd)?.clone()
};
let mut read_buf = vec![0u8; buf_len];
let read_len = file.read(&mut read_buf)?;
write_bytes_to_user(user_buf_addr, &mut VmReader::from(read_buf.as_slice()))?;
// According to <https://man7.org/linux/man-pages/man2/read.2.html>, if
// the user specified an empty buffer, we should detect errors by checking
// the file discriptor. If no errors detected, return 0 successfully.
let read_len = if buf_len != 0 {
let mut read_buf = vec![0u8; buf_len];
let read_len = file.read(&mut read_buf)?;
write_bytes_to_user(
user_buf_addr,
&mut VmReader::from(&read_buf[..min(read_len, buf_len)]),
)?;
read_len
} else {
file.read(&mut [])?
};
Ok(SyscallReturn::Return(read_len as _))
}