// Copyright 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "sandbox/win/src/process_mitigations.h"

#include <windows.h>

#include <string>

#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/path_service.h"
#include "base/strings/stringprintf.h"
#include "base/win/windows_version.h"
#include "sandbox/win/src/process_mitigations.h"
#include "sandbox/win/src/sandbox.h"
#include "sandbox/win/src/target_services.h"
#include "sandbox/win/tests/common/controller.h"
#include "sandbox/win/tests/integration_tests/hooking_dll.h"
#include "sandbox/win/tests/integration_tests/integration_tests_common.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace {

//------------------------------------------------------------------------------
// Internal Defines & Functions
//------------------------------------------------------------------------------

// Enum the dynamic code APIs being tested, to prevent hard coded int values.
enum DynCodeAPI {
  VIRTUALALLOC = 1,
  VIRTUALPROTECT,
  MAPVIEWCUSTOM,
  MAPVIEWFILE,
  NOTSUPPORTED  // Always leave this as the last enum.
};

// Advanced private function declaration.
void DynamicCodeTestHarness(sandbox::MitigationFlags which_mitigation,
                            bool expect_success,
                            bool enable_mitigation,
                            bool with_thread_opt_out = false);

// Common helper function for the different child process dynamic code tests.
//
// - VirtualAlloc with PAGE_EXECUTE_*
// - VirtualProtect with PAGE_EXECUTE_*
// - MapViewOfFile with FILE_MAP_EXECUTE | FILE_MAP_WRITE
int DynamicCodeTest(DynCodeAPI which_test, wchar_t* path) {
  switch (which_test) {
    case VIRTUALALLOC: {
      // Test VirtualAlloc with PAGE_EXECUTE_READWRITE.
      //-----------------------------------------------
      // Size rounds up to one page.
      void* allocation = ::VirtualAlloc(nullptr, 1, MEM_RESERVE | MEM_COMMIT,
                                        PAGE_EXECUTE_READWRITE);
      if (!allocation) {
        DWORD error = ::GetLastError();
        return static_cast<int>(error);
      }
      ::VirtualFree(allocation, 0, MEM_RELEASE);
      break;
    }
    case VIRTUALPROTECT: {
      // Test VirtualProtect with PAGE_EXECUTE_READWRITE.
      //-------------------------------------------------
      // Use an existing executable function pointer.
      BYTE* function = reinterpret_cast<BYTE*>(&DynamicCodeTestHarness);
      DWORD old_protect, temp = 0;
      // Test making executable binary writable.
      if (!::VirtualProtect(function, sizeof(size_t), PAGE_EXECUTE_READWRITE,
                            &old_protect)) {
        DWORD error = ::GetLastError();
        return static_cast<int>(error);
      }
      // Make sure to test the change back to executable.
      if (!::VirtualProtect(function, sizeof(size_t), old_protect, &temp)) {
        DWORD error = ::GetLastError();
        return static_cast<int>(error);
      }
      break;
    }
    case MAPVIEWCUSTOM: {
      // Test MapViewOfFile with FILE_MAP_EXECUTE | FILE_MAP_WRITE.
      // (Custom created mapping.)
      //-----------------------------------------------------------
      HANDLE section =
          ::CreateFileMappingW(INVALID_HANDLE_VALUE, nullptr,
                               PAGE_EXECUTE_READWRITE, 0, 4096, L"TestMapping");
      if (!section) {
        DWORD error = ::GetLastError();
        return static_cast<int>(error);
      }

      // Note: this test hinges on FILE_MAP_EXECUTE | FILE_MAP_WRITE access.
      // Any other access request will succeed even with the mitigation enabled.
      HANDLE* view = reinterpret_cast<HANDLE*>(::MapViewOfFile(
          section, FILE_MAP_EXECUTE | FILE_MAP_WRITE, 0, 0, 4096));

      if (!view) {
        DWORD error = ::GetLastError();
        return static_cast<int>(error);
      }

      ::UnmapViewOfFile(view);
      ::CloseHandle(section);
      break;
    }
    case MAPVIEWFILE: {
      // Test MapViewOfFile with FILE_MAP_EXECUTE | FILE_MAP_WRITE.
      // (Existing file on disk mapping.)
      //-----------------------------------------------------------
      // Caller should have passed in a non-null file path.
      if (!path)
        return sandbox::SBOX_TEST_INVALID_PARAMETER;

      // Note: INVALID_HANDLE_VALUE
      HANDLE file_handle =
          ::CreateFile(path, GENERIC_EXECUTE | GENERIC_READ | GENERIC_WRITE,
                       FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr,
                       OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
      if (file_handle == INVALID_HANDLE_VALUE) {
        DWORD error = ::GetLastError();
        return static_cast<int>(error);
      }

      HANDLE mapping_handle = ::CreateFileMapping(
          file_handle, nullptr, PAGE_EXECUTE_READWRITE, 0, 1, nullptr);
      if (!mapping_handle) {
        ::CloseHandle(file_handle);
        DWORD error = ::GetLastError();
        return static_cast<int>(error);
      }

      // Note: this test hinges on FILE_MAP_EXECUTE | FILE_MAP_WRITE access.
      // Any other access request will succeed even with the mitigation enabled.
      void* view_start = ::MapViewOfFile(
          mapping_handle, FILE_MAP_EXECUTE | FILE_MAP_WRITE, 0, 0, 0);
      if (!view_start) {
        ::CloseHandle(mapping_handle);
        ::CloseHandle(file_handle);
        DWORD error = ::GetLastError();
        return static_cast<int>(error);
      }

      ::UnmapViewOfFile(view_start);
      ::CloseHandle(mapping_handle);
      ::CloseHandle(file_handle);
      break;
    }
    default:
      return sandbox::SBOX_TEST_INVALID_PARAMETER;
  }

  return sandbox::SBOX_TEST_SUCCEEDED;
}

// Thread class for testing dynamic code per-thread opt-out.
class DynamicCodeOptOutThread {
 public:
  // |path| optional, depending on |which_test|.
  DynamicCodeOptOutThread(bool mitigation,
                          DynCodeAPI which_test,
                          wchar_t* path = nullptr)
      : thread_(nullptr),
        opt_out_(mitigation),
        which_api_test_(which_test),
        file_path_(path),
        return_code_(sandbox::SBOX_TEST_NOT_FOUND) {}

  ~DynamicCodeOptOutThread() {
    if (thread_) {
      ::CloseHandle(thread_);
      thread_ = nullptr;
    }
  }

  // LPTHREAD_START_ROUTINE
  static DWORD WINAPI StaticThreadFunc(LPVOID lpParam) {
    DynamicCodeOptOutThread* this_thread =
        reinterpret_cast<DynamicCodeOptOutThread*>(lpParam);
    return this_thread->ThreadFunc();
  }

  // Main function.  Call this to create and start the test thread.
  // Call Join() to get the test result.
  void Start() {
    if (thread_)
      return;

    thread_ = ::CreateThread(nullptr, 0, StaticThreadFunc, this, 0, nullptr);
    if (!thread_) {
      return_code_ = ::GetLastError();
      return;
    }
  }

  // Wait for test thread to finish, and get the final test result.
  int Join() {
    // Handle case where thread creation failed.
    if (!thread_)
      return return_code_;

    // NOTE: TestTimeouts::action_max_timeout() is not long enough here.  In
    //       debug build this times out.
    DWORD timeout = ::IsDebuggerPresent() ? INFINITE : 5000;
    return_code_ = ::WaitForSingleObject(thread_, timeout);
    // Handle case of abnormal thread exit (or timeout).
    if (return_code_ != WAIT_OBJECT_0)
      return return_code_;

    if (!::GetExitCodeThread(thread_,
                             reinterpret_cast<DWORD*>(&return_code_))) {
      // Handle unexpected case of failing to get thread exit code.
      return_code_ = ::GetLastError();
      return return_code_;
    }

    return return_code_;
  }

 private:
  DWORD ThreadFunc() {
    // Opt-out this thread from disabled dynamic code.
    if (opt_out_) {
      if (!sandbox::ApplyMitigationsToCurrentThread(
              sandbox::MITIGATION_DYNAMIC_CODE_OPT_OUT_THIS_THREAD)) {
        return ::GetLastError();
      }
    }
    // Run the test.
    return DynamicCodeTest(which_api_test_, file_path_);
  }

  HANDLE thread_;
  bool opt_out_;
  DynCodeAPI which_api_test_;
  wchar_t* file_path_;
  int return_code_;

  DISALLOW_COPY_AND_ASSIGN(DynamicCodeOptOutThread);
};

//------------------------------------------------------------------------------
// DisableDynamicCode test harness helper function.  Tests numerous APIs.
// - APIs fail with ERROR_DYNAMIC_CODE_BLOCKED if this mitigation is
//   enabled and the target tries to meddle.
// - Acquire the global g_hooking_dll_mutex mutex before calling
//   (as we meddle with a shared system resource).
// - Note: Do not use ASSERTs in this function, as a global mutex is held.
//
// Trigger test child processes (with or without mitigation enabled).
//------------------------------------------------------------------------------
void DynamicCodeTestHarness(sandbox::MitigationFlags which_mitigation,
                            bool expect_success,
                            bool enable_mitigation,
                            bool with_thread_opt_out) {
  if (which_mitigation != sandbox::MITIGATION_DYNAMIC_CODE_DISABLE &&
      which_mitigation !=
          sandbox::MITIGATION_DYNAMIC_CODE_DISABLE_WITH_OPT_OUT) {
    ADD_FAILURE();
    return;
  }

  sandbox::TestRunner runner;
  sandbox::TargetPolicy* policy = runner.GetPolicy();

  if (enable_mitigation) {
    EXPECT_EQ(policy->SetDelayedProcessMitigations(which_mitigation),
              sandbox::SBOX_ALL_OK);
  }

  base::string16 shared =
      (which_mitigation == sandbox::MITIGATION_DYNAMIC_CODE_DISABLE)
          ? L"TestWin81DynamicCode "
          : L"TestWin10DynamicCodeWithOptOut ";
  if (which_mitigation ==
      sandbox::MITIGATION_DYNAMIC_CODE_DISABLE_WITH_OPT_OUT) {
    shared += (with_thread_opt_out) ? L"true" : L"false";
  }

  // Test 1:
  base::string16 test =
      base::StringPrintf(L"%ls %u", shared.c_str(), VIRTUALALLOC);
  EXPECT_EQ((expect_success ? sandbox::SBOX_TEST_SUCCEEDED
                            : ERROR_DYNAMIC_CODE_BLOCKED),
            runner.RunTest(test.c_str()));

  // Test 2:
  test = base::StringPrintf(L"%ls %u", shared.c_str(), VIRTUALPROTECT);
  EXPECT_EQ((expect_success ? sandbox::SBOX_TEST_SUCCEEDED
                            : ERROR_DYNAMIC_CODE_BLOCKED),
            runner.RunTest(test.c_str()));

  // Test 3:
  // Need token level >= USER_LIMITED to be able to successfully run test 3.
  policy->SetTokenLevel(sandbox::TokenLevel::USER_RESTRICTED_SAME_ACCESS,
                        sandbox::TokenLevel::USER_LIMITED);

  test = base::StringPrintf(L"%ls %u", shared.c_str(), MAPVIEWCUSTOM);
  EXPECT_EQ((expect_success ? sandbox::SBOX_TEST_SUCCEEDED
                            : ERROR_DYNAMIC_CODE_BLOCKED),
            runner.RunTest(test.c_str()));

  // Test 4:
  // Set token levels back to default.
  policy->SetTokenLevel(sandbox::TokenLevel::USER_RESTRICTED_SAME_ACCESS,
                        sandbox::TokenLevel::USER_LOCKDOWN);

  // Ensure sandbox access to the file on disk.
  base::FilePath dll_path;
  ASSERT_TRUE(base::PathService::Get(base::DIR_EXE, &dll_path));
  dll_path = dll_path.Append(hooking_dll::g_hook_dll_file);

  // File must be writable, so create a writable copy in a temporary directory.
  base::ScopedTempDir temp_dir;
  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
  base::FilePath temp_dll_path =
      temp_dir.GetPath().Append(hooking_dll::g_hook_dll_file);
  ASSERT_TRUE(base::CopyFile(dll_path, temp_dll_path));

  EXPECT_TRUE(runner.AddFsRule(sandbox::TargetPolicy::FILES_ALLOW_ANY,
                               temp_dll_path.value().c_str()));

  test = base::StringPrintf(L"%ls %u \"%ls\"", shared.c_str(), MAPVIEWFILE,
                            temp_dll_path.value().c_str());
  EXPECT_EQ((expect_success ? sandbox::SBOX_TEST_SUCCEEDED
                            : ERROR_DYNAMIC_CODE_BLOCKED),
            runner.RunTest(test.c_str()));
}

}  // namespace

