tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

TestSharedMappingCommit.cpp (4310B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
      3 /* This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this
      5 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
      6 
      7 #include <cstdint>
      8 #include <cstdio>
      9 #include <windows.h>
     10 
     11 // Tests that when there are multiple views to a unique mapping, committing
     12 // memory pages for one of the views actually commits them for all views. We
     13 // rely on this behavior in `mozglue/interceptor/MMPolicies.h` and in
     14 // `security/sandbox/chromium/sandbox/win/src/interception.cc`.
     15 bool TestSharedMappingCommit() {
     16  constexpr size_t kMappingSize = 64 * 1024;
     17  constexpr size_t kCommitOffset = 32 * 1024;
     18  constexpr size_t kCommitSize = 4 * 1024;
     19 
     20  HANDLE mapping = ::CreateFileMappingW(INVALID_HANDLE_VALUE, nullptr,
     21                                        PAGE_EXECUTE_READWRITE | SEC_RESERVE, 0,
     22                                        kMappingSize, nullptr);
     23  if (!mapping) {
     24    printf(
     25        "TEST-FAIL | SharedMappingCommit | Failed to create a pagefile-backed "
     26        "mapping\n");
     27    return false;
     28  }
     29 
     30  void* rwView =
     31      ::MapViewOfFile(mapping, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);
     32  if (!rwView) {
     33    printf(
     34        "TEST-FAIL | SharedMappingCommit | Failed to get a read/write view\n");
     35    return false;
     36  }
     37 
     38  void* rxView =
     39      ::MapViewOfFile(mapping, FILE_MAP_READ | FILE_MAP_EXECUTE, 0, 0, 0);
     40  if (!rxView) {
     41    printf(
     42        "TEST-FAIL | SharedMappingCommit | Failed to get a read/execute "
     43        "view\n");
     44    return false;
     45  }
     46 
     47  auto* rwCommitAddress =
     48      static_cast<void*>(static_cast<uint8_t*>(rwView) + kCommitOffset);
     49  auto* rxCommitAddress =
     50      static_cast<void*>(static_cast<uint8_t*>(rxView) + kCommitOffset);
     51 
     52  {
     53    MEMORY_BASIC_INFORMATION info{};
     54    if (::VirtualQuery(rxCommitAddress, &info, sizeof(info)) != sizeof(info)) {
     55      printf(
     56          "TEST-FAIL | SharedMappingCommit | Failed to query basic information "
     57          "about the read/execute memory pages\n");
     58      return false;
     59    }
     60    if (info.State != MEM_RESERVE) {
     61      printf(
     62          "TEST-FAIL | SharedMappingCommit | Unexpected initial state for the "
     63          "read/execute memory pages: %lu\n",
     64          info.State);
     65      return false;
     66    }
     67  }
     68 
     69  rwCommitAddress = ::VirtualAlloc(static_cast<void*>(rwCommitAddress),
     70                                   kCommitSize, MEM_COMMIT, PAGE_READWRITE);
     71  if (!rwCommitAddress) {
     72    printf(
     73        "TEST-FAIL | SharedMappingCommit | Failed to commit read/write "
     74        "memory pages\n");
     75    return false;
     76  }
     77 
     78  {
     79    MEMORY_BASIC_INFORMATION info{};
     80    if (::VirtualQuery(rxCommitAddress, &info, sizeof(info)) != sizeof(info)) {
     81      printf(
     82          "TEST-FAIL | SharedMappingCommit | Failed to query basic information "
     83          "about the read/execute memory pages\n");
     84      return false;
     85    }
     86    if (info.State != MEM_COMMIT) {
     87      printf(
     88          "TEST-FAIL | SharedMappingCommit | Read/write commit hasn't changed "
     89          "the state of the read/execute memory pages: %lu\n",
     90          info.State);
     91      return false;
     92    }
     93    if (info.Protect != PAGE_EXECUTE_READ) {
     94      printf(
     95          "TEST-FAIL | SharedMappingCommit | Unexpected protection for the "
     96          "read/execute memory pages: %lu\n",
     97          info.Protect);
     98      return false;
     99    }
    100  }
    101 
    102  constexpr uint32_t kMagic = 0xdeadbeef;
    103 
    104  uint32_t* rwMagicAddr = static_cast<uint32_t*>(rwCommitAddress);
    105  *rwMagicAddr = kMagic;
    106 
    107  const uint32_t* rxMagicAddr = static_cast<const uint32_t*>(rxCommitAddress);
    108  if (*rxMagicAddr != kMagic) {
    109    printf(
    110        "TEST-FAIL | SharedMappingCommit | Read a different value through the "
    111        "read/execute view than was written through the read/write view\n");
    112    return false;
    113  }
    114 
    115  printf(
    116      "TEST-PASS | SharedMappingCommit | Committing memory pages through the "
    117      "read/write view also commited the corresponding pages in the "
    118      "read/execute view\n");
    119  return true;
    120 }
    121 
    122 int wmain(int argc, wchar_t* argv[]) {
    123  if (!TestSharedMappingCommit()) {
    124    return 1;
    125  }
    126 
    127  printf("TEST-PASS | SharedMappingCommit | All tests ran successfully\n");
    128  return 0;
    129 }