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

#include <fcntl.h>
#include <limits.h>
#include <string.h>
#include <sys/mman.h>
#include <syscall.h>
#include <unistd.h>

#include <algorithm>

#include "base/check_op.h"
#include "base/memory/page_size.h"
#include "base/posix/eintr_wrapper.h"
#include "third_party/lss/lss.h"
#include "util/linux/scoped_ptrace_attach.h"
#include "util/misc/memory_sanitizer.h"
#include "util/posix/scoped_mmap.h"

namespace crashpad {

namespace {

size_t FormatPID(char* buffer, pid_t pid) {
  DCHECK_GE(pid, 0);

  char pid_buf[16];
  size_t length = 0;
  do {
    DCHECK_LT(length, sizeof(pid_buf));

    pid_buf[length] = '0' + pid % 10;
    pid /= 10;
    ++length;
  } while (pid > 0);

  for (size_t index = 0; index < length; ++index) {
    buffer[index] = pid_buf[length - index - 1];
  }

  return length;
}

}  // namespace

class PtraceBroker::AttachmentsArray {
 public:
  AttachmentsArray() : allocation_(false), attach_count_(0) {}

  ~AttachmentsArray() {
    for (size_t index = 0; index < attach_count_; ++index) {
      PtraceDetach(Attachments()[index], false);
    }
  }

  bool Initialize() {
    return allocation_.ResetMmap(nullptr,
                                 base::GetPageSize(),
                                 PROT_READ | PROT_WRITE,
                                 MAP_PRIVATE | MAP_ANONYMOUS,
                                 -1,
                                 0);
  }

  bool Attach(pid_t pid) {
    pid_t* attach = AllocateAttachment();
    if (!attach || !PtraceAttach(pid, false)) {
      return false;
    }

    *attach = pid;
    return true;
  }

 private:
  pid_t* AllocateAttachment() {
    if (attach_count_ >= (allocation_.len() / sizeof(pid_t))) {
      return nullptr;
    }
    return &Attachments()[attach_count_++];
  }

  pid_t* Attachments() { return allocation_.addr_as<pid_t*>(); }

  ScopedMmap allocation_;
  size_t attach_count_;