namespace sandbox {

//------------------------------------------------------------------------------
// Exported functions called by child test processes.
//------------------------------------------------------------------------------

// Parse arguments and do the test.
//
// - Arg1 is a DynCodeAPI indicating which API to test.
// - [OPTIONAL] If Arg1 is MAPVIEWFILE, Arg2 is a file path to map.
SBOX_TESTS_COMMAND int TestWin81DynamicCode(int argc, wchar_t** argv) {
  if (argc < 1 || !argv[0])
    return SBOX_TEST_INVALID_PARAMETER;

  // Arg1
  int test = ::_wtoi(argv[0]);
  if (test <= 0 || test >= NOTSUPPORTED)
    return SBOX_TEST_INVALID_PARAMETER;

  // [OPTIONAL] Arg2
  wchar_t* path = nullptr;
  if (argc > 1)
    path = argv[1];

  return DynamicCodeTest(static_cast<DynCodeAPI>(test), path);
}

// Parse arguments and spawn the test thread.
//
// - Arg1 is a bool indicating whether to opt-out the test thread.
// - Arg2 is a DynCodeAPI indicating which API to test.
// - [OPTIONAL] If Arg2 is MAPVIEWFILE, Arg3 is a file path to map.
SBOX_TESTS_COMMAND int TestWin10DynamicCodeWithOptOut(int argc,
                                                      wchar_t** argv) {
  if (argc < 2 || !argv[0] || !argv[1])
    return SBOX_TEST_INVALID_PARAMETER;

  // Arg1
  bool opt_out = false;
  if (::wcsicmp(argv[0], L"true") == 0)
    opt_out = true;

  // Arg2
  int test = ::_wtoi(argv[1]);
  if (test <= 0 || test >= NOTSUPPORTED)
    return SBOX_TEST_INVALID_PARAMETER;

  // [OPTIONAL] Arg3
  wchar_t* path = nullptr;
  if (argc > 2)
    path = argv[2];

  // Spawn new thread and wait for it to finish!
  DynamicCodeOptOutThread opt_out_thread(opt_out, static_cast<DynCodeAPI>(test),
                                         path);
  opt_out_thread.Start();
  return opt_out_thread.Join();
}

//------------------------------------------------------------------------------
// Exported Dynamic Code Tests
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
// Disable dynamic code (MITIGATION_DYNAMIC_CODE_DISABLE)
// >= Win8.1
//------------------------------------------------------------------------------

// This test validates that setting the MITIGATION_DYNAMIC_CODE_DISABLE
// mitigation enables the setting on a process.
TEST(ProcessMitigationsTest, CheckWin81DynamicCodePolicySuccess) {
  if (base::win::GetVersion() < base::win::VERSION_WIN8_1)
    return;

// TODO(crbug.com/805414): Windows ASan hotpatching requires dynamic code.
#if defined(ADDRESS_SANITIZER)
  return;
#endif

  base::string16 test_command = L"CheckPolicy ";
  test_command += std::to_wstring(TESTPOLICY_DYNAMICCODE);

//---------------------------------
// 1) Test setting pre-startup.
// **Currently only running pre-startup in release.  Due to the sandbox in the
// child using dynamic code for hooks, calls to "dynamic code APIs" are
// failing... silently in release, but assert/breakpoint in debug.  Since
// this test is only to check the policy setting, ignoring the failures is ok.
//---------------------------------
#if defined(NDEBUG)
  TestRunner runner;
  sandbox::TargetPolicy* policy = runner.GetPolicy();

  EXPECT_EQ(policy->SetProcessMitigations(MITIGATION_DYNAMIC_CODE_DISABLE),
            SBOX_ALL_OK);
  EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(test_command.c_str()));
#endif  // defined(NDEBUG)
  //---------------------------------
  // 2) Test setting post-startup.
  //---------------------------------
  TestRunner runner2;
  sandbox::TargetPolicy* policy2 = runner2.GetPolicy();

