// Copyright 2018 The Crashpad Authors
//
// 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 "snapshot/sanitized/process_snapshot_sanitized.h"

#include <string.h>

#include <iterator>

#include "base/notreached.h"
#include "build/build_config.h"
#include "gtest/gtest.h"
#include "test/multiprocess_exec.h"
#include "util/file/file_io.h"
#include "util/misc/address_sanitizer.h"
#include "util/numeric/safe_assignment.h"

#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID)
#include <sys/syscall.h>

#include "snapshot/linux/process_snapshot_linux.h"
#include "util/linux/direct_ptrace_connection.h"
#include "util/linux/exception_information.h"
#include "util/posix/signals.h"
#endif

namespace crashpad {
namespace test {
namespace {

class ExceptionGenerator {
 public:
  ExceptionGenerator(const ExceptionGenerator&) = delete;
  ExceptionGenerator& operator=(const ExceptionGenerator&) = delete;

  static ExceptionGenerator* Get() {
    static ExceptionGenerator* instance = new ExceptionGenerator();
    return instance;
  }

  bool Initialize(FileHandle in, FileHandle out) {
    in_ = in;
    out_ = out;
    return Signals::InstallCrashHandlers(HandleCrash, 0, nullptr);
  }

 private:
  ExceptionGenerator() = default;
  ~ExceptionGenerator() = delete;

  static void HandleCrash(int signo, siginfo_t* siginfo, void* context) {
    auto state = Get();

    ExceptionInformation info = {};
    info.siginfo_address = FromPointerCast<VMAddress>(siginfo);
    info.context_address = FromPointerCast<VMAddress>(context);
    info.thread_id = syscall(SYS_gettid);

    auto info_addr = FromPointerCast<VMAddress>(&info);
    ASSERT_TRUE(LoggingWriteFile(state->out_, &info_addr, sizeof(info_addr)));

    CheckedReadFileAtEOF(state->in_);
    Signals::RestoreHandlerAndReraiseSignalOnReturn(siginfo, nullptr);
  }

  FileHandle in_;
  FileHandle out_;
};

constexpr char kAllowedAnnotationName[] = "name_of_allowed_anno";
constexpr char kAllowedAnnotationNamePattern[] = "name_of_another_*";
constexpr char kAllowedAnnotationNamePatternActual[] = "name_of_another_anno";
constexpr char kAllowedAnnotationValue[] = "some_value";
constexpr char kNonAllowedAnnotationName[] = "non_allowed_anno";
constexpr char kNonAllowedAnnotationValue[] = "private_annotation";
constexpr char kSensitiveStackData[] = "sensitive_stack_data";

struct ChildTestAddresses {
  VMAddress string_address;
  VMAddress module_address;
  VMAddress non_module_address;
  VMAddress code_pointer_address;
  VMAddress code_pointer_value;
};

void ChildTestFunction() {
  FileHandle in = StdioFileHandle(StdioStream::kStandardInput);
  FileHandle out = StdioFileHandle(StdioStream::kStandardOutput);

  static StringAnnotation<32> allowed_annotation(kAllowedAnnotationName);
  allowed_annotation.Set(kAllowedAnnotationValue);

  static StringAnnotation<32> allowed_matched_annotation(
      kAllowedAnnotationNamePatternActual);
  allowed_matched_annotation.Set(kAllowedAnnotationValue);

  static StringAnnotation<32> non_allowed_annotation(kNonAllowedAnnotationName);
  non_allowed_annotation.Set(kNonAllowedAnnotationValue);

  char string_data[std::size(kSensitiveStackData)];
  strcpy(string_data, kSensitiveStackData);

  void (*code_pointer)(void) = ChildTestFunction;

  ChildTestAddresses addrs = {};
  addrs.string_address = FromPointerCast<VMAddress>(string_data);
  addrs.module_address = FromPointerCast<VMAddress>(ChildTestFunction);
  addrs.non_module_address = FromPointerCast<VMAddress>(&addrs);
  addrs.code_pointer_address = FromPointerCast<VMAddress>(&code_pointer);
  addrs.code_pointer_value = FromPointerCast<VMAddress>(code_pointer);
  ASSERT_TRUE(LoggingWriteFile(out, &addrs, sizeof(addrs)));

  auto gen = ExceptionGenerator::Get();
  ASSERT_TRUE(gen->Initialize(in, out));

  __builtin_trap();
}

CRASHPAD_CHILD_TEST_MAIN(ChildToBeSanitized) {
  ChildTestFunction();
  NOTREACHED();
  return EXIT_SUCCESS;
}

void ExpectAnnotations(ProcessSnapshot* snapshot, bool sanitized) {
  bool found_allowed = false;
  bool found_matched_allowed = false;
  bool found_non_allowed = false;
  for (auto module : snapshot->Modules()) {
    for (const auto& anno : module->AnnotationObjects()) {
      if (anno.name == kAllowedAnnotationName) {
        found_allowed = true;
      }
      if (anno.name == kAllowedAnnotationNamePatternActual) {
        found_matched_allowed = true;
      } else if (anno.name == kNonAllowedAnnotationName) {
        found_non_allowed = true;
      }
    }
  }

  EXPECT_TRUE(found_allowed);
  EXPECT_TRUE(found_matched_allowed);
  if (sanitized) {
    EXPECT_FALSE(found_non_allowed);
  } else {
    EXPECT_TRUE(found_non_allowed);
  }
}

void ExpectProcessMemory(ProcessSnapshot* snapshot,
                         VMAddress allowed_byte,
                         bool sanitized) {
  auto memory = snapshot->Memory();

  char out;
  EXPECT_TRUE(memory->Read(allowed_byte, 1, &out));

  bool disallowed_read = memory->Read(allowed_byte + 1, 1, &out);
  if (sanitized) {
    EXPECT_FALSE(disallowed_read);
  } else {
    EXPECT_TRUE(disallowed_read);
  }
}

class StackSanitizationChecker : public MemorySnapshot::Delegate {
 public:
  StackSanitizationChecker() = default;
  ~StackSanitizationChecker() = default;

