Coverage for /Syzygy/agent/asan/scoped_page_protections_unittest.cc

CoverageLines executed / instrumented / missingexe / inst / missLanguageGroup
100.0%72720.C++test

Line-by-line coverage:

   1    :  // Copyright 2015 Google Inc. All Rights Reserved.
   2    :  //
   3    :  // Licensed under the Apache License, Version 2.0 (the "License");
   4    :  // you may not use this file except in compliance with the License.
   5    :  // You may obtain a copy of the License at
   6    :  //
   7    :  //     http://www.apache.org/licenses/LICENSE-2.0
   8    :  //
   9    :  // Unless required by applicable law or agreed to in writing, software
  10    :  // distributed under the License is distributed on an "AS IS" BASIS,
  11    :  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12    :  // See the License for the specific language governing permissions and
  13    :  // limitations under the License.
  14    :  //
  15    :  // Declares a helper class for use in performing hot-patching operations.
  16    :  // The class takes care of modifying page protections as the patcher works.
  17    :  
  18    :  #include "syzygy/agent/asan/scoped_page_protections.h"
  19    :  
  20    :  #include <cstdint>
  21    :  #include "base/logging.h"
  22    :  #include "gtest/gtest.h"
  23    :  #include "syzygy/agent/asan/constants.h"
  24    :  
  25    :  namespace agent {
  26    :  namespace asan {
  27    :  
  28    :  namespace {
  29    :  
  30    :  class ScopedPageProtectionsTest : public testing::Test {
  31    :   public:
  32    :    static const size_t kPageCount = 3;
  33    :  
  34  E :    ScopedPageProtectionsTest() : page_start_(nullptr), page_end_(nullptr) {}
  35    :  
  36  E :    void SetUp() override {
  37    :      page_start_ = reinterpret_cast<uint8_t*>(::VirtualAlloc(
  38  E :          nullptr, GetPageSize() * kPageCount, MEM_COMMIT, PAGE_READONLY));
  39  E :      ASSERT_TRUE(page_start_);
  40  E :      page_end_ = page_start_ + kPageCount * GetPageSize();
  41  E :    }
  42    :  
  43  E :    void TearDown() override {
  44  E :      ASSERT_TRUE(::VirtualFree(page_start_, 0, MEM_DECOMMIT));
  45  E :      page_start_ = nullptr;
  46  E :      page_end_ = nullptr;
  47  E :    }
  48    :  
  49    :    // Returns the base address of the page with a given index.
  50  E :    uint8_t* BaseOfPage(size_t index) {
  51  E :      CHECK_LE(index, kPageCount);
  52  E :      return page_start_ + index * GetPageSize();
  53  E :    }
  54    :  
  55    :    // Sets the given protection on the given page.
  56  E :    void SetProtection(size_t index, DWORD protection) {
  57  E :      CHECK_LT(index, kPageCount);
  58  E :      DWORD old_protection_unused = 0;
  59    :      ::VirtualProtect(BaseOfPage(index), GetPageSize(), protection,
  60  E :                       &old_protection_unused);
  61  E :    }
  62    :  
  63    :    // Returns the protection associated with the given page.
  64  E :    DWORD GetProtection(size_t index) {
  65  E :      CHECK_LT(index, kPageCount);
  66  E :      MEMORY_BASIC_INFORMATION mem_info = {};
  67  E :      CHECK_EQ(sizeof(mem_info),
  68    :               ::VirtualQuery(BaseOfPage(index), &mem_info, sizeof(mem_info)));
  69  E :      return mem_info.Protect;
  70  E :    }
  71    :  
  72    :    // An allocation with multiple pages. This is initially allocated read-only.
  73    :    uint8_t* page_start_;
  74    :    uint8_t* page_end_;
  75    :  };
  76    :  
  77    :  }  // namespace
  78    :  
  79  E :  TEST_F(ScopedPageProtectionsTest, ReadOnlyBecomesReadWrite) {
  80  E :    ScopedPageProtections spp;
  81    :  
  82    :    // The fixture should guarantee this.
  83  E :    ASSERT_EQ(PAGE_READONLY, GetProtection(0));
  84    :  
  85  E :    EXPECT_TRUE(spp.EnsureContainingPagesWritable(BaseOfPage(0), 1));
  86  E :    EXPECT_EQ(PAGE_READWRITE, GetProtection(0));
  87  E :    spp.RestorePageProtections();
  88  E :    EXPECT_EQ(PAGE_READONLY, GetProtection(0));
  89  E :  }
  90    :  
  91  E :  TEST_F(ScopedPageProtectionsTest, ExecReadOnlyBecomesExecReadWrite) {
  92  E :    ScopedPageProtections spp;
  93    :  
  94    :    // The fixture should guarantee these assertions.
  95  E :    ASSERT_EQ(PAGE_READONLY, GetProtection(0));
  96  E :    SetProtection(0, PAGE_EXECUTE_READ);
  97  E :    ASSERT_EQ(PAGE_EXECUTE_READ, GetProtection(0));
  98    :  
  99  E :    EXPECT_TRUE(spp.EnsureContainingPagesWritable(BaseOfPage(0), 1));
 100  E :    EXPECT_EQ(PAGE_EXECUTE_READWRITE, GetProtection(0));
 101  E :    spp.RestorePageProtections();
 102  E :    EXPECT_EQ(PAGE_EXECUTE_READ, GetProtection(0));
 103  E :  }
 104    :  
 105  E :  TEST_F(ScopedPageProtectionsTest, SpanMultiplePages) {
 106  E :    ScopedPageProtections spp;
 107    :  
 108    :    // The fixture should guarantee these assertions.
 109  E :    ASSERT_EQ(PAGE_READONLY, GetProtection(0));
 110  E :    ASSERT_EQ(PAGE_READONLY, GetProtection(1));
 111  E :    ASSERT_EQ(PAGE_READONLY, GetProtection(2));
 112  E :    SetProtection(1, PAGE_EXECUTE_READ);
 113  E :    ASSERT_EQ(PAGE_READONLY, GetProtection(0));
 114  E :    ASSERT_EQ(PAGE_EXECUTE_READ, GetProtection(1));
 115  E :    ASSERT_EQ(PAGE_READONLY, GetProtection(2));
 116    :  
 117  E :    uint8_t* begin = BaseOfPage(0) + 13;
 118  E :    uint8_t* end = BaseOfPage(3) - 100;
 119  E :    EXPECT_TRUE(spp.EnsureContainingPagesWritable(begin, end - begin));
 120  E :    EXPECT_EQ(PAGE_READWRITE, GetProtection(0));
 121  E :    EXPECT_EQ(PAGE_EXECUTE_READWRITE, GetProtection(1));
 122  E :    EXPECT_EQ(PAGE_READWRITE, GetProtection(2));
 123    :  
 124  E :    spp.RestorePageProtections();
 125  E :    EXPECT_EQ(PAGE_READONLY, GetProtection(0));
 126  E :    EXPECT_EQ(PAGE_EXECUTE_READ, GetProtection(1));
 127  E :    EXPECT_EQ(PAGE_READONLY, GetProtection(2));
 128  E :  }
 129    :  
 130  E :  TEST_F(ScopedPageProtectionsTest, RestoresProtectionsInDestructor) {
 131    :    // The fixture should guarantee this.
 132  E :    ASSERT_EQ(PAGE_READONLY, GetProtection(0));
 133    :  
 134    :    {
 135  E :      ScopedPageProtections spp;
 136  E :      EXPECT_TRUE(spp.EnsureContainingPagesWritable(BaseOfPage(0), 1));
 137  E :      EXPECT_EQ(PAGE_READWRITE, GetProtection(0));
 138  E :    }
 139    :  
 140  E :    EXPECT_EQ(PAGE_READONLY, GetProtection(0));
 141  E :  }
 142    :  
 143    :  }  // namespace asan
 144    :  }  // namespace agent

Coverage information generated Thu Jan 14 17:40:38 2016.