  EXPECT_EQ(
      policy2->SetDelayedProcessMitigations(MITIGATION_DYNAMIC_CODE_DISABLE),
      SBOX_ALL_OK);
  EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner2.RunTest(test_command.c_str()));
}

// This test validates that we can meddle with dynamic code if the
// MITIGATION_DYNAMIC_CODE_DISABLE mitigation is NOT set.
TEST(ProcessMitigationsTest, CheckWin81DynamicCode_BaseCase) {
  if (base::win::GetVersion() < base::win::VERSION_WIN8_1)
    return;

  HANDLE mutex =
      ::CreateMutexW(nullptr, false, hooking_dll::g_hooking_dll_mutex);
  EXPECT_TRUE(mutex);
  EXPECT_EQ(WAIT_OBJECT_0,
            ::WaitForSingleObject(mutex, SboxTestEventTimeout()));

  // Expect success, no mitigation.
  DynamicCodeTestHarness(sandbox::MITIGATION_DYNAMIC_CODE_DISABLE, true, false);

  EXPECT_TRUE(::ReleaseMutex(mutex));
  EXPECT_TRUE(::CloseHandle(mutex));
}

// This test validates that setting the MITIGATION_DYNAMIC_CODE_DISABLE
// mitigation prevents meddling with dynamic code.
TEST(ProcessMitigationsTest, CheckWin81DynamicCode_TestMitigation) {
  if (base::win::GetVersion() < base::win::VERSION_WIN8_1)
    return;

  HANDLE mutex =
      ::CreateMutexW(nullptr, false, hooking_dll::g_hooking_dll_mutex);
  EXPECT_TRUE(mutex);
  EXPECT_EQ(WAIT_OBJECT_0,
            ::WaitForSingleObject(mutex, SboxTestEventTimeout()));

  // Expect failure, with mitigation.
  DynamicCodeTestHarness(sandbox::MITIGATION_DYNAMIC_CODE_DISABLE, false, true);

  EXPECT_TRUE(::ReleaseMutex(mutex));
  EXPECT_TRUE(::CloseHandle(mutex));
}

