1 // Copyright 2018 The Fuchsia Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "vmo-probe.h"
6 
7 #include <lib/zx/vmo.h>
8 #include <unittest/unittest.h>
9 #include <zircon/rights.h>
10 
11 namespace vmo_probe {
12 
probe_access(void * addr,AccessType access_type,bool expect_can_access)13 bool probe_access(void* addr, AccessType access_type, bool expect_can_access) {
14     BEGIN_HELPER;
15     unittest_printf("probe_access for addr: %lu\n", (size_t)addr);
16 
17     switch (access_type) {
18     case AccessType::Rd: {
19         auto rd_fn = [](void* addr) { g_access_check_var = reinterpret_cast<uint32_t*>(addr)[0]; };
20         if (expect_can_access) {
21             ASSERT_NO_DEATH(rd_fn, addr, "Read probe failed when it should have succeeded.");
22         } else {
23             ASSERT_DEATH(rd_fn, addr, "Read probe succeeded when it should have failed.");
24         }
25     } break;
26 
27     case AccessType::Wr: {
28         auto wr_fn = [](void* addr) { reinterpret_cast<uint32_t*>(addr)[0] = g_access_check_var; };
29         if (expect_can_access) {
30             ASSERT_NO_DEATH(wr_fn, addr, "Write probe failed when it should have succeeded.");
31         } else {
32             ASSERT_DEATH(wr_fn, addr, "Write probe succeeded when it should have failed.");
33         }
34     } break;
35     }
36 
37     END_HELPER;
38 }
39 
probe_verify_region(void * start,size_t size,uint32_t access)40 bool probe_verify_region(void* start, size_t size, uint32_t access) {
41     BEGIN_HELPER;
42 
43     auto uint_base = reinterpret_cast<uintptr_t>(start);
44     void* probe_points[] = {
45         reinterpret_cast<void*>(uint_base),
46         reinterpret_cast<void*>(uint_base + (size / 2)),
47         reinterpret_cast<void*>(uint_base + size - sizeof(uint32_t)),
48     };
49 
50     unittest_printf("prove_verify_region for addr: %lu, size: %lu\n", (size_t)start, size);
51     for (void* probe_point : probe_points) {
52         ASSERT_TRUE(probe_access(probe_point, AccessType::Rd, access & ZX_VM_PERM_READ));
53         ASSERT_TRUE(probe_access(probe_point, AccessType::Wr, access & ZX_VM_PERM_WRITE));
54     }
55 
56     END_HELPER;
57 }
58 
59 } // namespace vmo_probe
60