// 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/asan_rtl_utils.h"

#include <windows.h>

#include "base/bind.h"
#include "base/rand_util.h"
#include "gtest/gtest.h"
#include "syzygy/agent/asan/asan_runtime.h"
#include "syzygy/agent/asan/shadow.h"

namespace agent {
namespace asan {

namespace {

using agent::asan::Shadow;

// A flag used in asan callback to ensure that a memory error has been detected.
bool memory_error_detected = false;
// Will save the information about the last ASan error.
AsanErrorInfo last_error_info = {};

void AsanErrorCallBack(AsanErrorInfo* error_info) {
  EXPECT_NE(reinterpret_cast<AsanErrorInfo*>(NULL), error_info);
  memory_error_detected = true;
  last_error_info = *error_info;
}

class TestAsanRuntime : public AsanRuntime {
 public:
  TestAsanRuntime() {
    memory_error_detected = false;
    SetUp(L"");
    SetErrorCallBack(base::Bind(AsanErrorCallBack));
  }

  ~TestAsanRuntime() {
    TearDown();
  }
};

}  // namespace

TEST(AsanRtlUtilsTest, ContextToAsanContext) {
  CONTEXT context = {};
  AsanContext asan_context = {};
  base::RandBytes(reinterpret_cast<void*>(&context), sizeof(context));
  ContextToAsanContext(context, &asan_context);

  EXPECT_EQ(context.Eax, asan_context.original_eax);
  EXPECT_EQ(context.Ebp, asan_context.original_ebp);
  EXPECT_EQ(context.Ebx, asan_context.original_ebx);
  EXPECT_EQ(context.Ecx, asan_context.original_ecx);
  EXPECT_EQ(context.Edi, asan_context.original_edi);
  EXPECT_EQ(context.Edx, asan_context.original_edx);
  EXPECT_EQ(context.Eip, asan_context.original_eip);
  EXPECT_EQ(context.Esi, asan_context.original_esi);
  EXPECT_EQ(context.Esp, asan_context.original_esp);
  EXPECT_EQ(context.EFlags, asan_context.original_eflags);
}

TEST(AsanRtlUtilsTest, ReportBadMemoryAccess) {
  TestAsanRuntime runtime;
  SetAsanRuntimeInstance(&runtime);
  void* bad_location = reinterpret_cast<void*>(0xBAD0ADD5);
  AccessMode access_mode = ASAN_READ_ACCESS;
  size_t access_size = 4;
  AsanContext asan_context = {};
  base::RandBytes(reinterpret_cast<void*>(&asan_context), sizeof(asan_context));
  ReportBadMemoryAccess(bad_location, access_mode, access_size, asan_context);

  EXPECT_TRUE(memory_error_detected);
  EXPECT_EQ(bad_location, last_error_info.location);
  EXPECT_EQ(access_size, last_error_info.access_size);
  EXPECT_EQ(access_mode, last_error_info.access_mode);
  EXPECT_EQ(asan_context.original_eax, last_error_info.context.Eax);
  EXPECT_EQ(asan_context.original_ebp, last_error_info.context.Ebp);
  EXPECT_EQ(asan_context.original_ebx, last_error_info.context.Ebx);
  EXPECT_EQ(asan_context.original_ecx, last_error_info.context.Ecx);
  EXPECT_EQ(asan_context.original_edi, last_error_info.context.Edi);
  EXPECT_EQ(asan_context.original_edx, last_error_info.context.Edx);
  EXPECT_EQ(asan_context.original_eip, last_error_info.context.Eip);
  EXPECT_EQ(asan_context.original_esi, last_error_info.context.Esi);
  EXPECT_EQ(asan_context.original_esp, last_error_info.context.Esp);
  EXPECT_EQ(asan_context.original_eflags, last_error_info.context.EFlags);
}

TEST(AsanRtlUtilsTest, ReportBadAccess) {
  TestAsanRuntime runtime;
  SetAsanRuntimeInstance(&runtime);
  uint8* bad_location = reinterpret_cast<uint8*>(0xBAD0ADD5);
  AccessMode access_mode = ASAN_READ_ACCESS;
  ReportBadAccess(bad_location, access_mode);

  EXPECT_TRUE(memory_error_detected);
  EXPECT_EQ(bad_location, last_error_info.location);
  EXPECT_EQ(access_mode, last_error_info.access_mode);
}

TEST(AsanRtlUtilsTest, TestMemoryRange) {
  TestAsanRuntime runtime;
  SetAsanRuntimeInstance(&runtime);
  AccessMode access_mode = ASAN_READ_ACCESS;
  const size_t kTestBufferSize = 64;
  scoped_ptr<uint8> test_buffer(new uint8[kTestBufferSize]);

  TestMemoryRange(test_buffer.get(), kTestBufferSize, access_mode);
  EXPECT_FALSE(memory_error_detected);

  // Poison the second half of the buffer.
  Shadow::Poison(test_buffer.get() + kTestBufferSize / 2,
                 kTestBufferSize / 2,
                 kUserRedzoneMarker);

  // Test the first half of the buffer, no error should be detected.
  TestMemoryRange(test_buffer.get(), kTestBufferSize / 2, access_mode);
  EXPECT_FALSE(memory_error_detected);

  // Test the second half of the buffer, we should get an invalid access on its
  // last byte.
  TestMemoryRange(test_buffer.get(), kTestBufferSize, access_mode);
  EXPECT_TRUE(memory_error_detected);
  EXPECT_EQ(test_buffer.get() + kTestBufferSize - 1, last_error_info.location);
  EXPECT_EQ(access_mode, last_error_info.access_mode);

  Shadow::Unpoison(test_buffer.get(), kTestBufferSize);
}

TEST(AsanRtlUtilsTest, TestStructure) {
  TestAsanRuntime runtime;
  SetAsanRuntimeInstance(&runtime);
  AccessMode access_mode = ASAN_READ_ACCESS;
  scoped_ptr<double> test_struct(new double);

  TestStructure(test_struct.get(), access_mode);
  EXPECT_FALSE(memory_error_detected);

  Shadow::Poison(test_struct.get(),
                 sizeof(double),
                 kUserRedzoneMarker);

  TestStructure(test_struct.get(), access_mode);
  EXPECT_TRUE(memory_error_detected);
  EXPECT_EQ(test_struct.get(), last_error_info.location);
  EXPECT_EQ(access_mode, last_error_info.access_mode);

  Shadow::Unpoison(test_struct.get(), sizeof(double));
}

}  // namespace asan
}  // namespace agent