//------------------------------------------------------------------------------
// Disable dynamic code, with per-thread opt-out enabled
// (MITIGATION_DYNAMIC_CODE_DISABLE_WITH_OPT_OUT).
// >= Win10_RS1 (Anniversary)
//------------------------------------------------------------------------------

// This test validates that setting the
// MITIGATION_DYNAMIC_CODE_DISABLE_WITH_OPT_OUT mitigation enables the setting
// on a process.
TEST(ProcessMitigationsTest, CheckWin10DynamicCodeOptOutPolicySuccess) {
  if (base::win::GetVersion() < base::win::VERSION_WIN10_RS1)
    return;

// TODO(crbug.com/805414): Windows ASan hotpatching requires dynamic code.
#if defined(ADDRESS_SANITIZER)
  return;
#endif

  base::string16 test_command = L"CheckPolicy ";
  test_command += std::to_wstring(TESTPOLICY_DYNAMICCODEOPTOUT);

//---------------------------------
// 1) Test setting pre-startup.
// **Currently only running pre-startup in release.  Due to the sandbox in the
// child using dynamic code for hooks, calls to "dynamic code APIs" are
// failing... silently in release, but assert/breakpoint in debug.  Since
// this test is only to check the policy setting, ignoring the failures is ok.
//---------------------------------
#if defined(NDEBUG)
  TestRunner runner;
  sandbox::TargetPolicy* policy = runner.GetPolicy();

  EXPECT_EQ(policy->SetProcessMitigations(
                MITIGATION_DYNAMIC_CODE_DISABLE_WITH_OPT_OUT),
            SBOX_ALL_OK);
  EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(test_command.c_str()));
