-
-
Notifications
You must be signed in to change notification settings - Fork 168
fix(vfs): 修复 pread64 系统调用的兼容性和错误处理 #1398
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
66b967e
696122e
c8c4dd9
c716be8
3f3ef9f
a756668
94d0a91
0dc99c0
667c09c
cbad321
030dfbe
8761ffe
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -4,6 +4,7 @@ use system_error::SystemError; | |||||||||||
|
|
||||||||||||
| use crate::arch::interrupt::TrapFrame; | ||||||||||||
| use crate::arch::syscall::nr::SYS_PREAD64; | ||||||||||||
| use crate::filesystem::vfs::FileType; | ||||||||||||
| use crate::process::ProcessManager; | ||||||||||||
| use crate::syscall::table::FormattedSyscallParam; | ||||||||||||
| use crate::syscall::table::Syscall; | ||||||||||||
|
|
@@ -35,7 +36,18 @@ impl Syscall for SysPread64Handle { | |||||||||||
| let len = Self::len(args); | ||||||||||||
| let offset = Self::offset(args); | ||||||||||||
|
|
||||||||||||
| let mut user_buffer_writer = UserBufferWriter::new(buf_vaddr, len, frame.is_from_user())?; | ||||||||||||
| // 检查offset是否为负数 | ||||||||||||
| if (offset as isize) < 0 { | ||||||||||||
| return Err(SystemError::EINVAL); | ||||||||||||
| } | ||||||||||||
|
|
||||||||||||
| // 检查offset + len是否溢出 | ||||||||||||
| if offset.checked_add(len).is_none() || offset > i64::MAX as usize { | ||||||||||||
|
||||||||||||
| // 检查offset + len是否溢出 | |
| if offset.checked_add(len).is_none() || offset > i64::MAX as usize { | |
| // 检查offset + len是否溢出,并且两者都不能超过i64::MAX | |
| let end_pos = offset.checked_add(len).ok_or(SystemError::EINVAL)?; | |
| if offset > i64::MAX as usize || end_pos > i64::MAX as usize { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
要求用户缓冲区已经映射应该是不对的。可能是pagefault延迟映射。应该是使用protected的那个,校验vma
fslongjin marked this conversation as resolved.
Show resolved
Hide resolved
Outdated
Copilot
AI
Nov 21, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Incomplete file type check for non-seekable files: The check should also include FileType::CharDevice to be consistent with lseek() at file.rs:364, which returns ESPIPE for both Pipe and CharDevice. Character devices like terminals are non-seekable and should fail pread64 with ESPIPE.
Should be: if md.file_type == FileType::Pipe || md.file_type == FileType::Socket || md.file_type == FileType::CharDevice
| if md.file_type == FileType::Pipe || md.file_type == FileType::Socket { | |
| if md.file_type == FileType::Pipe || md.file_type == FileType::Socket || md.file_type == FileType::CharDevice { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bug: CharDevice incorrectly included in ESPIPE file type check
The comment states this check is for pipes and sockets, but the code also includes FileType::CharDevice. According to POSIX, pread64 returns ESPIPE specifically for pipes, FIFOs, and sockets - not character devices. Many character devices like /dev/null and /dev/zero (which are FileType::CharDevice in this codebase) can legitimately support pread operations. Including CharDevice in this check will incorrectly return ESPIPE for valid pread64 calls on such devices.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The check
(offset as isize) < 0is redundant with the check on line 47offset > i64::MAX as usize. Both conditions check if offset >= 2^63 (on 64-bit systems). The first check interprets the value as signed and checks if the sign bit is set, while the second explicitly compares against i64::MAX. Consider removing the first check to avoid duplication and improve code clarity.