138 lines · cpp
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-exception6//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#if SCUDO_LINUX18#include <sys/mman.h>19#endif20 21static const char *MappingName = "scudo:test";22 23TEST(ScudoMapTest, PageSize) {24 EXPECT_EQ(scudo::getPageSizeCached(),25 static_cast<scudo::uptr>(sysconf(_SC_PAGESIZE)));26}27 28TEST(ScudoMapDeathTest, MapNoAccessUnmap) {29 const scudo::uptr Size = 4 * scudo::getPageSizeCached();30 scudo::ReservedMemoryT ReservedMemory;31 32 ASSERT_TRUE(ReservedMemory.create(/*Addr=*/0U, Size, MappingName));33 EXPECT_NE(ReservedMemory.getBase(), 0U);34 EXPECT_DEATH(35 memset(reinterpret_cast<void *>(ReservedMemory.getBase()), 0xaa, Size),36 "");37 38 ReservedMemory.release();39}40 41TEST(ScudoMapDeathTest, MapUnmap) {42 const scudo::uptr Size = 4 * scudo::getPageSizeCached();43 EXPECT_DEATH(44 {45 // Repeat few time to avoid missing crash if it's mmaped by unrelated46 // code.47 for (int i = 0; i < 10; ++i) {48 scudo::MemMapT MemMap;49 MemMap.map(/*Addr=*/0U, Size, MappingName);50 scudo::uptr P = MemMap.getBase();51 if (P == 0U)52 continue;53 MemMap.unmap();54 memset(reinterpret_cast<void *>(P), 0xbb, Size);55 }56 },57 "");58}59 60TEST(ScudoMapDeathTest, MapWithGuardUnmap) {61 const scudo::uptr PageSize = scudo::getPageSizeCached();62 const scudo::uptr Size = 4 * PageSize;63 scudo::ReservedMemoryT ReservedMemory;64 ASSERT_TRUE(65 ReservedMemory.create(/*Addr=*/0U, Size + 2 * PageSize, MappingName));66 ASSERT_NE(ReservedMemory.getBase(), 0U);67 68 scudo::MemMapT MemMap =69 ReservedMemory.dispatch(ReservedMemory.getBase(), Size + 2 * PageSize);70 ASSERT_TRUE(MemMap.isAllocated());71 scudo::uptr Q = MemMap.getBase() + PageSize;72 ASSERT_TRUE(MemMap.remap(Q, Size, MappingName));73 memset(reinterpret_cast<void *>(Q), 0xaa, Size);74 EXPECT_DEATH(memset(reinterpret_cast<void *>(Q), 0xaa, Size + 1), "");75 MemMap.unmap();76}77 78TEST(ScudoMapTest, MapGrowUnmap) {79 const scudo::uptr PageSize = scudo::getPageSizeCached();80 const scudo::uptr Size = 4 * PageSize;81 scudo::ReservedMemoryT ReservedMemory;82 ReservedMemory.create(/*Addr=*/0U, Size, MappingName);83 ASSERT_TRUE(ReservedMemory.isCreated());84 85 scudo::MemMapT MemMap =86 ReservedMemory.dispatch(ReservedMemory.getBase(), Size);87 ASSERT_TRUE(MemMap.isAllocated());88 scudo::uptr Q = MemMap.getBase() + PageSize;89 ASSERT_TRUE(MemMap.remap(Q, PageSize, MappingName));90 memset(reinterpret_cast<void *>(Q), 0xaa, PageSize);91 Q += PageSize;92 ASSERT_TRUE(MemMap.remap(Q, PageSize, MappingName));93 memset(reinterpret_cast<void *>(Q), 0xbb, PageSize);94 MemMap.unmap();95}96 97// Verify that zeroing works properly.98TEST(ScudoMapTest, Zeroing) {99 scudo::ReservedMemoryT ReservedMemory;100 const scudo::uptr PageSize = scudo::getPageSizeCached();101 const scudo::uptr Size = 3 * PageSize;102 ReservedMemory.create(/*Addr=*/0U, Size, MappingName);103 ASSERT_TRUE(ReservedMemory.isCreated());104 105 scudo::MemMapT MemMap = ReservedMemory.dispatch(ReservedMemory.getBase(),106 ReservedMemory.getCapacity());107 EXPECT_TRUE(108 MemMap.remap(MemMap.getBase(), MemMap.getCapacity(), MappingName));109 unsigned char *Data = reinterpret_cast<unsigned char *>(MemMap.getBase());110 memset(Data, 1U, MemMap.getCapacity());111 // Spot check some values.112 EXPECT_EQ(1U, Data[0]);113 EXPECT_EQ(1U, Data[PageSize]);114 EXPECT_EQ(1U, Data[PageSize * 2]);115 MemMap.releaseAndZeroPagesToOS(MemMap.getBase(), MemMap.getCapacity());116 EXPECT_EQ(0U, Data[0]);117 EXPECT_EQ(0U, Data[PageSize]);118 EXPECT_EQ(0U, Data[PageSize * 2]);119 120#if SCUDO_LINUX121 // Now verify that if madvise fails, the data is still zeroed.122 memset(Data, 1U, MemMap.getCapacity());123 if (mlock(Data, MemMap.getCapacity()) != -1) {124 EXPECT_EQ(1U, Data[0]);125 EXPECT_EQ(1U, Data[PageSize]);126 EXPECT_EQ(1U, Data[PageSize * 2]);127 MemMap.releaseAndZeroPagesToOS(MemMap.getBase(), MemMap.getCapacity());128 EXPECT_EQ(0U, Data[0]);129 EXPECT_EQ(0U, Data[PageSize]);130 EXPECT_EQ(0U, Data[PageSize * 2]);131 132 EXPECT_NE(-1, munlock(Data, MemMap.getCapacity()));133 }134#endif135 136 MemMap.unmap();137}138