forked from rcore-os/zCore
Change how we handle the vmar permission
This commit is contained in:
parent
31fde3be20
commit
0988aa6b56
|
@ -19,6 +19,7 @@ pub mod defs {
|
|||
const WRITE = 1 << 3;
|
||||
const EXECUTE = 1 << 4;
|
||||
const USER = 1 << 5;
|
||||
const RXW = Self::READ.bits | Self::WRITE.bits | Self::EXECUTE.bits;
|
||||
}
|
||||
}
|
||||
numeric_enum! {
|
||||
|
|
|
@ -157,7 +157,7 @@ impl VmAddressRegion {
|
|||
len: usize,
|
||||
flags: MMUFlags,
|
||||
) -> ZxResult<VirtAddr> {
|
||||
self.map_ext(Some(vmar_offset), vmo, vmo_offset, len, flags, false, true)
|
||||
self.map(Some(vmar_offset), vmo, vmo_offset, len, flags)
|
||||
}
|
||||
|
||||
/// Map the `vmo` into this VMAR.
|
||||
|
@ -169,7 +169,16 @@ impl VmAddressRegion {
|
|||
len: usize,
|
||||
flags: MMUFlags,
|
||||
) -> ZxResult<VirtAddr> {
|
||||
self.map_ext(vmar_offset, vmo, vmo_offset, len, flags, false, true)
|
||||
self.map_ext(
|
||||
vmar_offset,
|
||||
vmo,
|
||||
vmo_offset,
|
||||
len,
|
||||
MMUFlags::RXW,
|
||||
flags,
|
||||
false,
|
||||
true,
|
||||
)
|
||||
}
|
||||
|
||||
/// Map the `vmo` into this VMAR.
|
||||
|
@ -180,6 +189,7 @@ impl VmAddressRegion {
|
|||
vmo: Arc<VmObject>,
|
||||
vmo_offset: usize,
|
||||
len: usize,
|
||||
permissions: MMUFlags,
|
||||
flags: MMUFlags,
|
||||
overwrite: bool,
|
||||
_map_range: bool,
|
||||
|
@ -187,6 +197,9 @@ impl VmAddressRegion {
|
|||
if !page_aligned(vmo_offset) || !page_aligned(len) || vmo_offset.overflowing_add(len).1 {
|
||||
return Err(ZxError::INVALID_ARGS);
|
||||
}
|
||||
if !permissions.contains(flags & MMUFlags::RXW) {
|
||||
return Err(ZxError::ACCESS_DENIED);
|
||||
}
|
||||
// TODO: allow the mapping extends past the end of vmo
|
||||
if vmo_offset > vmo.len() || len > vmo.len() - vmo_offset {
|
||||
return Err(ZxError::INVALID_ARGS);
|
||||
|
@ -208,7 +221,15 @@ impl VmAddressRegion {
|
|||
return Err(ZxError::NO_MEMORY);
|
||||
}
|
||||
}
|
||||
let mapping = VmMapping::new(addr, len, vmo, vmo_offset, flags, self.page_table.clone());
|
||||
let mapping = VmMapping::new(
|
||||
addr,
|
||||
len,
|
||||
vmo,
|
||||
vmo_offset,
|
||||
permissions,
|
||||
flags,
|
||||
self.page_table.clone(),
|
||||
);
|
||||
let map_range = true;
|
||||
if map_range {
|
||||
mapping.map()?;
|
||||
|
@ -614,6 +635,9 @@ pub struct VmarInfo {
|
|||
|
||||
/// Virtual Memory Mapping
|
||||
pub struct VmMapping {
|
||||
/// The permission limitation of the vmar
|
||||
permissions: MMUFlags,
|
||||
/// The actual flags used in the mapping
|
||||
flags: MMUFlags,
|
||||
vmo: Arc<VmObject>,
|
||||
page_table: Arc<Mutex<dyn PageTableTrait>>,
|
||||
|
@ -643,6 +667,7 @@ impl core::fmt::Debug for VmMapping {
|
|||
f.debug_struct("VmMapping")
|
||||
.field("addr", &inner.addr)
|
||||
.field("size", &inner.size)
|
||||
.field("permissions", &self.permissions)
|
||||
.field("flags", &self.flags)
|
||||
.field("vmo_id", &self.vmo.id())
|
||||
.field("vmo_offset", &inner.vmo_offset)
|
||||
|
@ -656,6 +681,7 @@ impl VmMapping {
|
|||
size: usize,
|
||||
vmo: Arc<VmObject>,
|
||||
vmo_offset: usize,
|
||||
permissions: MMUFlags,
|
||||
flags: MMUFlags,
|
||||
page_table: Arc<Mutex<dyn PageTableTrait>>,
|
||||
) -> Arc<Self> {
|
||||
|
@ -665,6 +691,7 @@ impl VmMapping {
|
|||
size,
|
||||
vmo_offset,
|
||||
}),
|
||||
permissions,
|
||||
flags,
|
||||
page_table,
|
||||
vmo: vmo.clone(),
|
||||
|
@ -769,6 +796,7 @@ impl VmMapping {
|
|||
new_len2,
|
||||
self.vmo.clone(),
|
||||
inner.vmo_offset + (end - inner.addr),
|
||||
self.permissions,
|
||||
self.flags,
|
||||
self.page_table.clone(),
|
||||
))
|
||||
|
@ -786,16 +814,7 @@ impl VmMapping {
|
|||
}
|
||||
|
||||
fn is_valid_mapping_flags(&self, flags: MMUFlags) -> bool {
|
||||
if !flags.contains(MMUFlags::READ) && self.flags.contains(MMUFlags::READ) {
|
||||
return false;
|
||||
}
|
||||
if !flags.contains(MMUFlags::WRITE) && self.flags.contains(MMUFlags::WRITE) {
|
||||
return false;
|
||||
}
|
||||
if !flags.contains(MMUFlags::EXECUTE) && self.flags.contains(MMUFlags::EXECUTE) {
|
||||
return false;
|
||||
}
|
||||
true
|
||||
self.permissions.contains(flags & MMUFlags::RXW)
|
||||
}
|
||||
|
||||
fn protect(&self, flags: MMUFlags) {
|
||||
|
@ -864,6 +883,7 @@ impl VmMapping {
|
|||
let new_vmo = self.vmo.create_child(false, 0, self.vmo.len())?;
|
||||
let mapping = Arc::new(VmMapping {
|
||||
inner: Mutex::new(self.inner.lock().clone()),
|
||||
permissions: self.permissions,
|
||||
flags: self.flags,
|
||||
page_table,
|
||||
vmo: new_vmo.clone(),
|
||||
|
|
|
@ -117,19 +117,17 @@ impl Syscall<'_> {
|
|||
if !is_specific && vmar_offset != 0 {
|
||||
return Err(ZxError::INVALID_ARGS);
|
||||
}
|
||||
if !vmar_rights.contains(options.to_required_rights()) {
|
||||
return Err(ZxError::ACCESS_DENIED);
|
||||
}
|
||||
let mut permissions = MMUFlags::empty();
|
||||
permissions.set(MMUFlags::READ, vmo_rights.contains(Rights::READ));
|
||||
permissions.set(MMUFlags::WRITE, vmo_rights.contains(Rights::WRITE));
|
||||
permissions.set(MMUFlags::EXECUTE, vmo_rights.contains(Rights::EXECUTE));
|
||||
let mut mapping_flags = MMUFlags::USER;
|
||||
mapping_flags.set(
|
||||
MMUFlags::READ,
|
||||
vmar_rights.contains(Rights::READ) && vmo_rights.contains(Rights::READ),
|
||||
);
|
||||
mapping_flags.set(
|
||||
MMUFlags::WRITE,
|
||||
vmar_rights.contains(Rights::WRITE) && vmo_rights.contains(Rights::WRITE),
|
||||
);
|
||||
mapping_flags.set(
|
||||
MMUFlags::EXECUTE,
|
||||
vmar_rights.contains(Rights::EXECUTE) && vmo_rights.contains(Rights::EXECUTE),
|
||||
);
|
||||
mapping_flags.set(MMUFlags::READ, options.contains(VmOptions::PERM_READ));
|
||||
mapping_flags.set(MMUFlags::WRITE, options.contains(VmOptions::PERM_WRITE));
|
||||
mapping_flags.set(MMUFlags::EXECUTE, options.contains(VmOptions::PERM_EXECUTE));
|
||||
info!(
|
||||
"mmuflags: {:?}, is_specific {:?}",
|
||||
mapping_flags, is_specific
|
||||
|
@ -153,6 +151,7 @@ impl Syscall<'_> {
|
|||
vmo,
|
||||
vmo_offset,
|
||||
len,
|
||||
permissions,
|
||||
mapping_flags,
|
||||
overwrite,
|
||||
map_range,
|
||||
|
@ -183,7 +182,7 @@ impl Syscall<'_> {
|
|||
len: u64,
|
||||
) -> ZxResult {
|
||||
let options = VmOptions::from_bits(options).ok_or(ZxError::INVALID_ARGS)?;
|
||||
let rights = options.to_rights();
|
||||
let rights = options.to_required_rights();
|
||||
info!(
|
||||
"vmar.protect: handle={:#x}, options={:#x}, addr={:#x}, len={:#x}",
|
||||
handle_value, options, addr, len
|
||||
|
@ -255,6 +254,20 @@ impl VmOptions {
|
|||
rights
|
||||
}
|
||||
|
||||
fn to_required_rights(self) -> Rights {
|
||||
let mut rights = Rights::empty();
|
||||
if self.contains(VmOptions::PERM_READ) {
|
||||
rights.insert(Rights::READ);
|
||||
}
|
||||
if self.contains(VmOptions::PERM_WRITE) {
|
||||
rights.insert(Rights::WRITE);
|
||||
}
|
||||
if self.contains(VmOptions::PERM_EXECUTE) {
|
||||
rights.insert(Rights::EXECUTE);
|
||||
}
|
||||
rights
|
||||
}
|
||||
|
||||
fn to_flags(self) -> VmarFlags {
|
||||
let mut flags = VmarFlags::empty();
|
||||
if self.contains(VmOptions::COMPACT) {
|
||||
|
|
Loading…
Reference in New Issue