// Copyright 2014 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "syzygy/agent/asan/block.h"

#include "windows.h"

#include "base/debug/alias.h"
#include "base/memory/scoped_ptr.h"
#include "gtest/gtest.h"

namespace agent {
namespace asan {

namespace {

BlockLayout BuildBlockLayout(size_t block_alignment,
                             size_t block_size,
                             size_t header_size,
                             size_t header_padding_size,
                             size_t body_size,
                             size_t trailer_padding_size,
                             size_t trailer_size) {
  BlockLayout layout = { block_alignment, block_size, header_size,
      header_padding_size, body_size, trailer_padding_size, trailer_size };
  return layout;
}

// Checks that the given block is valid, and initialized as expected.
void IsValidBlockImpl(const BlockInfo& block, bool just_initialized) {
  EXPECT_EQ(0u, block.block_size % kShadowRatio);

  // Validate the layout of the block.
  EXPECT_TRUE(block.block != NULL);
  EXPECT_EQ(0u, block.block_size % kShadowRatio);
  EXPECT_EQ(block.block, reinterpret_cast<void*>(block.header));
  EXPECT_EQ(0u, block.header_padding_size % kShadowRatio);
  EXPECT_EQ(reinterpret_cast<uint8*>(block.header + 1),
            block.header_padding);
  EXPECT_EQ(block.header_padding + block.header_padding_size,
            block.body);
  EXPECT_EQ(reinterpret_cast<uint8*>(block.body + block.body_size),
            block.trailer_padding);
  EXPECT_EQ(block.trailer_padding + block.trailer_padding_size,
            reinterpret_cast<uint8*>(block.trailer));
  EXPECT_EQ(block.block + block.block_size,
            reinterpret_cast<uint8*>(block.trailer + 1));

  // Validate the actual contents of the various parts of the block.

  // Check the header.
  EXPECT_EQ(kBlockHeaderMagic, block.header->magic);
  EXPECT_FALSE(block.header->is_nested);
  EXPECT_LT(0u, block.header->body_size);
  EXPECT_EQ(block.header->body_size, block.body_size);
  if (just_initialized) {
    EXPECT_EQ(0u, block.header->checksum);
    EXPECT_EQ(NULL, block.header->alloc_stack);
    EXPECT_EQ(NULL, block.header->free_stack);
    EXPECT_EQ(ALLOCATED_BLOCK, block.header->state);
  }

  // By default we assume the blocks to not be nested.
  EXPECT_FALSE(block.header->is_nested);
  EXPECT_EQ(static_cast<bool>(block.header->is_nested), block.is_nested);

  // Check the header padding.
  if (block.header->has_header_padding) {
    EXPECT_LE(kShadowRatio, block.header_padding_size);
    EXPECT_EQ(block.header_padding_size,
              *reinterpret_cast<const uint32*>(block.header_padding));
    EXPECT_EQ(block.header_padding_size,
              *reinterpret_cast<const uint32*>(block.header_padding +
                  block.header_padding_size - sizeof(uint32)));
    for (size_t i = sizeof(uint32);
         i < block.header_padding_size - sizeof(uint32);
         ++i) {
      EXPECT_EQ(kBlockHeaderPaddingByte, block.header_padding[i]);
    }
  }

  // Check the trailer padding.
  size_t start_of_trailer_iteration = 0;
  if (block.header->has_excess_trailer_padding) {
    start_of_trailer_iteration = 4;
    EXPECT_EQ(block.trailer_padding_size,
              *reinterpret_cast<const uint32*>(block.trailer_padding));
  }
  for (size_t i = start_of_trailer_iteration; i < block.trailer_padding_size;
       ++i) {
    EXPECT_EQ(kBlockTrailerPaddingByte, block.trailer_padding[i]);
  }

  // Check the trailer.
  EXPECT_NE(0u, block.trailer->alloc_tid);
  EXPECT_GE(::GetTickCount(), block.trailer->alloc_ticks);
  if (just_initialized) {
    EXPECT_EQ(0u, block.trailer->free_tid);
    EXPECT_EQ(0u, block.trailer->free_ticks);
  }
}

void IsValidInitializedBlock(const BlockInfo& block) {
  IsValidBlockImpl(block, true);
}

void IsValidBlock(const BlockInfo& block) {
  IsValidBlockImpl(block, false);
}

}  // namespace

bool operator==(const BlockLayout& bl1, const BlockLayout& bl2) {
  return ::memcmp(&bl1, &bl2, sizeof(BlockLayout)) == 0;
}

bool operator==(const BlockInfo& bi1, const BlockInfo& bi2) {
  return ::memcmp(&bi1, &bi2, sizeof(BlockInfo)) == 0;
}

TEST(BlockTest, BlockPlanLayout) {
  BlockLayout layout = {};

  // Zero sized allocations should work fine.
  BlockPlanLayout(8, 8, 0, 0, 0, &layout);
  EXPECT_EQ(BuildBlockLayout(8, 40, 16, 0, 0, 4, 20), layout);

  BlockPlanLayout(8, 8, 60, 32, 32, &layout);
  EXPECT_EQ(BuildBlockLayout(8, 128, 16, 16, 60, 16, 20), layout);

  BlockPlanLayout(8, 8, 60, 0, 0, &layout);
  EXPECT_EQ(BuildBlockLayout(8, 96, 16, 0, 60, 0, 20), layout);

  BlockPlanLayout(8, 8, 64, 0, 0, &layout);
  EXPECT_EQ(BuildBlockLayout(8, 104, 16, 0, 64, 4, 20), layout);

  BlockPlanLayout(8, 8, 61, 0, 0, &layout);
  EXPECT_EQ(BuildBlockLayout(8, 104, 16, 0, 61, 7, 20), layout);

  // Plan a layout that would use guard pages.
  BlockPlanLayout(4096, 8, 100, 4096, 4096, &layout);
  EXPECT_EQ(BuildBlockLayout(4096, 3 * 4096, 16, 8072, 100, 4080, 20), layout);
}

TEST(BlockTest, EndToEnd) {
  BlockLayout layout = {};
  BlockInfo block_info = {};

  BlockPlanLayout(8, 8, 4, 0, 0, &layout);
  void* block_data = ::malloc(layout.block_size);
  ASSERT_TRUE(block_data != NULL);
  BlockInitialize(layout, block_data, false, &block_info);
  EXPECT_NO_FATAL_FAILURE(IsValidInitializedBlock(block_info));
  ::free(block_data);
  block_data = NULL;

  BlockPlanLayout(8, 8, 61, 0, 0, &layout);
  block_data = ::malloc(layout.block_size);
  ASSERT_TRUE(block_data != NULL);
  BlockInitialize(layout, block_data, false, &block_info);
  EXPECT_NO_FATAL_FAILURE(IsValidInitializedBlock(block_info));
  ::free(block_data);
  block_data = NULL;

  BlockPlanLayout(8, 8, 60, 32, 32, &layout);
  block_data = ::malloc(layout.block_size);
  ASSERT_TRUE(block_data != NULL);
  BlockInitialize(layout, block_data, false, &block_info);
  EXPECT_NO_FATAL_FAILURE(IsValidInitializedBlock(block_info));
  ::free(block_data);
  block_data = NULL;

  // Do an allocation that uses entire pages.
  BlockPlanLayout(4096, 8, 100, 4096, 4096, &layout);
  block_data = ::VirtualAlloc(NULL, layout.block_size, MEM_COMMIT,
                              PAGE_READWRITE);
  ASSERT_TRUE(block_data != NULL);
  BlockInitialize(layout, block_data, false, &block_info);
  EXPECT_NO_FATAL_FAILURE(IsValidInitializedBlock(block_info));
  ASSERT_EQ(TRUE, ::VirtualFree(block_data, 0, MEM_RELEASE));
  block_data = NULL;
}

TEST(BlockTest, GetHeaderFromBody) {
  // Plan two layouts, one with header padding and another without.
  BlockLayout layout1 = {};
  BlockLayout layout2 = {};
  BlockPlanLayout(kShadowRatio, kShadowRatio, 10, 0, 0, &layout1);
  BlockPlanLayout(kShadowRatio, kShadowRatio, 10, 32, 0, &layout2);

  uint8* data = new uint8[layout2.block_size];

  // First try navigating a block without header padding.
  BlockInfo info = {};
  BlockInitialize(layout1, data, false, &info);
  // This should succeed as expected.
  EXPECT_EQ(info.header, BlockGetHeaderFromBody(info.body));
  // This fails because of invalid alignment.
  EXPECT_TRUE(BlockGetHeaderFromBody(info.body + 1) == NULL);
  // This fails because the pointer is not at the beginning of the
  // body.
  EXPECT_TRUE(BlockGetHeaderFromBody(info.body + 8) == NULL);
  // This fails because of invalid header magic.
  ++info.header->magic;
  EXPECT_TRUE(BlockGetHeaderFromBody(info.body) == NULL);
  // This fails because the header indicates there's padding.
  --info.header->magic;
  info.header->has_header_padding = 1;
  EXPECT_TRUE(BlockGetHeaderFromBody(info.body) == NULL);

  // Now navigate a block with header padding.
  BlockInitialize(layout2, data, false, &info);
  // This should succeed as expected.
  EXPECT_EQ(info.header, BlockGetHeaderFromBody(info.body));
  // This fails because of invalid alignment.
  EXPECT_TRUE(BlockGetHeaderFromBody(info.body + 1) == NULL);
  // This fails because the pointer is not at the beginning of the
  // body.
  EXPECT_TRUE(BlockGetHeaderFromBody(info.body + 8) == NULL);
  // This fails because of invalid header magic.
  ++info.header->magic;
  EXPECT_TRUE(BlockGetHeaderFromBody(info.body) == NULL);
  // This fails because the header indicates there's no padding.
  --info.header->magic;
  info.header->has_header_padding = 0;
  EXPECT_TRUE(BlockGetHeaderFromBody(info.body) == NULL);
  // This fails because the padding length is invalid.
  info.header->has_header_padding = 1;
  uint32* head = reinterpret_cast<uint32*>(info.header_padding);
  uint32* tail = head + (info.header_padding_size / sizeof(uint32)) - 1;
  ++(*tail);
  EXPECT_TRUE(BlockGetHeaderFromBody(info.body) == NULL);
  // This fails because the padding lengths don't agree.
  --(*tail);
  ++(*head);
  EXPECT_TRUE(BlockGetHeaderFromBody(info.body) == NULL);

  delete[] data;
}

TEST(BlockTest, GetHeaderFromBodyProtectedMemory) {
  BlockLayout layout = {};
  BlockPlanLayout(4096, 4096, 4096, 4096, 4096, &layout);
  void* alloc = ::VirtualAlloc(NULL, layout.block_size, MEM_COMMIT,
                               PAGE_READWRITE);
  ASSERT_TRUE(alloc != NULL);
  BlockInfo block_info = {};
  BlockInitialize(layout, alloc, false, &block_info);

  BlockProtectRedzones(block_info);
  EXPECT_TRUE(BlockGetHeaderFromBody(block_info.body) == NULL);

  ASSERT_EQ(TRUE, ::VirtualFree(alloc, 0, MEM_RELEASE));
}

TEST(BlockTest, BlockInfoFromMemory) {
  // Plan two layouts, one with header padding and another without.
  BlockLayout layout1 = {};
  BlockLayout layout2 = {};
  BlockPlanLayout(kShadowRatio, kShadowRatio, 10, 0, 0, &layout1);
  BlockPlanLayout(kShadowRatio, kShadowRatio, 10, 32, 0, &layout2);

  scoped_ptr<uint8> data(new uint8[layout2.block_size]);

  // First recover a block without header padding.
  BlockInfo info = {};
  BlockInitialize(layout1, data.get(), false, &info);
  BlockInfo info_recovered = {};
  EXPECT_TRUE(BlockInfoFromMemory(info.block, &info_recovered));
  EXPECT_EQ(info, info_recovered);
  // Failed because its not aligned.
  EXPECT_FALSE(BlockInfoFromMemory(info.block + 1, &info_recovered));
  // Failed because the magic is invalid.
  ++info.header->magic;
  EXPECT_FALSE(BlockInfoFromMemory(info.block, &info_recovered));
  --info.header->magic;
  // This fails because the header indicates there's padding yet there is
  // none.
  info.header->has_header_padding = 1;
  EXPECT_FALSE(BlockInfoFromMemory(info.block, &info_recovered));

  // Now recover a block with header padding.
  BlockInitialize(layout2, data.get(), false, &info);
  EXPECT_TRUE(BlockInfoFromMemory(info.block, &info_recovered));
  EXPECT_EQ(info, info_recovered);
  // Failed because the magic is invalid.
  ++info.header->magic;
  EXPECT_FALSE(BlockInfoFromMemory(info.block, &info_recovered));
  --info.header->magic;
  // Failed because the header padding lengths don't match.
  uint32* head = reinterpret_cast<uint32*>(info.header_padding);
  uint32* tail = head + (info.header_padding_size / sizeof(uint32)) - 1;
  ++(*tail);
  EXPECT_FALSE(BlockInfoFromMemory(info.block, &info_recovered));
  --(*tail);

  // Finally ensure that we can recover information about blocks of various
  // sizes.
  for (size_t block_size = 0; block_size < kShadowRatio * 2; ++block_size) {
    BlockLayout layout = {};
    BlockPlanLayout(kShadowRatio, kShadowRatio, block_size, 0, 0, &layout);
    data.reset(new uint8[layout.block_size]);
    BlockInitialize(layout, data.get(), false, &info);
    EXPECT_TRUE(BlockInfoFromMemory(info.block, &info_recovered));
    EXPECT_EQ(info.body_size, info_recovered.body_size);
    EXPECT_EQ(info, info_recovered);
  }
}

TEST(BlockTest, BlockInfoFromMemoryProtectedMemory) {
  BlockLayout layout = {};
  BlockPlanLayout(4096, 4096, 4096, 4096, 4096, &layout);
  void* alloc = ::VirtualAlloc(NULL, layout.block_size, MEM_COMMIT,
                               PAGE_READWRITE);
  ASSERT_TRUE(alloc != NULL);
  BlockInfo block_info = {};
  BlockInitialize(layout, alloc, false, &block_info);

  BlockProtectRedzones(block_info);
  BlockInfo recovered_info = {};
  EXPECT_FALSE(BlockInfoFromMemory(block_info.block, &recovered_info));

  ASSERT_EQ(TRUE, ::VirtualFree(alloc, 0, MEM_RELEASE));
}

TEST(BlockTest, BlockInfoFromMemoryForNestedBlock) {
  BlockLayout layout = {};
  BlockPlanLayout(kShadowRatio, kShadowRatio, 10, 0, 0, &layout);

  scoped_ptr<uint8> data(new uint8[layout.block_size]);
  BlockInfo block_info = {};
  BlockInitialize(layout, data.get(), true, &block_info);

  BlockInfo recovered_info = {};
  EXPECT_TRUE(BlockInfoFromMemory(block_info.block, &recovered_info));

  EXPECT_TRUE(recovered_info.is_nested);
  EXPECT_TRUE(recovered_info.header->is_nested);
}

TEST(BlockTest, ChecksumWorksForAllStates) {
  BlockLayout layout = {};
  BlockPlanLayout(kShadowRatio, kShadowRatio, 10, 0, 0, &layout);
  uint8* data = new uint8[layout.block_size];
  BlockInfo info = {};
  BlockInitialize(layout, data, false, &info);
  while (true) {
    BlockCalculateChecksum(info);
    ++info.header->state;
    if (info.header->state == 0)
      break;
  }
  delete[] data;
}

namespace {

// Given two arrays of data, compares them byte-by-byte to find the first
// byte with altered data. Within that byte determines the mask of bits that
// have been altered. Returns the results via |offset| and |mask|.
void FindModifiedBits(size_t length,
                      const uint8* buffer1,
                      const uint8* buffer2,
                      size_t* offset,
                      uint8* mask) {
  ASSERT_TRUE(buffer1 != NULL);
  ASSERT_TRUE(buffer2 != NULL);
  ASSERT_TRUE(offset != NULL);
  ASSERT_TRUE(mask != NULL);

  for (size_t i = 0; i < length; ++i) {
    if (buffer1[i] != buffer2[i]) {
      *offset = i;
      *mask = buffer1[i] ^ buffer2[i];
      return;
    }
  }

  *offset = 0;
  *mask = 0;
}

bool ChecksumDetectsTamperingWithMask(const BlockInfo& block_info,
                                      void* address_to_modify,
                                      uint8 mask_to_modify) {
  uint8* byte_to_modify = reinterpret_cast<uint8*>(address_to_modify);

  // Remember the original contents.
  uint8 original_value = *byte_to_modify;
  uint8 original_bits = original_value & ~mask_to_modify;

  // Since the checksum can collide we check a handful of times to build up
  // some confidence. Since we sometimes expect this to return false the number
  // of iterations needs to be kept reasonably low to keep the unittest fast.
  bool detected = false;
  BlockSetChecksum(block_info);
  uint32 checksum = block_info.header->checksum;
  for (size_t i = 0; i < 4; ++i) {
    // Modify the value, altering only bits in |mask_to_modify|.
    while (true) {
      ++(*byte_to_modify);
      if (((*byte_to_modify) & ~mask_to_modify) == original_bits)
        break;
    }
    BlockSetChecksum(block_info);
    if (block_info.header->checksum != checksum) {
      // Success, the checksum detected the change!
      detected = true;
      break;
    }
  }

  // Restore the original value before returning.
  *byte_to_modify = original_value;
  return detected;
}

bool ChecksumDetectsTampering(const BlockInfo& block_info,
                              void* address_to_modify) {
  if (!ChecksumDetectsTamperingWithMask(block_info, address_to_modify, 0xFF))
    return false;
  return true;
}

void TestChecksumDetectsTampering(const BlockInfo& block_info) {
  uint32 checksum = BlockCalculateChecksum(block_info);
  block_info.header->checksum = checksum;
  EXPECT_TRUE(BlockChecksumIsValid(block_info));
  ++block_info.header->checksum;
  EXPECT_FALSE(BlockChecksumIsValid(block_info));
  BlockSetChecksum(block_info);
  EXPECT_EQ(checksum, block_info.header->checksum);

  // Get the offset of the byte and the mask of the bits containing the
  // block state. This is resilient to changes in the BlockHeader layout.
  static size_t state_offset = -1;
  static uint8 state_mask = 0;
  if (state_offset == -1) {
    BlockHeader header1 = {};
    BlockHeader header2 = {};
    header2.state = -1;
    FindModifiedBits(sizeof(BlockHeader),
                     reinterpret_cast<const uint8*>(&header1),
                     reinterpret_cast<const uint8*>(&header2),
                     &state_offset,
                     &state_mask);
  }

  // Header bytes should be tamper proof.
  EXPECT_TRUE(ChecksumDetectsTampering(block_info, block_info.header));
  EXPECT_TRUE(ChecksumDetectsTampering(block_info,
                                       &block_info.header->alloc_stack));
  EXPECT_TRUE(ChecksumDetectsTamperingWithMask(
      block_info,
      block_info.block + state_offset,
      state_mask));

  // Header padding should be tamper proof.
  if (block_info.header_padding_size > 0) {
    EXPECT_TRUE(ChecksumDetectsTampering(block_info,
        block_info.header_padding + block_info.header_padding_size / 2));
  }

  // Trailer padding should be tamper proof.
  if (block_info.trailer_padding_size > 0) {
    EXPECT_TRUE(ChecksumDetectsTampering(block_info,
        block_info.trailer_padding + block_info.trailer_padding_size / 2));
  }

  // Trailer bytes should be tamper proof.
  EXPECT_TRUE(ChecksumDetectsTampering(block_info, block_info.trailer));
  EXPECT_TRUE(ChecksumDetectsTampering(block_info,
                                       &block_info.trailer->alloc_ticks));

  // Expect the checksum to detect body tampering in quarantined and freed
  // states, but not in the allocated state.
  bool expected = (block_info.header->state != ALLOCATED_BLOCK);
  EXPECT_EQ(expected, ChecksumDetectsTampering(block_info, block_info.body));
  EXPECT_EQ(expected, ChecksumDetectsTampering(block_info,
      block_info.body + block_info.body_size / 2));
  EXPECT_EQ(expected, ChecksumDetectsTampering(block_info,
      block_info.body + block_info.body_size - 1));
}

}  // namespace

TEST(BlockTest, ChecksumDetectsTampering) {
  size_t kSizes[] = { 1, 4, 7, 16, 23, 32, 117, 1000, 4096 };

  // Doing a single allocation makes this test a bit faster.
  size_t kAllocSize = 4 * 4096;
  void* alloc = ::VirtualAlloc(NULL, kAllocSize, MEM_COMMIT, PAGE_READWRITE);
  ASSERT_TRUE(alloc != NULL);

  // We test 9 different sizes, 9 different chunk sizes, 1 to 9 different
  // alignments, and 2 different redzone sizes. This is 810 different
  // combinations. We test each of these block allocations in all 3 possible
  // states. The probe itself tests the block at 7 to 9 different points, and
  // the tests require multiple iterations. Be careful playing with these
  // constants or the unittest time can easily spiral out of control! This
  // currently requires less than half a second, and is strictly CPU bound.
  for (size_t chunk_size = kShadowRatio; chunk_size <= kPageSize;
       chunk_size *= 2) {
    for (size_t align = kShadowRatio; align <= chunk_size; align *= 2) {
      for (size_t redzone = 0; redzone <= chunk_size; redzone += chunk_size) {
        for (size_t i = 0; i < arraysize(kSizes); ++i) {
          BlockLayout layout = {};
          BlockPlanLayout(chunk_size, align, kSizes[i], redzone, redzone,
                          &layout);
          ASSERT_GT(kAllocSize, layout.block_size);

          BlockInfo block_info = {};
          BlockInitialize(layout, alloc, false, &block_info);

          // Test that the checksum detects tampering as expected in each block
          // state.
          block_info.header->state = ALLOCATED_BLOCK;
          ASSERT_NO_FATAL_FAILURE(TestChecksumDetectsTampering(block_info));
          block_info.header->state = QUARANTINED_BLOCK;
          ASSERT_NO_FATAL_FAILURE(TestChecksumDetectsTampering(block_info));
          block_info.header->state = FREED_BLOCK;
          ASSERT_NO_FATAL_FAILURE(TestChecksumDetectsTampering(block_info));
        }  // kSizes[i]
      }  // redzone
    }  // align
  }  // chunk_size

  ASSERT_EQ(TRUE, ::VirtualFree(alloc, 0, MEM_RELEASE));
}

namespace {

// An exception filter that grabs and sets an exception pointer, and
// triggers only for access violations.
DWORD AccessViolationFilter(EXCEPTION_POINTERS* e,
                            EXCEPTION_POINTERS** pe) {
  *pe = e;
  if (e->ExceptionRecord->ExceptionCode == EXCEPTION_ACCESS_VIOLATION)
    return EXCEPTION_EXECUTE_HANDLER;
  return EXCEPTION_CONTINUE_SEARCH;
}

// Tries to access the given address, validating whether or not an
// access violation occurs.
bool TestAccess(void* address, bool expect_access_violation) {
  uint8* m = reinterpret_cast<uint8*>(address);
  ULONG_PTR p = reinterpret_cast<ULONG_PTR>(address);

  // Try a read.
  uint8 value = 0;
  EXCEPTION_POINTERS* e = NULL;
  __try {
    value = m[0];
    if (expect_access_violation)
      return false;
  } __except (AccessViolationFilter(GetExceptionInformation(), &e)) {
    if (!expect_access_violation)
      return false;
    if (e->ExceptionRecord == NULL ||
        e->ExceptionRecord->NumberParameters < 2 ||
        e->ExceptionRecord->ExceptionInformation[1] != p) {
      return false;
    }
    return true;
  }

  // Try a write.
  __try {
    m[0] = 0;
    if (expect_access_violation)
      return false;
  } __except (AccessViolationFilter(GetExceptionInformation(), &e)) {
    if (!expect_access_violation)
      return false;
    if (e->ExceptionRecord == NULL ||
        e->ExceptionRecord->NumberParameters < 2 ||
        e->ExceptionRecord->ExceptionInformation[1] != p) {
      return false;
    }
  }

  // Ensure that |value| doesn't get optimized away. If so, the attempted
  // read never occurs.
  base::debug::Alias(&value);

  return true;
}

// Readable wrappers to TestAccess.
bool IsAccessible(void* address) {
  return TestAccess(address, false);
}
bool IsNotAccessible(void* address) {
  return TestAccess(address, true);
}

enum Protection {
  kProtectNone,
  kProtectRedzones,
  kProtectAll,
};

void TestAccessUnderProtection(const BlockInfo& block_info,
                               Protection protection) {
  // Grab a set of points to sample for access, scattered across the various
  // components of the block.
  std::set<void*> samples;
  samples.insert(block_info.header);
  samples.insert(block_info.header_padding - 1);
  samples.insert(block_info.header_padding);
  samples.insert(block_info.header_padding +
      block_info.header_padding_size / 2);
  samples.insert(block_info.header_padding +
      block_info.header_padding_size - 1);
  samples.insert(block_info.body);
  samples.insert(block_info.body + block_info.body_size / 2);
  samples.insert(block_info.body + block_info.body_size - 1);
  samples.insert(block_info.trailer_padding);
  samples.insert(block_info.trailer_padding +
      block_info.trailer_padding_size / 2);
  samples.insert(block_info.trailer_padding +
      block_info.trailer_padding_size - 1);
  samples.insert(block_info.trailer);
  samples.insert(block_info.trailer);
  samples.insert(block_info.block + block_info.block_size - 1);

  // Also sample at points at the edges of the pages in the redzones.
  if (block_info.left_redzone_pages_size > 0) {
    if (block_info.block < block_info.left_redzone_pages)
      samples.insert(block_info.left_redzone_pages - 1);
    samples.insert(block_info.left_redzone_pages);
    samples.insert(block_info.left_redzone_pages +
        block_info.left_redzone_pages_size - 1);
    samples.insert(block_info.left_redzone_pages +
        block_info.left_redzone_pages_size);
  }
  if (block_info.right_redzone_pages_size > 0) {
    samples.insert(block_info.right_redzone_pages - 1);
    samples.insert(block_info.right_redzone_pages);
    samples.insert(block_info.right_redzone_pages +
        block_info.right_redzone_pages_size - 1);
    uint8* past_end = block_info.right_redzone_pages +
        block_info.right_redzone_pages_size;
    if (past_end < block_info.block + block_info.block_size)
      samples.insert(past_end);
  }

  uint8* left_end = block_info.left_redzone_pages +
      block_info.left_redzone_pages_size;
  uint8* right_end = block_info.right_redzone_pages +
      block_info.right_redzone_pages_size;
  uint8* block_end = block_info.block_pages + block_info.block_pages_size;

  std::set<void*>::const_iterator it = samples.begin();
  for (; it != samples.end(); ++it) {
    if ((*it >= block_info.left_redzone_pages && *it < left_end) ||
        (*it >= block_info.right_redzone_pages && *it < right_end)) {
      // In the left or right guard pages.
      if (protection == kProtectNone) {
        EXPECT_TRUE(IsAccessible(*it));
      } else {
        EXPECT_TRUE(IsNotAccessible(*it));
      }
    } else if (*it >= block_info.block_pages && *it < block_end) {
      // In the block pages, but not a left or right guard page.
      if (protection == kProtectAll) {
        EXPECT_TRUE(IsNotAccessible(*it));
      } else {
        EXPECT_TRUE(IsAccessible(*it));
      }
    } else {
      // In the block, but in a page that is only partially covered.
      EXPECT_TRUE(IsAccessible(*it));
    }
  }
}

// Tests that the page protections are as expected after calling
// BlockProtectNone.
void TestProtectNone(const BlockInfo& block_info) {
  BlockProtectNone(block_info);
  EXPECT_NO_FATAL_FAILURE(TestAccessUnderProtection(block_info,
                                                    kProtectNone));
}

// Tests that the page protections are as expected after calling
// BlockProtectRedzones.
void TestProtectRedzones(const BlockInfo& block_info) {
  BlockProtectRedzones(block_info);
  EXPECT_NO_FATAL_FAILURE(TestAccessUnderProtection(block_info,
                                                    kProtectRedzones));
}

// Tests that the page protections are as expected after calling
// BlockProtectAll.
void TestProtectAll(const BlockInfo& block_info) {
  BlockProtectAll(block_info);
  EXPECT_NO_FATAL_FAILURE(TestAccessUnderProtection(block_info,
                                                    kProtectAll));
}

// Tests that all page protection transitions work.
void TestAllProtectionTransitions(size_t chunk_size,
                                  size_t alignment,
                                  size_t size,
                                  size_t min_left_redzone_size,
                                  size_t min_right_redzone_size) {
  // Create and initialize the given block.
  BlockLayout layout = {};
  BlockPlanLayout(chunk_size, alignment, size, min_left_redzone_size,
                  min_right_redzone_size, &layout);
  void* alloc = ::VirtualAlloc(NULL, layout.block_size, MEM_COMMIT,
                               PAGE_READWRITE);
  ASSERT_TRUE(alloc != NULL);
  BlockInfo block_info = {};
  BlockInitialize(layout, alloc, false, &block_info);

  // By default the protections should be disabled for a fresh allocation.
  EXPECT_NO_FATAL_FAILURE(TestAccessUnderProtection(block_info,
                                                    kProtectNone));

  // Try a full cycle of page protections. This tests all possible
  // transitions, including self transitions.
  EXPECT_NO_FATAL_FAILURE(TestProtectNone(block_info));
  EXPECT_NO_FATAL_FAILURE(TestProtectNone(block_info));
  EXPECT_NO_FATAL_FAILURE(TestProtectRedzones(block_info));
  EXPECT_NO_FATAL_FAILURE(TestProtectRedzones(block_info));
  EXPECT_NO_FATAL_FAILURE(TestProtectAll(block_info));
  EXPECT_NO_FATAL_FAILURE(TestProtectAll(block_info));
  EXPECT_NO_FATAL_FAILURE(TestProtectNone(block_info));
  EXPECT_NO_FATAL_FAILURE(TestProtectAll(block_info));
  EXPECT_NO_FATAL_FAILURE(TestProtectRedzones(block_info));
  EXPECT_NO_FATAL_FAILURE(TestProtectNone(block_info));

  ASSERT_EQ(TRUE, ::VirtualFree(alloc, 0, MEM_RELEASE));
}

}  // namespace

TEST(BlockTest, ProtectionTransitions) {
  // Left and right guard pages, everything page aligned.
  EXPECT_NO_FATAL_FAILURE(TestAllProtectionTransitions(
      4096, 4096, 4096, 4096, 4096));

  // Left and right guard pages will contain entire pages, but
  // not be entirely covered by pages.
  EXPECT_NO_FATAL_FAILURE(TestAllProtectionTransitions(
      8, 8, 128, 4100, 8200));

  // An allocation that will contain no pages whatsoever.
  EXPECT_NO_FATAL_FAILURE(TestAllProtectionTransitions(
      8, 8, 67, 0, 0));

  // An allocation with redzones containing no pages, but that covers an
  // entire page.
  EXPECT_NO_FATAL_FAILURE(TestAllProtectionTransitions(
      4096, 8, 67, 0, 0));
}

}  // namespace asan
}  // namespace agent
