Support force-write via `/proc/pid/mem`
This commit is contained in:
parent
35b9841cee
commit
bf7709f345
|
|
@ -331,15 +331,7 @@ impl VmMapping {
|
|||
page_fault_info: &PageFaultInfo,
|
||||
rss_delta: &mut RssDelta,
|
||||
) -> Result<()> {
|
||||
if !self.perms.contains(page_fault_info.required_perms) {
|
||||
trace!(
|
||||
"self.perms {:?}, page_fault_info.required_perms {:?}, self.range {:?}",
|
||||
self.perms,
|
||||
page_fault_info.required_perms,
|
||||
self.range()
|
||||
);
|
||||
return_errno_with_message!(Errno::EACCES, "perm check fails");
|
||||
}
|
||||
self.check_perms_for_page_fault(page_fault_info)?;
|
||||
|
||||
let page_aligned_addr = page_fault_info.address.align_down(PAGE_SIZE);
|
||||
let is_write = page_fault_info.required_perms.contains(VmPerms::WRITE);
|
||||
|
|
@ -379,6 +371,33 @@ impl VmMapping {
|
|||
)
|
||||
}
|
||||
|
||||
fn check_perms_for_page_fault(&self, page_fault_info: &PageFaultInfo) -> Result<()> {
|
||||
trace!(
|
||||
"self.perms {:?}, page_fault_info.required_perms {:?}, self.range {:?}",
|
||||
self.perms,
|
||||
page_fault_info.required_perms,
|
||||
self.range()
|
||||
);
|
||||
|
||||
let mut perms = self.perms;
|
||||
|
||||
// Reference: <https://elixir.bootlin.com/linux/v6.16.5/source/mm/gup.c#L1282-L1311>
|
||||
if page_fault_info.is_forced {
|
||||
if perms.contains(VmPerms::MAY_READ) {
|
||||
perms.insert(VmPerms::READ);
|
||||
}
|
||||
if self.is_cow() {
|
||||
perms.insert(VmPerms::WRITE);
|
||||
}
|
||||
}
|
||||
|
||||
if !perms.contains(page_fault_info.required_perms) {
|
||||
return_errno_with_message!(Errno::EACCES, "perm check fails");
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn handle_single_page_fault(
|
||||
&self,
|
||||
vm_space: &VmSpace,
|
||||
|
|
@ -430,7 +449,6 @@ impl VmMapping {
|
|||
let new_frame = duplicate_frame(&frame)?;
|
||||
prop.flags |= new_flags;
|
||||
cursor.map(new_frame.into(), prop);
|
||||
rss_delta.add(self.rss_type(), 1);
|
||||
}
|
||||
cursor.flusher().sync_tlb_flush();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,8 +37,9 @@ FN_TEST(proc_mem_remote)
|
|||
CHECK(close(pipe_p2c[1]));
|
||||
|
||||
int fd = CHECK(open(FILE_NAME, O_RDONLY));
|
||||
void *addr =
|
||||
CHECK_WITH(mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE,
|
||||
// The parent should successfully read from and (force) write to this
|
||||
// memory region via `/proc/pid/mem`, although it isn't `PROT_WRITE`.
|
||||
void *addr = CHECK_WITH(mmap(NULL, PAGE_SIZE, PROT_READ,
|
||||
MAP_PRIVATE, fd, 0),
|
||||
_ret != MAP_FAILED);
|
||||
CHECK(write(pipe_c2p[1], &addr, sizeof(addr)));
|
||||
|
|
|
|||
Loading…
Reference in New Issue