  void CheckStack(const MemorySnapshot* stack,
                  const ChildTestAddresses& addrs,
                  bool is_64_bit,
                  bool sanitized) {
    stack_ = stack;
    addrs_ = addrs;
    is_64_bit_ = is_64_bit;
    sanitized_ = sanitized;
    EXPECT_TRUE(stack_->Read(this));
  }

  // MemorySnapshot::Delegate
  bool MemorySnapshotDelegateRead(void* data, size_t size) override {
    // AddressSanitizer with use-after-return detection causes stack variables
    // to be allocated on the heap.
#if !defined(ADDRESS_SANITIZER)
    size_t pointer_offset;
    if (!AssignIfInRange(&pointer_offset,
                         addrs_.code_pointer_address - stack_->Address())) {
      ADD_FAILURE();
      return false;
    }

    const auto data_c = static_cast<char*>(data);
    VMAddress pointer_value;
    if (is_64_bit_) {
      pointer_value = *reinterpret_cast<uint64_t*>(data_c + pointer_offset);
    } else {
      pointer_value = *reinterpret_cast<uint32_t*>(data_c + pointer_offset);
    }
    EXPECT_EQ(pointer_value, addrs_.code_pointer_value);

    size_t string_offset;
    if (!AssignIfInRange(&string_offset,
                         addrs_.string_address - stack_->Address())) {
      ADD_FAILURE();
      return false;
    }

    auto string = data_c + string_offset;
    if (sanitized_) {
      EXPECT_STRNE(string, kSensitiveStackData);
    } else {
      EXPECT_STREQ(string, kSensitiveStackData);
    }
#endif  // !ADDRESS_SANITIZER
    return true;
  }

 private:
  const MemorySnapshot* stack_;
  ChildTestAddresses addrs_;
  bool is_64_bit_;
  bool sanitized_;
};

void ExpectStackData(ProcessSnapshot* snapshot,
                     const ChildTestAddresses& addrs,
                     bool sanitized) {
  const ThreadSnapshot* crasher = nullptr;
  for (const auto thread : snapshot->Threads()) {
    if (thread->ThreadID() == snapshot->Exception()->ThreadID()) {
      crasher = thread;
      break;
    }
  }
  ASSERT_TRUE(crasher);

  const MemorySnapshot* stack = crasher->Stack();
  StackSanitizationChecker().CheckStack(
      stack, addrs, crasher->Context()->Is64Bit(), sanitized);
}

class SanitizeTest : public MultiprocessExec {
 public:
  SanitizeTest() : MultiprocessExec() {
    SetChildTestMainFunction("ChildToBeSanitized");
    SetExpectedChildTerminationBuiltinTrap();
  }

  SanitizeTest(const SanitizeTest&) = delete;
  SanitizeTest& operator=(const SanitizeTest&) = delete;

  ~SanitizeTest() = default;

 private:
  void MultiprocessParent() {
    ChildTestAddresses addrs = {};
    ASSERT_TRUE(
        LoggingReadFileExactly(ReadPipeHandle(), &addrs, sizeof(addrs)));

    VMAddress exception_info_addr;
    ASSERT_TRUE(LoggingReadFileExactly(
        ReadPipeHandle(), &exception_info_addr, sizeof(exception_info_addr)));

    DirectPtraceConnection connection;
    ASSERT_TRUE(connection.Initialize(ChildProcess()));

    ProcessSnapshotLinux snapshot;
    ASSERT_TRUE(snapshot.Initialize(&connection));
    ASSERT_TRUE(snapshot.InitializeException(exception_info_addr));

    ExpectAnnotations(&snapshot, /* sanitized= */ false);
    ExpectStackData(&snapshot, addrs, /* sanitized= */ false);
    ExpectProcessMemory(&snapshot,
                        addrs.string_address,
                        /* sanitized= */ false);

    auto allowed_annotations = std::make_unique<std::vector<std::string>>();
    allowed_annotations->push_back(kAllowedAnnotationName);
    allowed_annotations->push_back(kAllowedAnnotationNamePattern);

    auto allowed_memory_ranges =
        std::make_unique<std::vector<std::pair<VMAddress, VMAddress>>>();
    allowed_memory_ranges->push_back(
        std::make_pair(addrs.string_address, addrs.string_address + 1));

    ProcessSnapshotSanitized sanitized;
    ASSERT_TRUE(sanitized.Initialize(&snapshot,
                                     std::move(allowed_annotations),
                                     std::move(allowed_memory_ranges),
                                     addrs.module_address,
                                     true));

    ExpectAnnotations(&sanitized, /* sanitized= */ true);
    ExpectStackData(&sanitized, addrs, /* sanitized= */ true);
    ExpectProcessMemory(&sanitized,
                        addrs.string_address,
                        /* sanitized= */ true);

    ProcessSnapshotSanitized screened_snapshot;
    EXPECT_FALSE(screened_snapshot.Initialize(
        &snapshot, nullptr, nullptr, addrs.non_module_address, false));
  }
};

TEST(ProcessSnapshotSanitized, Sanitize) {
  SanitizeTest test;
  test.Run();
}

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