// Copyright 2016 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "authpolicy/platform_helper.h"

#include <fcntl.h>
#include <linux/capability.h>
#include <poll.h>
#include <sys/capability.h>
#include <sys/prctl.h>
#include <sysexits.h>
#include <cstdint>

#include <sys/ioctl.h>

#include <algorithm>
#include <vector>

#include <base/files/file_path.h>
#include <base/files/file_util.h>

namespace authpolicy {

namespace {

// Size limit on the total number of bytes to read from a pipe.
const size_t kMaxReadSize = 16 * 1024 * 1024;  // 16 MB
// The size of the buffer used to read from a pipe.
const size_t kBufferSize = PIPE_BUF;  // ~4 Kb on my system
// Timeout used for poll()ing pipes.
const int kPollTimeoutMilliseconds = 30000;

// Creates a non-blocking local pipe and returns the read and the write end.
bool CreatePipe(base::ScopedFD* pipe_read_end, base::ScopedFD* pipe_write_end) {
  int pipe_fd[2];
  if (!base::CreateLocalNonBlockingPipe(pipe_fd)) {
    LOG(ERROR) << "Failed to create pipe";
    return false;
  }
  pipe_read_end->reset(pipe_fd[0]);
  pipe_write_end->reset(pipe_fd[1]);
  return true;
}

// Reads up to |kBufferSize| bytes from the file descriptor |src_fd| and appends
// them to |dst_str|. Sets |done| to true iff the whole file was read
// successfully. Might block if |src_fd| is a blocking pipe. Returns false on
// error.
bool ReadPipe(int src_fd, std::string* dst_str, bool* done) {
  *done = false;
  char buffer[kBufferSize];
  const ssize_t bytes_read = HANDLE_EINTR(read(src_fd, buffer, kBufferSize));
  if (bytes_read < 0 && errno != EAGAIN && errno != EWOULDBLOCK) {
    PLOG(ERROR) << "read() from fd " << src_fd << " failed";
    return false;
  }
  if (bytes_read == 0)
    *done = true;
  else if (bytes_read > 0)
    dst_str->append(buffer, bytes_read);
  return true;
}

// Splices (copies) as much as possible data from the file descriptor |src_fd|
// to |dst_fd|. Sets |done| to true iff the whole |src_fd| file was spliced
// successfully. Might block if |src_fd| or |dst_fd| are blocking pipes. Returns
// false on error.
bool SplicePipe(int dst_fd, int src_fd, bool* done) {
  *done = false;
  const int flags = SPLICE_F_NONBLOCK | SPLICE_F_MORE | SPLICE_F_MOVE;
  const ssize_t bytes_written =
      HANDLE_EINTR(splice(src_fd, nullptr, dst_fd, nullptr, INT_MAX, flags));
  if (bytes_written < 0 && errno != EAGAIN && errno != EWOULDBLOCK) {
    PLOG(ERROR) << "splice() " << src_fd << " failed";
    return false;
  }
  if (bytes_written == 0)
    *done = true;
  return true;
}

// Writes as much as possible from |src_str|, beginning at position |src_pos|,
// to the file descriptor |dst_fd|. Sets |done| to true iff the whole string
// was written successfully. Handles blocking |dst_fd|. Returns false on error.
// On success, increases |src_pos| by the number of bytes written.
bool WritePipe(int dst_fd,
               const std::string& src_str,
               size_t* src_pos,
               bool* done) {
  DCHECK_LE(*src_pos, src_str.size());
  // Writing 0 bytes might not be well defined, so early out in this case.
  if (*src_pos == src_str.size()) {
    *done = true;
    return true;
  }
  *done = false;
  const ssize_t bytes_written = HANDLE_EINTR(
      write(dst_fd, src_str.data() + *src_pos, src_str.size() - *src_pos));
  if (bytes_written < 0 && errno != EAGAIN && errno != EWOULDBLOCK) {
    PLOG(ERROR) << "write() to " << dst_fd << " failed";
    return false;
  }
  if (bytes_written > 0) {
    *src_pos += bytes_written;
    DCHECK_LE(*src_pos, src_str.size());
  }
  if (*src_pos == src_str.size())
    *done = true;
  return true;
}

}  // namespace

bool ReadPipeToString(int fd, std::string* out) {
  char buffer[kBufferSize];
  size_t total_read = 0;
  while (total_read < kMaxReadSize) {
    const ssize_t bytes_read = HANDLE_EINTR(
        read(fd, buffer, std::min(kBufferSize, kMaxReadSize - total_read)));
    if (bytes_read < 0)
      return false;
    if (bytes_read == 0)
      return true;
    total_read += bytes_read;
    out->append(buffer, bytes_read);
  }

  // Size limit hit. Do one more read to check if the file size is exactly
  // kMaxReadSize bytes.
  return HANDLE_EINTR(read(fd, buffer, 1)) == 0;
}

base::ScopedFD ReadFileToPipe(const base::FilePath& path) {
  base::ScopedFD pipe_read_end, pipe_write_end;
  if (!authpolicy::CreatePipe(&pipe_read_end, &pipe_write_end))
    return base::ScopedFD();

  bool done = false;
  base::ScopedFD file_fd(open(path.value().c_str(), O_RDONLY | O_NONBLOCK));
  if (!file_fd.is_valid()) {
    PLOG(ERROR) << "Failed to open file '" << path.value() << "'";
    return base::ScopedFD();
  }
  // Splice twice. The first splice reads the whole file, but doesn't set
  // |done|. The second splice sets |done| to true.
  if (!SplicePipe(pipe_write_end.get(), file_fd.get(), &done) ||
      !SplicePipe(pipe_write_end.get(), file_fd.get(), &done)) {
    return base::ScopedFD();
  }
  if (!done) {
    LOG(ERROR) << "Failed to splice the whole pipe in one go";
    return base::ScopedFD();
  }
  return pipe_read_end;
}

bool PerformPipeIo(int stdin_fd,
                   int stdout_fd,
                   int stderr_fd,
                   int input_fd,
                   const std::string& input_str,
                   std::string* stdout,
                   std::string* stderr) {
  // Make sure pipes get closed when exiting the scope.
  base::ScopedFD stdin_scoped_fd(stdin_fd);
  base::ScopedFD stdout_scoped_fd(stdout_fd);
  base::ScopedFD stderr_scoped_fd(stderr_fd);

  size_t input_str_pos = 0;
  bool splicing_input_fd = (input_fd != -1);

  while (stdin_scoped_fd.is_valid() || stdout_scoped_fd.is_valid() ||
         stderr_scoped_fd.is_valid()) {
    // Note that closed files (*_scoped_fd.get() == -1) are ignored.
    const int kIndexStdin = 0, kIndexStdout = 1, kIndexStderr = 2;
    const char* kPipeNames[] = {"stdin", "stdout", "stderr"};
    const int kPollCount = 3;

    struct pollfd poll_fds[kPollCount];
    poll_fds[kIndexStdin] = {stdin_scoped_fd.get(), POLLOUT, 0};
    poll_fds[kIndexStdout] = {stdout_scoped_fd.get(), POLLIN, 0};
    poll_fds[kIndexStderr] = {stderr_scoped_fd.get(), POLLIN, 0};

    const int poll_result =
        HANDLE_EINTR(poll(poll_fds, kPollCount, kPollTimeoutMilliseconds));
    if (poll_result < 0) {
      PLOG(ERROR) << "poll() failed";
      return false;
    }
    // Treat POLLNVAL as an error for all pipes.
    for (int n : {kIndexStdin, kIndexStdout, kIndexStderr}) {
      if ((poll_fds[n].revents & POLLNVAL) == 0)
        continue;
      LOG(ERROR) << "POLLNVAL for " << kPipeNames[n];
      return false;
    }
    // Special case: POLLERR can legitimately happen on the child process'
    // stdin if it already exited. Do not treat that as an error unless
    // there was data the parent process wanted to send to the child
    // process.
    for (int n : {kIndexStdin, kIndexStdout, kIndexStderr}) {
      if ((poll_fds[n].revents & POLLERR) == 0)
        continue;
      if (n == kIndexStdin) {
        if (!splicing_input_fd && input_str.size() == input_str_pos) {
          VLOG(1) << "Ignoring POLLERR for stdin.";
          stdin_scoped_fd.reset();
          continue;
        }

        LOG(ERROR) << "Child process stdin closed due to POLLERR when "
                   << "there was still data to write.";
      }
      LOG(ERROR) << "POLLERR for " << kPipeNames[n];
      return false;
    }

    // Should only happen on timeout. Log a warning here, so we get at least a
    // log if the process is stale.
    if (poll_result == 0)
      LOG(WARNING) << "poll() timed out. Process might be stale.";

    // Read stdout to the stdout string.
    if (stdout_scoped_fd.is_valid() &&
        (poll_fds[kIndexStdout].revents & (POLLIN | POLLHUP))) {
      bool done = false;
      if (!ReadPipe(stdout_scoped_fd.get(), stdout, &done))
        return false;
      else if (done)
        stdout_scoped_fd.reset();
    }

    // Read stderr to the stderr string.
    if (stderr_scoped_fd.is_valid() &&
        (poll_fds[kIndexStderr].revents & (POLLIN | POLLHUP))) {
      bool done = false;
      if (!ReadPipe(stderr_scoped_fd.get(), stderr, &done))
        return false;
      else if (done)
        stderr_scoped_fd.reset();
    }

    if (stdin_scoped_fd.is_valid() && poll_fds[kIndexStdin].revents & POLLOUT) {
      bool done = false;
      if (splicing_input_fd) {
        // Splice input_fd to stdin_scoped_fd.
        if (!SplicePipe(stdin_scoped_fd.get(), input_fd, &done))
          return false;
        else if (done)
          splicing_input_fd = false;
      } else {
        // Write input_str to stdin_scoped_fd.
        if (!WritePipe(stdin_scoped_fd.get(), input_str, &input_str_pos, &done))
          return false;
        else if (done)
          stdin_scoped_fd.reset();
      }
    }

    // Check size limits.
    if (stdout->size() > kMaxReadSize || stderr->size() > kMaxReadSize) {
      LOG(ERROR) << "Hit size limit";
      return false;
    }
  }
  return true;
}

base::ScopedFD DuplicatePipe(int src_fd) {
  base::ScopedFD pipe_read_end, pipe_write_end;
  if (!authpolicy::CreatePipe(&pipe_read_end, &pipe_write_end))
    return base::ScopedFD();

  if (HANDLE_EINTR(
          tee(src_fd, pipe_write_end.get(), INT_MAX, SPLICE_F_NONBLOCK)) <= 0) {
    PLOG(ERROR) << "Failed to duplicate pipe";
    return base::ScopedFD();
  }
  return pipe_read_end;
}

base::ScopedFD WriteStringToPipe(const std::string& str) {
  base::ScopedFD pipe_read_end, pipe_write_end;
  if (!authpolicy::CreatePipe(&pipe_read_end, &pipe_write_end))
    return base::ScopedFD();

  if (!base::WriteFileDescriptor(pipe_write_end.get(), str.data(),
                                 str.size())) {
    LOG(ERROR) << "Failed to write string to pipe";
    return base::ScopedFD();
  }
  return pipe_read_end;
}

base::ScopedFD WriteStringAndPipeToPipe(const std::string& str, int fd) {
  base::ScopedFD pipe_read_end, pipe_write_end;
  if (!authpolicy::CreatePipe(&pipe_read_end, &pipe_write_end))
    return base::ScopedFD();

  if (!base::WriteFileDescriptor(pipe_write_end.get(), str.data(),
                                 str.size())) {
    LOG(ERROR) << "Failed to write string to pipe";
    return base::ScopedFD();
  }

  if (HANDLE_EINTR(tee(fd, pipe_write_end.get(), INT_MAX, SPLICE_F_NONBLOCK)) <=
      0) {
    PLOG(ERROR) << "Failed to duplicate pipe";
    return base::ScopedFD();
  }
  return pipe_read_end;
}

uid_t GetEffectiveUserId() {
  return geteuid();
}

bool SetSavedUserAndDropCaps(uid_t saved_uid) {
  // Only set the saved UID, keep the other ones.
  if (setresuid(-1, -1, saved_uid)) {
    PLOG(ERROR) << "setresuid failed";
    return false;
  }

  // Drop capabilities from bounding set.
  if (prctl(PR_CAPBSET_DROP, CAP_SETUID) ||
      prctl(PR_CAPBSET_DROP, CAP_SETPCAP)) {
    PLOG(ERROR) << "Failed to drop caps from bounding set";
    return false;
  }

  // Clear capabilities.
  cap_t caps = cap_get_proc();
  if (!caps || cap_clear_flag(caps, CAP_INHERITABLE) ||
      cap_clear_flag(caps, CAP_EFFECTIVE) ||
      cap_clear_flag(caps, CAP_PERMITTED) || cap_set_proc(caps)) {
    PLOG(ERROR) << "Clearing caps failed";
    return false;
  }

  return true;
}

ScopedSwitchToSavedUid::ScopedSwitchToSavedUid() {
  uid_t real_uid, effective_uid;
  CHECK_EQ(0, getresuid(&real_uid, &effective_uid, &saved_uid_));
  CHECK(real_uid == effective_uid);
  real_and_effective_uid_ = real_uid;
  CHECK_EQ(0, setresuid(saved_uid_, saved_uid_, real_and_effective_uid_));
}

ScopedSwitchToSavedUid::~ScopedSwitchToSavedUid() {
  CHECK_EQ(0, setresuid(real_and_effective_uid_, real_and_effective_uid_,
                        saved_uid_));
}

}  // namespace authpolicy
