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

#include <errno.h>
#include <stdio.h>
#include <string.h>

#include <string>

#include "base/cxx17_backports.h"
#include "base/logging.h"
#include "base/strings/string_number_conversions.h"
#include "util/file/file_io.h"
#include "util/linux/ptrace_broker.h"
#include "util/process/process_memory_linux.h"

namespace crashpad {

namespace {

bool ReceiveAndLogError(int sock, const std::string& operation) {
  ExceptionHandlerProtocol::Errno error;
  if (!LoggingReadFileExactly(sock, &error, sizeof(error))) {
    return false;
  }
  errno = error;
  PLOG(ERROR) << operation;
  return true;
}

bool ReceiveAndLogReadError(int sock, const std::string& operation) {
  PtraceBroker::ReadError err;
  if (!LoggingReadFileExactly(sock, &err, sizeof(err))) {
    return false;
  }
  switch (err) {
    case PtraceBroker::kReadErrorAccessDenied:
      LOG(ERROR) << operation << " access denied";
      return true;
    default:
      if (err <= 0) {
        LOG(ERROR) << operation << " invalid error " << err;
        DCHECK(false);
        return false;
      }
      errno = err;
      PLOG(ERROR) << operation;
      return true;
  }
}

bool AttachImpl(int sock, pid_t tid) {
  PtraceBroker::Request request = {};
  request.type = PtraceBroker::Request::kTypeAttach;
  request.tid = tid;
  if (!LoggingWriteFile(sock, &request, sizeof(request))) {
    return false;
  }

  ExceptionHandlerProtocol::Bool success;
  if (!LoggingReadFileExactly(sock, &success, sizeof(success))) {
    return false;
  }

  if (success != ExceptionHandlerProtocol::kBoolTrue) {
    ReceiveAndLogError(sock, "PtraceBroker Attach");
    return false;
  }

  return true;
}

struct Dirent64 {
  ino64_t d_ino;
  off64_t d_off;
  unsigned short d_reclen;
  unsigned char d_type;
  char d_name[];
};

void ReadDentsAsThreadIDs(char* buffer,
                          size_t size,
                          std::vector<pid_t>* threads) {
  while (size > offsetof(Dirent64, d_name)) {
    auto dirent = reinterpret_cast<Dirent64*>(buffer);
    if (size < dirent->d_reclen) {
      LOG(ERROR) << "short dirent";
      break;
    }
    buffer += dirent->d_reclen;
    size -= dirent->d_reclen;

    const size_t max_name_length =
        dirent->d_reclen - offsetof(Dirent64, d_name);
    size_t name_len = strnlen(dirent->d_name, max_name_length);
    if (name_len >= max_name_length) {
      LOG(ERROR) << "format error";
      break;
    }

    if (strcmp(dirent->d_name, ".") == 0 || strcmp(dirent->d_name, "..") == 0) {
      continue;
    }

    pid_t tid;
    if (!base::StringToInt(dirent->d_name, &tid)) {
      LOG(ERROR) << "format error";
      continue;
    }
    threads->push_back(tid);
  }
  DCHECK_EQ(size, 0u);
}

}  // namespace

PtraceClient::PtraceClient()
    : PtraceConnection(),
      memory_(),
      sock_(kInvalidFileHandle),
      pid_(-1),
      is_64_bit_(false),
      initialized_() {}

PtraceClient::~PtraceClient() {
  if (sock_ != kInvalidFileHandle) {
    PtraceBroker::Request request = {};
    request.type = PtraceBroker::Request::kTypeExit;
    LoggingWriteFile(sock_, &request, sizeof(request));
  }
}

bool PtraceClient::Initialize(int sock, pid_t pid) {
  INITIALIZATION_STATE_SET_INITIALIZING(initialized_);
  sock_ = sock;
  pid_ = pid;

  if (!AttachImpl(sock_, pid_)) {
    return false;
  }

  PtraceBroker::Request request = {};
  request.type = PtraceBroker::Request::kTypeIs64Bit;
  request.tid = pid_;

  if (!LoggingWriteFile(sock_, &request, sizeof(request))) {
    return false;
  }

  ExceptionHandlerProtocol::Bool is_64_bit;
  if (!LoggingReadFileExactly(sock_, &is_64_bit, sizeof(is_64_bit))) {
    return false;
  }
  is_64_bit_ = is_64_bit == ExceptionHandlerProtocol::kBoolTrue;

  INITIALIZATION_STATE_SET_VALID(initialized_);
  return true;
}

pid_t PtraceClient::GetProcessID() {
  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
  return pid_;
}

bool PtraceClient::Attach(pid_t tid) {
  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
  return AttachImpl(sock_, tid);
}

bool PtraceClient::Is64Bit() {
  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
  return is_64_bit_;
}

bool PtraceClient::GetThreadInfo(pid_t tid, ThreadInfo* info) {
  INITIALIZATION_STATE_DCHECK_VALID(initialized_);

  PtraceBroker::Request request = {};
  request.type = PtraceBroker::Request::kTypeGetThreadInfo;
  request.tid = tid;
  if (!LoggingWriteFile(sock_, &request, sizeof(request))) {
    return false;
  }

  PtraceBroker::GetThreadInfoResponse response;
  if (!LoggingReadFileExactly(sock_, &response, sizeof(response))) {
    return false;
  }

  if (response.success == ExceptionHandlerProtocol::kBoolTrue) {
    *info = response.info;
    return true;
  }

  ReceiveAndLogError(sock_, "PtraceBroker GetThreadInfo");
  return false;
}

bool PtraceClient::ReadFileContents(const base::FilePath& path,
                                    std::string* contents) {
  INITIALIZATION_STATE_DCHECK_VALID(initialized_);

  PtraceBroker::Request request = {};
  request.type = PtraceBroker::Request::kTypeReadFile;
  request.path.path_length = path.value().size();

  if (!LoggingWriteFile(sock_, &request, sizeof(request)) ||
      !SendFilePath(path.value().c_str(), request.path.path_length)) {
    return false;
  }

  std::string local_contents;
  int32_t read_result;
  do {
    if (!LoggingReadFileExactly(sock_, &read_result, sizeof(read_result))) {
      return false;
    }

    if (read_result < 0) {
      ReceiveAndLogReadError(sock_, "ReadFileContents");
      return false;
    }

    if (read_result > 0) {
      size_t old_length = local_contents.size();
      local_contents.resize(old_length + read_result);
      if (!LoggingReadFileExactly(
              sock_, &local_contents[old_length], read_result)) {
        return false;
      }
    }
  } while (read_result > 0);

  contents->swap(local_contents);
  return true;
}

ProcessMemoryLinux* PtraceClient::Memory() {
  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
  if (!memory_) {
    memory_ = std::make_unique<ProcessMemoryLinux>(this);
  }
  return memory_.get();
}

bool PtraceClient::Threads(std::vector<pid_t>* threads) {
  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
  DCHECK(threads->empty());

  // If the broker is unable to read thread IDs, fall-back to just the main
  // thread's ID.
  threads->push_back(pid_);

  char path[32];
  snprintf(path, base::size(path), "/proc/%d/task", pid_);

  PtraceBroker::Request request = {};
  request.type = PtraceBroker::Request::kTypeListDirectory;
  request.path.path_length = strlen(path);

  if (!LoggingWriteFile(sock_, &request, sizeof(request)) ||
      !SendFilePath(path, request.path.path_length)) {
    return false;
  }

  std::vector<pid_t> local_threads;
  int32_t read_result;
  do {
    if (!LoggingReadFileExactly(sock_, &read_result, sizeof(read_result))) {
      return false;
    }

    if (read_result < 0) {
      return ReceiveAndLogReadError(sock_, "Threads");
    }

    if (read_result > 0) {
      auto buffer = std::make_unique<char[]>(read_result);
      if (!LoggingReadFileExactly(sock_, buffer.get(), read_result)) {
        return false;
      }

      ReadDentsAsThreadIDs(buffer.get(), read_result, &local_threads);
    }
  } while (read_result > 0);

  threads->swap(local_threads);
  return true;
}

ssize_t PtraceClient::ReadUpTo(VMAddress address, size_t size, void* buffer) {
  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
  char* buffer_c = reinterpret_cast<char*>(buffer);

  PtraceBroker::Request request = {};
  request.type = PtraceBroker::Request::kTypeReadMemory;
  request.tid = pid_;
  request.iov.base = address;
  request.iov.size = size;

  if (!LoggingWriteFile(sock_, &request, sizeof(request))) {
    return false;
  }

  ssize_t total_read = 0;
  while (size > 0) {
    int32_t bytes_read;
    if (!LoggingReadFileExactly(sock_, &bytes_read, sizeof(bytes_read))) {
      return -1;
    }

    if (bytes_read < 0) {
      ReceiveAndLogReadError(sock_, "PtraceBroker ReadMemory");
      return -1;
    }

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

    if (!LoggingReadFileExactly(sock_, buffer_c, bytes_read)) {
      return -1;
    }

    size -= bytes_read;
    buffer_c += bytes_read;
    total_read += bytes_read;
  }

  return total_read;
}

bool PtraceClient::SendFilePath(const char* path, size_t length) {
  if (!LoggingWriteFile(sock_, path, length)) {
    return false;
  }

  PtraceBroker::OpenResult result;
  if (!LoggingReadFileExactly(sock_, &result, sizeof(result))) {
    return false;
  }

  switch (result) {
    case PtraceBroker::kOpenResultAccessDenied:
      LOG(ERROR) << "Broker Open: access denied";
      return false;

    case PtraceBroker::kOpenResultTooLong:
      LOG(ERROR) << "Broker Open: path too long";
      return false;

    case PtraceBroker::kOpenResultSuccess:
      return true;

    default:
      if (result < 0) {
        LOG(ERROR) << "Broker Open: invalid result " << result;
        DCHECK(false);
      } else {
        errno = result;
        PLOG(ERROR) << "Broker Open";
      }
      return false;
  }
}

}  // namespace crashpad
