Skip to content

Commit

Permalink
[vmar][map] Require that vmo_offset + size not overflow
Browse files Browse the repository at this point in the history
Change-Id: I134b81e09a80be99ce3c92667273e11b0101fbb8
Todd Eisenberger committed Dec 22, 2016
1 parent a6253b2 commit ac6bdcb
Showing 3 changed files with 20 additions and 4 deletions.
3 changes: 2 additions & 1 deletion docs/syscalls/vmar_map.md
Original file line number Diff line number Diff line change
@@ -59,7 +59,8 @@ error value is returned.
non-zero when neither **MX_VM_FLAG_SPECIFIC** nor
**MX_VM_FLAG_SPECIFIC_OVERWRITE** are given, *vmar_offset* and *len*
describe an unsatisfiable allocation due to exceeding the region bounds,
*vmar_offset* or *vmo_offset* are not page-aligned, or *len* is 0.
*vmar_offset* or *vmo_offset* are not page-aligned,
*vmo_offset* + ROUNDUP(*len*, PAGE_SIZE) overflows, or *len* is 0.

**ERR_ACCESS_DENIED** insufficient privileges to make the requested mapping

8 changes: 5 additions & 3 deletions kernel/kernel/vm/vm_address_region.cpp
Original file line number Diff line number Diff line change
@@ -194,7 +194,11 @@ status_t VmAddressRegion::CreateVmMapping(size_t mapping_offset, size_t size, ui
return ERR_ACCESS_DENIED;
}

if (!IS_PAGE_ALIGNED(vmo_offset)) {
size = ROUNDUP(size, PAGE_SIZE);

// Make sure that vmo_offset is aligned and that a mapping of this size
// wouldn't overflow the vmo offset.
if (!IS_PAGE_ALIGNED(vmo_offset) || vmo_offset + size < vmo_offset) {
return ERR_INVALID_ARGS;
}

@@ -210,8 +214,6 @@ status_t VmAddressRegion::CreateVmMapping(size_t mapping_offset, size_t size, ui
vmar_flags |= VMAR_FLAG_CAN_MAP_EXECUTE;
}

size = ROUNDUP(size, PAGE_SIZE);

mxtl::RefPtr<VmAddressRegionOrMapping> res;
status_t status =
CreateSubVmarInternal(mapping_offset, size, align_pow2, vmar_flags, mxtl::move(vmo),
13 changes: 13 additions & 0 deletions system/utest/core/vmar/vmar.cpp
Original file line number Diff line number Diff line change
@@ -561,6 +561,19 @@ bool invalid_args_test() {
ERR_INVALID_ARGS, "");
EXPECT_EQ(mx_vmar_unmap(vmar, map_addr, 4 * PAGE_SIZE), NO_ERROR, "");

// Overflowing vmo_offset
EXPECT_EQ(mx_vmar_map(vmar, 0, vmo, UINT64_MAX + 1 - PAGE_SIZE,
PAGE_SIZE,
MX_VM_FLAG_PERM_READ | MX_VM_FLAG_PERM_WRITE,
&map_addr),
ERR_INVALID_ARGS, "");
EXPECT_EQ(mx_vmar_map(vmar, 0, vmo, UINT64_MAX + 1 - 2 * PAGE_SIZE,
PAGE_SIZE,
MX_VM_FLAG_PERM_READ | MX_VM_FLAG_PERM_WRITE,
&map_addr),
NO_ERROR, "");
EXPECT_EQ(mx_vmar_unmap(vmar, map_addr, PAGE_SIZE), NO_ERROR, "");

// size=0
EXPECT_EQ(mx_vmar_allocate(vmar, 0, 0,
MX_VM_FLAG_CAN_MAP_READ | MX_VM_FLAG_CAN_MAP_WRITE,

0 comments on commit ac6bdcb

Please sign in to comment.