// 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 <syscall.h>
#include <unistd.h>

#include <algorithm>

#include "base/logging.h"
#include "base/posix/eintr_wrapper.h"
#include "util/misc/memory_sanitizer.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

PtraceBroker::PtraceBroker(int sock, pid_t pid, bool is_64_bit)
    : ptracer_(is_64_bit, /* can_log= */ false),
      file_root_(file_root_buffer_),
      attachments_(nullptr),
      attach_count_(0),
      attach_capacity_(0),
      memory_file_(),
      sock_(sock),
      memory_pid_(pid),
      tried_opening_mem_file_(false) {
  AllocateAttachments();

  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() {
  int result = RunImpl();
  ReleaseAttachments();
  return result;
}

bool PtraceBroker::AllocateAttachments() {
  constexpr size_t page_size = 4096;
  constexpr size_t alloc_size =
      (sizeof(ScopedPtraceAttach) + page_size - 1) & ~(page_size - 1);
  void* alloc = sbrk(alloc_size);
  if (reinterpret_cast<intptr_t>(alloc) == -1) {
    return false;
  }

  if (attachments_ == nullptr) {
    attachments_ = reinterpret_cast<ScopedPtraceAttach*>(alloc);
  }

  attach_capacity_ += alloc_size / sizeof(ScopedPtraceAttach);
  return true;
}

void PtraceBroker::ReleaseAttachments() {
  for (size_t index = 0; index < attach_count_; ++index) {
    attachments_[index].Reset();
  }
}

int PtraceBroker::RunImpl() {
  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: {
        ScopedPtraceAttach* attach;
        ScopedPtraceAttach stack_attach;
        bool attach_on_stack = false;

        if (attach_capacity_ > attach_count_ || AllocateAttachments()) {
          attach = new (&attachments_[attach_count_]) ScopedPtraceAttach;
        } else {
          attach = &stack_attach;
          attach_on_stack = true;
        }

        ExceptionHandlerProtocol::Bool status =
            ExceptionHandlerProtocol::kBoolFalse;
        if (attach->ResetAttach(request.tid)) {
          status = ExceptionHandlerProtocol::kBoolTrue;
          if (!attach_on_stack) {
            ++attach_count_;
          }
        }

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

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

        if (attach_on_stack && status == ExceptionHandlerProtocol::kBoolTrue) {
          return RunImpl();
        }
        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
