1 | //===-- map_test.cpp --------------------------------------------*- C++ -*-===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | |
9 | #include "tests/scudo_unit_test.h" |
10 | |
11 | #include "common.h" |
12 | #include "mem_map.h" |
13 | |
14 | #include <string.h> |
15 | #include <unistd.h> |
16 | |
17 | static const char *MappingName = "scudo:test" ; |
18 | |
19 | TEST(ScudoMapTest, PageSize) { |
20 | EXPECT_EQ(scudo::getPageSizeCached(), |
21 | static_cast<scudo::uptr>(sysconf(_SC_PAGESIZE))); |
22 | } |
23 | |
24 | TEST(ScudoMapDeathTest, MapNoAccessUnmap) { |
25 | const scudo::uptr Size = 4 * scudo::getPageSizeCached(); |
26 | scudo::ReservedMemoryT ReservedMemory; |
27 | |
28 | ASSERT_TRUE(ReservedMemory.create(/*Addr=*/0U, Size, Name: MappingName)); |
29 | EXPECT_NE(ReservedMemory.getBase(), 0U); |
30 | EXPECT_DEATH( |
31 | memset(reinterpret_cast<void *>(ReservedMemory.getBase()), 0xaa, Size), |
32 | "" ); |
33 | |
34 | ReservedMemory.release(); |
35 | } |
36 | |
37 | TEST(ScudoMapDeathTest, MapUnmap) { |
38 | const scudo::uptr Size = 4 * scudo::getPageSizeCached(); |
39 | EXPECT_DEATH( |
40 | { |
41 | // Repeat few time to avoid missing crash if it's mmaped by unrelated |
42 | // code. |
43 | for (int i = 0; i < 10; ++i) { |
44 | scudo::MemMapT MemMap; |
45 | MemMap.map(/*Addr=*/0U, Size, MappingName); |
46 | scudo::uptr P = MemMap.getBase(); |
47 | if (P == 0U) |
48 | continue; |
49 | MemMap.unmap(MemMap.getBase(), Size); |
50 | memset(reinterpret_cast<void *>(P), 0xbb, Size); |
51 | } |
52 | }, |
53 | "" ); |
54 | } |
55 | |
56 | TEST(ScudoMapDeathTest, MapWithGuardUnmap) { |
57 | const scudo::uptr PageSize = scudo::getPageSizeCached(); |
58 | const scudo::uptr Size = 4 * PageSize; |
59 | scudo::ReservedMemoryT ReservedMemory; |
60 | ASSERT_TRUE( |
61 | ReservedMemory.create(/*Addr=*/0U, Size: Size + 2 * PageSize, Name: MappingName)); |
62 | ASSERT_NE(ReservedMemory.getBase(), 0U); |
63 | |
64 | scudo::MemMapT MemMap = |
65 | ReservedMemory.dispatch(Addr: ReservedMemory.getBase(), Size: Size + 2 * PageSize); |
66 | ASSERT_TRUE(MemMap.isAllocated()); |
67 | scudo::uptr Q = MemMap.getBase() + PageSize; |
68 | ASSERT_TRUE(MemMap.remap(Addr: Q, Size, Name: MappingName)); |
69 | memset(s: reinterpret_cast<void *>(Q), c: 0xaa, n: Size); |
70 | EXPECT_DEATH(memset(reinterpret_cast<void *>(Q), 0xaa, Size + 1), "" ); |
71 | MemMap.unmap(Addr: MemMap.getBase(), Size: MemMap.getCapacity()); |
72 | } |
73 | |
74 | TEST(ScudoMapTest, MapGrowUnmap) { |
75 | const scudo::uptr PageSize = scudo::getPageSizeCached(); |
76 | const scudo::uptr Size = 4 * PageSize; |
77 | scudo::ReservedMemoryT ReservedMemory; |
78 | ReservedMemory.create(/*Addr=*/0U, Size, Name: MappingName); |
79 | ASSERT_TRUE(ReservedMemory.isCreated()); |
80 | |
81 | scudo::MemMapT MemMap = |
82 | ReservedMemory.dispatch(Addr: ReservedMemory.getBase(), Size); |
83 | ASSERT_TRUE(MemMap.isAllocated()); |
84 | scudo::uptr Q = MemMap.getBase() + PageSize; |
85 | ASSERT_TRUE(MemMap.remap(Addr: Q, Size: PageSize, Name: MappingName)); |
86 | memset(s: reinterpret_cast<void *>(Q), c: 0xaa, n: PageSize); |
87 | Q += PageSize; |
88 | ASSERT_TRUE(MemMap.remap(Addr: Q, Size: PageSize, Name: MappingName)); |
89 | memset(s: reinterpret_cast<void *>(Q), c: 0xbb, n: PageSize); |
90 | MemMap.unmap(Addr: MemMap.getBase(), Size: MemMap.getCapacity()); |
91 | } |
92 | |