// Copyright 2017 The Crashpad Authors. 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 "util/win/safe_terminate_process.h"

#include <string.h>

#include <string>
#include <memory>

#include "base/check.h"
#include "base/cxx17_backports.h"
#include "base/files/file_path.h"
#include "base/macros.h"
#include "build/build_config.h"
#include "gtest/gtest.h"
#include "test/errors.h"
#include "test/test_paths.h"
#include "test/win/child_launcher.h"
#include "util/win/scoped_handle.h"

namespace crashpad {
namespace test {
namespace {

// Patches executable code, saving a copy of the original code so that it can be
// restored on destruction.
class ScopedExecutablePatch {
 public:
  ScopedExecutablePatch(void* target, const void* source, size_t size)
      : original_(new uint8_t[size]), target_(target), size_(size) {
    memcpy(original_.get(), target_, size_);

    ScopedVirtualProtectRWX protect_rwx(target_, size_);
    memcpy(target_, source, size_);
  }

  ~ScopedExecutablePatch() {
    ScopedVirtualProtectRWX protect_rwx(target_, size_);
    memcpy(target_, original_.get(), size_);
  }

 private:
  // Sets the protection on (address, size) to PAGE_EXECUTE_READWRITE by calling
  // VirtualProtect(), and restores the original protection on destruction. Note
  // that the region may span multiple pages, but the first page’s original
  // protection will be applied to the entire region on destruction. This
  // shouldn’t be a problem in practice for patching a function for this test’s
  // purposes.
  class ScopedVirtualProtectRWX {
   public:
    // If either the constructor or destructor fails, PCHECK() to terminate
    // immediately, because the process will be in a weird and untrustworthy
    // state, and Google Test error handling isn’t worthwhile at that point.

    ScopedVirtualProtectRWX(void* address, size_t size)
        : address_(address), size_(size) {
      PCHECK(VirtualProtect(
          address_, size_, PAGE_EXECUTE_READWRITE, &old_protect_))
          << "VirtualProtect";
    }

    ~ScopedVirtualProtectRWX() {
      DWORD last_protect_;
      PCHECK(VirtualProtect(address_, size_, old_protect_, &last_protect_))
          << "VirtualProtect";
    }

   private:
    void* address_;
    size_t size_;
    DWORD old_protect_;

    DISALLOW_COPY_AND_ASSIGN(ScopedVirtualProtectRWX);
  };

  std::unique_ptr<uint8_t[]> original_;
  void* target_;
  size_t size_;

  DISALLOW_COPY_AND_ASSIGN(ScopedExecutablePatch);
};

// SafeTerminateProcess is calling convention specific only for x86.
#if defined(ARCH_CPU_X86_FAMILY)
TEST(SafeTerminateProcess, PatchBadly) {
  // This is a test of SafeTerminateProcess(), but it doesn’t actually terminate
  // anything. Instead, it works with a process handle for the current process
  // that doesn’t have PROCESS_TERMINATE access. The whole point of this test is
  // to patch the real TerminateProcess() badly with a cdecl implementation to
  // ensure that SafeTerminateProcess() can recover from such gross misconduct.
  // The actual termination isn’t relevant to this test.
  //
  // Notably, don’t duplicate the process handle with PROCESS_TERMINATE access
  // or with the DUPLICATE_SAME_ACCESS option. The SafeTerminateProcess() calls
  // that follow operate on a duplicate of the current process’ process handle,
  // and they’re supposed to fail, not terminate this process.
  HANDLE process;
  ASSERT_TRUE(DuplicateHandle(GetCurrentProcess(),
                              GetCurrentProcess(),
                              GetCurrentProcess(),
                              &process,
                              PROCESS_QUERY_INFORMATION,
                              false,
                              0))
      << ErrorMessage("DuplicateHandle");
  ScopedKernelHANDLE process_owner(process);

  // Make sure that TerminateProcess() works as a baseline.
  SetLastError(ERROR_SUCCESS);
  EXPECT_FALSE(TerminateProcess(process, 0));
  EXPECT_EQ(GetLastError(), static_cast<DWORD>(ERROR_ACCESS_DENIED));

  // Make sure that SafeTerminateProcess() works, calling through to
  // TerminateProcess() properly.
  SetLastError(ERROR_SUCCESS);
  EXPECT_FALSE(SafeTerminateProcess(process, 0));
  EXPECT_EQ(GetLastError(), static_cast<DWORD>(ERROR_ACCESS_DENIED));

  {
    // Patch TerminateProcess() badly. This turns it into a no-op that returns 0
    // without cleaning up arguments from the stack, as a stdcall function is
    // expected to do.
    //
    // This simulates the unexpected cdecl-patched TerminateProcess() as seen at
    // https://crashpad.chromium.org/bug/179. In reality, this only affects
    // 32-bit x86, as there’s no calling convention confusion on x86_64. It
    // doesn’t hurt to run this test in the 64-bit environment, though.
    static constexpr uint8_t patch[] = {
#if defined(ARCH_CPU_X86)
        0x31, 0xc0,  // xor eax, eax
#elif defined(ARCH_CPU_X86_64)
        0x48, 0x31, 0xc0,  // xor rax, rax
#else
#error Port
#endif
        0xc3,  // ret
    };

    void* target = reinterpret_cast<void*>(TerminateProcess);
    ScopedExecutablePatch executable_patch(target, patch, base::size(patch));

    // Make sure that SafeTerminateProcess() can be called. Since it’s been
    // patched with a no-op stub, GetLastError() shouldn’t be modified.
    SetLastError(ERROR_SUCCESS);
    EXPECT_FALSE(SafeTerminateProcess(process, 0));
    EXPECT_EQ(GetLastError(), static_cast<DWORD>(ERROR_SUCCESS));
  }

  // Now that the real TerminateProcess() has been restored, verify that it
  // still works properly.
  SetLastError(ERROR_SUCCESS);
  EXPECT_FALSE(SafeTerminateProcess(process, 0));
  EXPECT_EQ(GetLastError(), static_cast<DWORD>(ERROR_ACCESS_DENIED));
}
#endif  // ARCH_CPU_X86_FAMILY

TEST(SafeTerminateProcess, TerminateChild) {
  base::FilePath child_executable =
      TestPaths::BuildArtifact(L"util",
                               L"safe_terminate_process_test_child",
                               TestPaths::FileType::kExecutable);
  ChildLauncher child(child_executable, L"");
  ASSERT_NO_FATAL_FAILURE(child.Start());

  constexpr DWORD kExitCode = 0x51ee9d1e;  // Sort of like “sleep and die.”

  ASSERT_TRUE(SafeTerminateProcess(child.process_handle(), kExitCode))
      << ErrorMessage("TerminateProcess");
  EXPECT_EQ(child.WaitForExit(), kExitCode);
}

}  // namespace
}  // namespace test
}  // namespace crashpad