  DISALLOW_COPY_AND_ASSIGN(AttachmentsArray);
};

PtraceBroker::PtraceBroker(int sock, pid_t pid, bool is_64_bit)
    : ptracer_(is_64_bit, /* can_log= */ false),
      file_root_(file_root_buffer_),
      memory_file_(),
      sock_(sock),
      memory_pid_(pid),
      tried_opening_mem_file_(false) {
  static constexpr char kProc[] = "/proc/";
  size_t root_length = strlen(kProc);
  memcpy(file_root_buffer_, kProc, root_length);

  if (pid >= 0) {
    root_length += FormatPID(file_root_buffer_ + root_length, pid);
    DCHECK_LT(root_length, sizeof(file_root_buffer_));
    file_root_buffer_[root_length] = '/';
    ++root_length;
  }

  DCHECK_LT(root_length, sizeof(file_root_buffer_));
  file_root_buffer_[root_length] = '\0';
}

PtraceBroker::~PtraceBroker() = default;

void PtraceBroker::SetFileRoot(const char* new_root) {
  DCHECK_EQ(new_root[strlen(new_root) - 1], '/');
  memory_pid_ = -1;
  file_root_ = new_root;
}

int PtraceBroker::Run() {
  AttachmentsArray attachments;
  attachments.Initialize();
  return RunImpl(&attachments);
}

int PtraceBroker::RunImpl(AttachmentsArray* attachments) {
  while (true) {
    Request request = {};
    if (!ReadFileExactly(sock_, &request, sizeof(request))) {
      return errno;
    }

    if (request.version != Request::kVersion) {
      return EINVAL;
    }

    switch (request.type) {
      case Request::kTypeAttach: {
        ExceptionHandlerProtocol::Bool status =
            attachments->Attach(request.tid)
                ? ExceptionHandlerProtocol::kBoolTrue
                : ExceptionHandlerProtocol::kBoolFalse;

        if (!WriteFile(sock_, &status, sizeof(status))) {
          return errno;
        }

        if (status == ExceptionHandlerProtocol::kBoolFalse) {
          ExceptionHandlerProtocol::Errno error = errno;
          if (!WriteFile(sock_, &error, sizeof(error))) {
            return errno;
          }
        }

        continue;
      }

      case Request::kTypeIs64Bit: {
        ExceptionHandlerProtocol::Bool is_64_bit =
            ptracer_.Is64Bit() ? ExceptionHandlerProtocol::kBoolTrue
                               : ExceptionHandlerProtocol::kBoolFalse;
        if (!WriteFile(sock_, &is_64_bit, sizeof(is_64_bit))) {
          return errno;
        }
        continue;
      }

      case Request::kTypeGetThreadInfo: {
        GetThreadInfoResponse response;
        response.success = ptracer_.GetThreadInfo(request.tid, &response.info)
                               ? ExceptionHandlerProtocol::kBoolTrue
                               : ExceptionHandlerProtocol::kBoolFalse;

        if (!WriteFile(sock_, &response, sizeof(response))) {
          return errno;
        }

        if (response.success == ExceptionHandlerProtocol::kBoolFalse) {
          ExceptionHandlerProtocol::Errno error = errno;
          if (!WriteFile(sock_, &error, sizeof(error))) {
            return errno;
          }
        }
        continue;
      }

      case Request::kTypeReadFile: {
        ScopedFileHandle handle;
        int result = ReceiveAndOpenFilePath(request.path.path_length,
                                            /* is_directory= */ false,
                                            &handle);
        if (result != 0) {
          return result;
        }

        if (!handle.is_valid()) {
          continue;
        }

        result = SendFileContents(handle.get());
        if (result != 0) {
          return result;
        }
        continue;
      }

      case Request::kTypeReadMemory: {
        int result =
            SendMemory(request.tid, request.iov.base, request.iov.size);
        if (result != 0) {
          return result;
        }
        continue;
      }

      case Request::kTypeListDirectory: {
        ScopedFileHandle handle;
        int result = ReceiveAndOpenFilePath(request.path.path_length,
                                            /* is_directory= */ true,
                                            &handle);
        if (result != 0) {
          return result;
        }

        if (!handle.is_valid()) {
          continue;
        }

        result = SendDirectory(handle.get());
        if (result != 0) {
          return result;
        }
        continue;
      }

      case Request::kTypeExit:
        return 0;
    }

    DCHECK(false);
    return EINVAL;
  }
}

int PtraceBroker::SendError(ExceptionHandlerProtocol::Errno err) {
  return WriteFile(sock_, &err, sizeof(err)) ? 0 : errno;
}

int PtraceBroker::SendReadError(ReadError error) {
  int32_t rv = -1;
  return WriteFile(sock_, &rv, sizeof(rv)) &&
                 WriteFile(sock_, &error, sizeof(error))
             ? 0
             : errno;
}

int PtraceBroker::SendOpenResult(OpenResult result) {
  return WriteFile(sock_, &result, sizeof(result)) ? 0 : errno;
}

int PtraceBroker::SendFileContents(FileHandle handle) {
  char buffer[4096];
  int32_t rv;
  do {
    rv = ReadFile(handle, buffer, sizeof(buffer));

    if (rv < 0) {
      return SendReadError(static_cast<ReadError>(errno));
    }

    if (!WriteFile(sock_, &rv, sizeof(rv))) {
      return errno;
    }

    if (rv > 0) {
      if (!WriteFile(sock_, buffer, static_cast<size_t>(rv))) {
        return errno;
      }
    }
  } while (rv > 0);

  return 0;
}

void PtraceBroker::TryOpeningMemFile() {
  if (tried_opening_mem_file_) {
    return;
  }
  tried_opening_mem_file_ = true;

  if (memory_pid_ < 0) {
    return;
  }

  char mem_path[32];
  size_t root_length = strlen(file_root_buffer_);
  static constexpr char kMem[] = "mem";

  DCHECK_LT(root_length + strlen(kMem) + 1, sizeof(mem_path));
  memcpy(mem_path, file_root_buffer_, root_length);
  // Include the trailing NUL.
  memcpy(mem_path + root_length, kMem, strlen(kMem) + 1);
  memory_file_.reset(
      HANDLE_EINTR(open(mem_path, O_RDONLY | O_CLOEXEC | O_NOCTTY)));
}

int PtraceBroker::SendMemory(pid_t pid, VMAddress address, VMSize size) {
  if (memory_pid_ >= 0 && pid != memory_pid_) {
    return SendReadError(kReadErrorAccessDenied);
  }

  TryOpeningMemFile();
  auto read_memory = [this, pid](VMAddress address, size_t size, char* buffer) {
    return this->memory_file_.is_valid()
               ? HANDLE_EINTR(
                     pread64(this->memory_file_.get(), buffer, size, address))
               : this->ptracer_.ReadUpTo(pid, address, size, buffer);
  };

  char buffer[4096];
  while (size > 0) {
    size_t to_read = std::min(size, VMSize{sizeof(buffer)});

    int32_t bytes_read = read_memory(address, to_read, buffer);

    if (bytes_read < 0) {
      return SendReadError(static_cast<ReadError>(errno));
    }

    if (!WriteFile(sock_, &bytes_read, sizeof(bytes_read))) {
      return errno;
    }

    if (bytes_read == 0) {
      return 0;
    }

    if (!WriteFile(sock_, buffer, bytes_read)) {
      return errno;
    }

    size -= bytes_read;
    address += bytes_read;
  }
  return 0;
}

#if defined(MEMORY_SANITIZER)
// MSan doesn't intercept syscall() and doesn't see that buffer is initialized.
__attribute__((no_sanitize("memory")))
#endif  // defined(MEMORY_SANITIZER)
int PtraceBroker::SendDirectory(FileHandle handle) {
  char buffer[4096];
  int rv;
  do {
    rv = syscall(SYS_getdents64, handle, buffer, sizeof(buffer));

    if (rv < 0) {
      return SendReadError(static_cast<ReadError>(errno));
    }

    if (!WriteFile(sock_, &rv, sizeof(rv))) {
      return errno;
    }

    if (rv > 0) {
      if (!WriteFile(sock_, buffer, static_cast<size_t>(rv))) {
        return errno;
      }
    }
  } while (rv > 0);

  return 0;
}

int PtraceBroker::ReceiveAndOpenFilePath(VMSize path_length,
                                         bool is_directory,
                                         ScopedFileHandle* handle) {
  char path[std::max(4096, PATH_MAX)];

  if (path_length >= sizeof(path)) {
    return SendOpenResult(kOpenResultTooLong);
  }

  if (!ReadFileExactly(sock_, path, path_length)) {
    return errno;
  }
  path[path_length] = '\0';

  if (strncmp(path, file_root_, strlen(file_root_)) != 0) {
    return SendOpenResult(kOpenResultAccessDenied);
  }

  int flags = O_RDONLY | O_CLOEXEC | O_NOCTTY;
  if (is_directory) {
    flags |= O_DIRECTORY;
  }
  ScopedFileHandle local_handle(HANDLE_EINTR(open(path, flags)));
  if (!local_handle.is_valid()) {
    return SendOpenResult(static_cast<OpenResult>(errno));
  }

  handle->reset(local_handle.release());
  return SendOpenResult(kOpenResultSuccess);
}

}  // namespace crashpad