#endif  // defined(NDEBUG)
  //---------------------------------
  // 2) Test setting post-startup.
  //---------------------------------
  TestRunner runner2;
  sandbox::TargetPolicy* policy2 = runner2.GetPolicy();

  EXPECT_EQ(policy2->SetDelayedProcessMitigations(
                MITIGATION_DYNAMIC_CODE_DISABLE_WITH_OPT_OUT),
            SBOX_ALL_OK);
  EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner2.RunTest(test_command.c_str()));
}

// This test validates that we CAN meddle with dynamic code if the
// MITIGATION_DYNAMIC_CODE_DISABLE_WITH_OPT_OUT mitigation is NOT set.
TEST(ProcessMitigationsTest, CheckWin10DynamicCodeOptOut_BaseCase) {
  if (base::win::GetVersion() < base::win::VERSION_WIN10_RS1)
    return;

  HANDLE mutex =
      ::CreateMutexW(nullptr, false, hooking_dll::g_hooking_dll_mutex);
  EXPECT_TRUE(mutex);
  EXPECT_EQ(WAIT_OBJECT_0,
            ::WaitForSingleObject(mutex, SboxTestEventTimeout()));

  // Expect success, no mitigation (and therefore no thread opt-out).
  DynamicCodeTestHarness(sandbox::MITIGATION_DYNAMIC_CODE_DISABLE_WITH_OPT_OUT,
                         true, false, false);

  EXPECT_TRUE(::ReleaseMutex(mutex));
  EXPECT_TRUE(::CloseHandle(mutex));
}

