Skip to content

Commit 486762b

Browse files
committed
Partially protect a mapping
1 parent 027c76c commit 486762b

File tree

2 files changed

+20
-9
lines changed

2 files changed

+20
-9
lines changed

scripts/zircon/test-check-passed.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -375,6 +375,8 @@ Vmar.ObjectInfoTest
375375
Vmar.UnmapSplitTest
376376
Vmar.UnmapMultipleTest
377377
Vmar.UnmapBaseNotMappedTest
378+
Vmar.ProtectSplitTest
379+
Vmar.ProtectMultipleTest
378380
Vmar.PartialUnmapAndRead
379381
Vmar.PartialUnmapAndWrite
380382
Vmar.PartialUnmapWithVmarOffset

zircon-object/src/vm/vmar.rs

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -295,13 +295,20 @@ impl VmAddressRegion {
295295
let mut guard = self.inner.lock();
296296
let inner = guard.as_mut().ok_or(ZxError::BAD_STATE)?;
297297
let end_addr = addr + len;
298-
// TODO: Partially protect a mapping
298+
// check if there are overlapping subregion
299+
if inner
300+
.children
301+
.iter()
302+
.any(|child| child.end_addr() >= addr && child.addr() <= end_addr)
303+
{
304+
return Err(ZxError::INVALID_ARGS);
305+
}
299306
let length: usize = inner
300307
.mappings
301308
.iter()
302309
.filter_map(|map| {
303-
if map.addr() >= addr && map.end_addr() <= end_addr {
304-
Some(map.size())
310+
if map.end_addr() >= addr && map.addr() <= end_addr {
311+
Some(end_addr.min(map.end_addr()) - addr.max(map.addr()))
305312
} else {
306313
None
307314
}
@@ -310,21 +317,23 @@ impl VmAddressRegion {
310317
if length != len {
311318
return Err(ZxError::NOT_FOUND);
312319
}
320+
// check if protect flags is valid
313321
if inner
314322
.mappings
315323
.iter()
316-
.filter(|map| map.addr() >= addr && map.end_addr() <= end_addr) // get mappings in range: [addr, end_addr]
324+
.filter(|map| map.end_addr() >= addr && map.addr() <= end_addr) // get mappings in range: [addr, end_addr]
317325
.any(|map| !map.is_valid_mapping_flags(flags))
318-
// check if protect flags is valid
319326
{
320327
return Err(ZxError::ACCESS_DENIED);
321328
}
322329
inner
323330
.mappings
324331
.iter()
325-
.filter(|map| map.addr() >= addr && map.end_addr() <= end_addr)
332+
.filter(|map| map.end_addr() >= addr && map.addr() <= end_addr)
326333
.for_each(|map| {
327-
map.protect(flags);
334+
let start_index = pages(addr.max(map.addr()) - map.addr());
335+
let end_index = pages(end_addr.min(map.end_addr()) - map.addr());
336+
map.protect(flags, start_index, end_index);
328337
});
329338
Ok(())
330339
}
@@ -834,10 +843,10 @@ impl VmMapping {
834843
self.permissions.contains(flags & MMUFlags::RXW)
835844
}
836845

837-
fn protect(&self, flags: MMUFlags) {
846+
fn protect(&self, flags: MMUFlags, start_index: usize, end_index: usize) {
838847
let mut inner = self.inner.lock();
839848
let mut pg_table = self.page_table.lock();
840-
for i in 0..pages(inner.size) {
849+
for i in start_index..end_index {
841850
let mut new_flags = inner.flags[i];
842851
new_flags.remove(MMUFlags::RXW);
843852
new_flags.insert(flags & MMUFlags::RXW);

0 commit comments

Comments
 (0)