Skip to content

Commit 58676c8

Browse files
refactor(mm): 重命名 verify_area 为 access_ok 并改进文档 (#1597)
重命名理由: - verify_area 暗示"已验证可访问",具有误导性 - access_ok 强调"快速范围检查",符合实际行为 文档改进: - 明确说明这只是第一层检查,不保证真正可访问 - 添加粗体警告,防止误用为"已验证可访问" - 补充典型用法示例,展示配合 copy_to_user 的正确模式 这将函数语义从"验证已完成"纠正为"可以尝试访问", 避免开发者误认为 Ok(()) 代表地址已映射或真正可访问。
1 parent d3aea1d commit 58676c8

File tree

22 files changed

+75
-57
lines changed

22 files changed

+75
-57
lines changed

kernel/src/arch/x86_64/process/syscall.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use crate::{
77
process::table::{USER_CS, USER_DS},
88
MMArch,
99
},
10-
mm::{verify_area, MemoryManagementArch, VirtAddr},
10+
mm::{access_ok, MemoryManagementArch, VirtAddr},
1111
process::{
1212
exec::{BinaryLoaderResult, ExecParam},
1313
ProcessControlBlock, ProcessManager,
@@ -107,7 +107,7 @@ impl Syscall {
107107
ARCH_SET_FS => {
108108
// 验证FS地址是否为有效的用户空间地址
109109
let fs_addr = VirtAddr::new(arg2);
110-
verify_area(fs_addr, MMArch::PAGE_SIZE).map_err(|_| SystemError::EPERM)?;
110+
access_ok(fs_addr, MMArch::PAGE_SIZE).map_err(|_| SystemError::EPERM)?;
111111
arch_info.fsbase = arg2;
112112
// 如果是当前进程则直接写入寄存器
113113
if pcb.raw_pid() == ProcessManager::current_pcb().raw_pid() {
@@ -117,7 +117,7 @@ impl Syscall {
117117
ARCH_SET_GS => {
118118
// 验证GS地址是否为有效的用户空间地址
119119
let gs_addr = VirtAddr::new(arg2);
120-
verify_area(gs_addr, MMArch::PAGE_SIZE).map_err(|_| SystemError::EPERM)?;
120+
access_ok(gs_addr, MMArch::PAGE_SIZE).map_err(|_| SystemError::EPERM)?;
121121
arch_info.gsbase = arg2;
122122
if pcb.raw_pid() == ProcessManager::current_pcb().raw_pid() {
123123
unsafe { arch_info.restore_gsbase() }

kernel/src/driver/disk/ahci/ahcidisk.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ use crate::driver::disk::ahci::hba::{
2323
};
2424
use crate::libs::rwsem::{RwSemReadGuard, RwSemWriteGuard};
2525
use crate::libs::spinlock::{SpinLock, SpinLockGuard};
26-
use crate::mm::{verify_area, MemoryManagementArch, PhysAddr, VirtAddr};
26+
use crate::mm::{access_ok, MemoryManagementArch, PhysAddr, VirtAddr};
2727
use log::error;
2828
use system_error::SystemError;
2929

@@ -114,7 +114,7 @@ impl AhciDisk {
114114
// 由于目前的内存管理机制无法把用户空间的内存地址转换为物理地址,所以只能先把数据拷贝到内核空间
115115
// TODO:在内存管理重构后,可以直接使用用户空间的内存地址
116116

117-
let user_buf = verify_area(VirtAddr::new(buf_ptr), buf.len()).is_ok();
117+
let user_buf = access_ok(VirtAddr::new(buf_ptr), buf.len()).is_ok();
118118
let mut kbuf = if user_buf {
119119
let x: Vec<u8> = vec![0; buf.len()];
120120
Some(x)
@@ -276,7 +276,7 @@ impl AhciDisk {
276276

277277
// 由于目前的内存管理机制无法把用户空间的内存地址转换为物理地址,所以只能先把数据拷贝到内核空间
278278
// TODO:在内存管理重构后,可以直接使用用户空间的内存地址
279-
let user_buf = verify_area(VirtAddr::new(buf_ptr), buf.len()).is_ok();
279+
let user_buf = access_ok(VirtAddr::new(buf_ptr), buf.len()).is_ok();
280280
let mut kbuf = if user_buf {
281281
let mut x: Vec<u8> = vec![0; buf.len()];
282282
x.resize(buf.len(), 0);

kernel/src/filesystem/vfs/iov.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use alloc::vec::Vec;
22
use system_error::SystemError;
33

44
use crate::{
5-
mm::verify_area,
5+
mm::access_ok,
66
mm::VirtAddr,
77
syscall::user_access::{
88
copy_from_user_protected, user_accessible_len, UserBufferReader, UserBufferWriter,
@@ -93,7 +93,7 @@ impl IoVecs {
9393
// This checks that the address range is within user space limits,
9494
// but does NOT traverse page tables or check actual mappings.
9595
// Actual page mapping/permission checks happen during copy operations.
96-
verify_area(base, one.iov_len)?;
96+
access_ok(base, one.iov_len)?;
9797

9898
// Skip zero-length iovecs after validation
9999
if one.iov_len == 0 {

kernel/src/filesystem/vfs/syscall/sys_getcwd.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use crate::alloc::string::ToString;
66
use crate::arch::interrupt::TrapFrame;
77
use crate::arch::syscall::nr::SYS_GETCWD;
88
use crate::filesystem::vfs::utils::is_ancestor;
9-
use crate::mm::verify_area;
9+
use crate::mm::access_ok;
1010
use crate::mm::VirtAddr;
1111
use crate::process::ProcessManager;
1212
use crate::syscall::table::FormattedSyscallParam;
@@ -36,7 +36,7 @@ impl Syscall for SysGetcwdHandle {
3636
let size = Self::size(args);
3737

3838
let security_check = || {
39-
verify_area(VirtAddr::new(buf_vaddr as usize), size)?;
39+
access_ok(VirtAddr::new(buf_vaddr as usize), size)?;
4040
return Ok(());
4141
};
4242
let r = security_check();

kernel/src/libs/futex/syscall/sys_futex.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use crate::libs::futex::{constant::*, futex::Futex};
66

77
use crate::{
88
arch::{interrupt::TrapFrame, syscall::nr::SYS_FUTEX},
9-
mm::{verify_area, VirtAddr},
9+
mm::{access_ok, VirtAddr},
1010
syscall::{
1111
table::{FormattedSyscallParam, Syscall},
1212
user_access::UserBufferReader,
@@ -165,7 +165,7 @@ pub(super) fn do_futex(
165165
| FutexArg::FUTEX_WAKE_OP
166166
| FutexArg::FUTEX_WAIT_REQUEUE_PI
167167
| FutexArg::FUTEX_CMP_REQUEUE_PI => {
168-
verify_area(uaddr2, core::mem::size_of::<u32>())?;
168+
access_ok(uaddr2, core::mem::size_of::<u32>())?;
169169
}
170170
_ => {}
171171
}
@@ -193,7 +193,7 @@ pub(super) fn do_futex(
193193
&& uaddr.data() == 0;
194194

195195
if !skip_uaddr_check {
196-
verify_area(uaddr, core::mem::size_of::<u32>())?;
196+
access_ok(uaddr, core::mem::size_of::<u32>())?;
197197
}
198198

199199
match cmd {

kernel/src/libs/futex/syscall/sys_robust_futex.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use system_error::SystemError;
33
use crate::{
44
arch::interrupt::TrapFrame,
55
arch::syscall::nr::{SYS_GET_ROBUST_LIST, SYS_SET_ROBUST_LIST},
6-
mm::{verify_area, VirtAddr},
6+
mm::{access_ok, VirtAddr},
77
syscall::table::{FormattedSyscallParam, Syscall},
88
};
99
use alloc::{string::ToString, vec::Vec};
@@ -39,7 +39,7 @@ impl Syscall for SysSetRobustListHandle {
3939
let len = Self::len(args);
4040

4141
// 判断用户空间地址的合法性
42-
verify_area(head, core::mem::size_of::<u32>())?;
42+
access_ok(head, core::mem::size_of::<u32>())?;
4343

4444
let result = crate::libs::futex::futex::RobustListHead::set_robust_list(head, len);
4545

@@ -99,8 +99,8 @@ impl Syscall for SysGetRobustListHandle {
9999
let len_ptr = Self::len_ptr(args);
100100

101101
// 判断用户空间地址的合法性
102-
verify_area(head, core::mem::size_of::<u32>())?;
103-
verify_area(len_ptr, core::mem::size_of::<u32>())?;
102+
access_ok(head, core::mem::size_of::<u32>())?;
103+
access_ok(len_ptr, core::mem::size_of::<u32>())?;
104104

105105
crate::libs::futex::futex::RobustListHead::get_robust_list(pid, head, len_ptr)
106106
}

kernel/src/mm/mod.rs

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -921,13 +921,31 @@ impl Ord for VirtRegion {
921921
}
922922
}
923923

924-
/// ## 判断虚拟地址是否超出了用户空间
924+
/// ## 快速检查用户地址范围的基本合法性
925925
///
926-
/// 如果虚拟地址超出了用户空间,返回Err(SystemError::EFAULT).
927-
/// 如果end < start,返回Err(SystemError::EOVERFLOW)
926+
/// 该函数是**第一层检查**,仅验证地址是否在用户空间范围内,
927+
/// 以及是否发生算术溢出。**不保证地址真正可访问**。
928928
///
929-
/// 否则返回Ok(())
930-
pub fn verify_area(addr: VirtAddr, size: usize) -> Result<(), SystemError> {
929+
/// ⚠️ **重要**: 返回 `Ok(())` 不意味着地址已映射或真正可访问。
930+
/// 实际访问时仍可能触发缺页异常。
931+
///
932+
/// ### 参数
933+
/// - `addr`: 起始虚拟地址
934+
/// - `size`: 要检查的字节数
935+
///
936+
/// ### 返回值
937+
/// - `Ok(())`: 地址范围看起来合法,**可以尝试访问**
938+
/// - `Err(SystemError::EFAULT)`: 地址不在用户空间
939+
/// - `Err(SystemError::EOVERFLOW)`: `addr + size` 溢出
940+
///
941+
/// ### 典型用法
942+
/// ```rust
943+
/// // 作为快速失败的前置检查
944+
/// if access_ok(user_ptr, size).is_ok() {
945+
/// copy_to_user(user_ptr, data, size)?; // 真正的访问(带缺页处理)
946+
/// }
947+
/// ```
948+
pub fn access_ok(addr: VirtAddr, size: usize) -> Result<(), SystemError> {
931949
let end = addr.add(size);
932950
if unlikely(end.data() < addr.data()) {
933951
return Err(SystemError::EOVERFLOW);

kernel/src/mm/syscall/sys_madvise.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use crate::libs::align::page_align_up;
55
use crate::mm::{
66
syscall::{MadvFlags, PageFrameCount},
77
ucontext::AddressSpace,
8-
MemoryManagementArch, VirtPageFrame, {verify_area, VirtAddr},
8+
MemoryManagementArch, VirtPageFrame, {access_ok, VirtAddr},
99
};
1010
use crate::syscall::table::{FormattedSyscallParam, Syscall};
1111
use system_error::SystemError;
@@ -62,7 +62,7 @@ impl Syscall for SysMadviseHandle {
6262
}
6363

6464
// 验证地址范围的有效性
65-
if verify_area(start_vaddr, aligned_len).is_err() {
65+
if access_ok(start_vaddr, aligned_len).is_err() {
6666
return Err(SystemError::EINVAL);
6767
}
6868

kernel/src/mm/syscall/sys_mincore.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use crate::arch::MMArch;
44
use crate::libs::align::page_align_up;
55
use crate::mm::allocator::page_frame::{PageFrameCount, VirtPageFrame};
66
use crate::mm::ucontext::AddressSpace;
7-
use crate::mm::{verify_area, MemoryManagementArch};
7+
use crate::mm::{access_ok, MemoryManagementArch};
88
use crate::syscall::table::{FormattedSyscallParam, Syscall};
99
use crate::syscall::user_access::UserBufferWriter;
1010
use system_error::SystemError;
@@ -35,7 +35,7 @@ impl Syscall for SysMincoreHandle {
3535
return Err(SystemError::EINVAL);
3636
}
3737

38-
if verify_area(start_vaddr, len).is_err() {
38+
if access_ok(start_vaddr, len).is_err() {
3939
return Err(SystemError::ENOMEM);
4040
}
4141
if len == 0 {

kernel/src/mm/syscall/sys_mmap.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use crate::mm::syscall::MapFlags;
77
use crate::mm::ucontext::DEFAULT_MMAP_MIN_ADDR;
88
use crate::mm::AddressSpace;
99
use crate::mm::VirtAddr;
10-
use crate::mm::{verify_area, MemoryManagementArch};
10+
use crate::mm::{access_ok, MemoryManagementArch};
1111
use crate::syscall::table::{FormattedSyscallParam, Syscall};
1212
use log::error;
1313
use system_error::SystemError;
@@ -60,7 +60,7 @@ impl Syscall for SysMmapHandle {
6060
}
6161
let offset = offset_raw as usize;
6262
// 基础参数校验
63-
if verify_area(start_vaddr, len).is_err() {
63+
if access_ok(start_vaddr, len).is_err() {
6464
return Err(SystemError::EFAULT);
6565
}
6666

0 commit comments

Comments
 (0)