// This test validates that setting the
// MITIGATION_DYNAMIC_CODE_DISABLE_WITH_OPT_OUT mitigation BLOCKS meddling
// with dynamic code.
TEST(ProcessMitigationsTest, CheckWin10DynamicCodeOptOut_TestMitigation) {
  if (base::win::GetVersion() < base::win::VERSION_WIN10_RS1)
    return;

  HANDLE mutex =
      ::CreateMutexW(nullptr, false, hooking_dll::g_hooking_dll_mutex);
  EXPECT_TRUE(mutex);
  EXPECT_EQ(WAIT_OBJECT_0,
            ::WaitForSingleObject(mutex, SboxTestEventTimeout()));

  // Expect failure, with mitigation, no thread opt-out.
  DynamicCodeTestHarness(sandbox::MITIGATION_DYNAMIC_CODE_DISABLE_WITH_OPT_OUT,
                         false, true, false);

  EXPECT_TRUE(::ReleaseMutex(mutex));
  EXPECT_TRUE(::CloseHandle(mutex));
}

// This test validates that setting the
// MITIGATION_DYNAMIC_CODE_DISABLE_WITH_OPT_OUT mitigation AND using
// thread-specific opt-out ALLOWS meddling with dynamic code.
TEST(ProcessMitigationsTest,
     CheckWin10DynamicCodeOptOut_TestMitigationWithOptOut) {
  if (base::win::GetVersion() < base::win::VERSION_WIN10_RS1)
    return;

  HANDLE mutex =
      ::CreateMutexW(nullptr, false, hooking_dll::g_hooking_dll_mutex);
  EXPECT_TRUE(mutex);
  EXPECT_EQ(WAIT_OBJECT_0,
            ::WaitForSingleObject(mutex, SboxTestEventTimeout()));

  // Expect success, with mitigation, with thread opt-out.
  DynamicCodeTestHarness(sandbox::MITIGATION_DYNAMIC_CODE_DISABLE_WITH_OPT_OUT,
                         true, true, true);

  EXPECT_TRUE(::ReleaseMutex(mutex));
  EXPECT_TRUE(::CloseHandle(mutex));
}

}  // namespace sandbox
