mirror of
https://github.com/rcore-os/rCore.git
synced 2024-11-22 16:16:16 +04:00
fix check user ptr across VMAs
This commit is contained in:
parent
a25c8132fe
commit
60cdea81d9
@ -3,6 +3,7 @@
|
||||
|
||||
use alloc::{boxed::Box, string::String, vec::Vec};
|
||||
use core::fmt::{Debug, Error, Formatter};
|
||||
use core::mem::size_of;
|
||||
|
||||
use crate::paging::*;
|
||||
|
||||
@ -52,16 +53,27 @@ impl MemoryArea {
|
||||
pub fn contains(&self, addr: VirtAddr) -> bool {
|
||||
addr >= self.start_addr && addr < self.end_addr
|
||||
}
|
||||
/// Check the array is within the readable memory
|
||||
fn check_read_array<S>(&self, ptr: *const S, count: usize) -> bool {
|
||||
/// Check the array is within the readable memory.
|
||||
/// Return the size of space covered in the area.
|
||||
fn check_read_array<S>(&self, ptr: *const S, count: usize) -> usize {
|
||||
// page align
|
||||
ptr as usize >= Page::of_addr(self.start_addr).start_address()
|
||||
&& unsafe { ptr.add(count) as usize }
|
||||
< Page::of_addr(self.end_addr + PAGE_SIZE - 1).start_address()
|
||||
let min_bound = (ptr as usize).max(Page::of_addr(self.start_addr).start_address());
|
||||
let max_bound = unsafe { ptr.add(count) as usize }
|
||||
.min(Page::of_addr(self.end_addr + PAGE_SIZE - 1).start_address());
|
||||
if max_bound >= min_bound {
|
||||
max_bound - min_bound
|
||||
} else {
|
||||
0
|
||||
}
|
||||
}
|
||||
/// Check the array is within the writable memory
|
||||
fn check_write_array<S>(&self, ptr: *mut S, count: usize) -> bool {
|
||||
!self.attr.readonly && self.check_read_array(ptr, count)
|
||||
/// Check the array is within the writable memory.
|
||||
/// Return the size of space covered in the area.
|
||||
fn check_write_array<S>(&self, ptr: *mut S, count: usize) -> usize {
|
||||
if self.attr.readonly {
|
||||
0
|
||||
} else {
|
||||
self.check_read_array(ptr, count)
|
||||
}
|
||||
}
|
||||
/// Check the null-end C string is within the readable memory, and is valid.
|
||||
/// If so, clone it to a String.
|
||||
@ -198,11 +210,14 @@ impl<T: InactivePageTable> MemorySet<T> {
|
||||
ptr: *const S,
|
||||
count: usize,
|
||||
) -> VMResult<&'static [S]> {
|
||||
self.areas
|
||||
.iter()
|
||||
.find(|area| area.check_read_array(ptr, count))
|
||||
.map(|_| core::slice::from_raw_parts(ptr, count))
|
||||
.ok_or(VMError::InvalidPtr)
|
||||
let mut valid_size = 0;
|
||||
for area in self.areas.iter() {
|
||||
valid_size += area.check_read_array(ptr, count);
|
||||
if valid_size == size_of::<S>() * count {
|
||||
return Ok(core::slice::from_raw_parts(ptr, count));
|
||||
}
|
||||
}
|
||||
Err(VMError::InvalidPtr)
|
||||
}
|
||||
/// Check the array is within the writable memory
|
||||
pub unsafe fn check_write_array<S>(
|
||||
@ -210,11 +225,14 @@ impl<T: InactivePageTable> MemorySet<T> {
|
||||
ptr: *mut S,
|
||||
count: usize,
|
||||
) -> VMResult<&'static mut [S]> {
|
||||
self.areas
|
||||
.iter()
|
||||
.find(|area| area.check_write_array(ptr, count))
|
||||
.map(|_| core::slice::from_raw_parts_mut(ptr, count))
|
||||
.ok_or(VMError::InvalidPtr)
|
||||
let mut valid_size = 0;
|
||||
for area in self.areas.iter() {
|
||||
valid_size += area.check_write_array(ptr, count);
|
||||
if valid_size == size_of::<S>() * count {
|
||||
return Ok(core::slice::from_raw_parts_mut(ptr, count));
|
||||
}
|
||||
}
|
||||
Err(VMError::InvalidPtr)
|
||||
}
|
||||
/// Check the null-end C string pointer array
|
||||
/// Used for getting argv & envp
|
||||
|
@ -189,14 +189,14 @@ impl Thread {
|
||||
let ustack_top = USER_STACK_OFFSET + USER_STACK_SIZE;
|
||||
vm.push(
|
||||
ustack_buttom,
|
||||
ustack_top - PAGE_SIZE,
|
||||
ustack_top - PAGE_SIZE * 4,
|
||||
MemoryAttr::default().user(),
|
||||
Delay::new(GlobalFrameAlloc),
|
||||
"user_stack_delay",
|
||||
);
|
||||
// We are going to write init info now. So map the last page eagerly.
|
||||
// We are going to write init info now. So map the last 4 pages eagerly.
|
||||
vm.push(
|
||||
ustack_top - PAGE_SIZE,
|
||||
ustack_top - PAGE_SIZE * 4,
|
||||
ustack_top,
|
||||
MemoryAttr::default().user(),
|
||||
ByFrame::new(GlobalFrameAlloc),
|
||||
|
Loading…
Reference in New Issue
Block a user