// Copyright 2019 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/socket.h"

#include <unistd.h>

#include "base/logging.h"
#include "base/posix/eintr_wrapper.h"
#include "third_party/lss/lss.h"

namespace crashpad {

// static
bool UnixCredentialSocket::CreateCredentialSocketpair(ScopedFileHandle* sock1,
                                                      ScopedFileHandle* sock2) {
  int socks[2];
  if (socketpair(AF_UNIX, SOCK_SEQPACKET, 0, socks) != 0) {
    PLOG(ERROR) << "socketpair";
    return false;
  }
  ScopedFileHandle local_sock1(socks[0]);
  ScopedFileHandle local_sock2(socks[1]);

  int optval = 1;
  socklen_t optlen = sizeof(optval);
  if (setsockopt(local_sock1.get(), SOL_SOCKET, SO_PASSCRED, &optval, optlen) !=
          0 ||
      setsockopt(local_sock2.get(), SOL_SOCKET, SO_PASSCRED, &optval, optlen) !=
          0) {
    PLOG(ERROR) << "setsockopt";
    return false;
  }

  sock1->swap(local_sock1);
  sock2->swap(local_sock2);
  return true;
}

constexpr size_t UnixCredentialSocket::kMaxSendRecvMsgFDs = 4;

// static
int UnixCredentialSocket::SendMsg(int fd,
                                  const void* buf,
                                  size_t buf_size,
                                  const int* fds,
                                  size_t fd_count) {
  // This function is intended to be used after a crash. fds is an integer
  // array instead of a vector to avoid forcing callers to provide a vector,
  // which they would have to create prior to the crash.
  if (fds && fd_count > kMaxSendRecvMsgFDs) {
    DLOG(ERROR) << "too many fds " << fd_count;
    return EINVAL;
  }

  iovec iov;
  iov.iov_base = const_cast<void*>(buf);
  iov.iov_len = buf_size;

  msghdr msg = {};
  msg.msg_iov = &iov;
  msg.msg_iovlen = 1;

  char cmsg_buf[CMSG_SPACE(sizeof(int) * kMaxSendRecvMsgFDs)];
  if (fds) {
    msg.msg_control = cmsg_buf;
    msg.msg_controllen = CMSG_SPACE(sizeof(int) * fd_count);

    cmsghdr* cmsg = CMSG_FIRSTHDR(&msg);
    DCHECK(cmsg);

    cmsg->cmsg_level = SOL_SOCKET;
    cmsg->cmsg_type = SCM_RIGHTS;
    cmsg->cmsg_len = CMSG_LEN(sizeof(int) * fd_count);
    memcpy(CMSG_DATA(cmsg), fds, sizeof(int) * fd_count);
  }

  // TODO(jperaza): Use sys_sendmsg when lss has macros for maniuplating control
  // messages. https://crbug.com/crashpad/265
  if (HANDLE_EINTR(sendmsg(fd, &msg, MSG_NOSIGNAL)) < 0) {
    DPLOG(ERROR) << "sendmsg";
    return errno;
  }
  return 0;
}

// static
bool UnixCredentialSocket::RecvMsg(int fd,
                                   void* buf,
                                   size_t buf_size,
                                   ucred* creds,
                                   std::vector<ScopedFileHandle>* fds) {
  iovec iov;
  iov.iov_base = buf;
  iov.iov_len = buf_size;

  msghdr msg = {};
  msg.msg_iov = &iov;
  msg.msg_iovlen = 1;

  char cmsg_buf[CMSG_SPACE(sizeof(ucred)) +
                CMSG_SPACE(sizeof(int) * kMaxSendRecvMsgFDs)];
  msg.msg_control = cmsg_buf;
  msg.msg_controllen = sizeof(cmsg_buf);

  int res = HANDLE_EINTR(recvmsg(fd, &msg, 0));
  if (res < 0) {
    PLOG(ERROR) << "recvmsg";
    return false;
  }

  ucred* local_creds = nullptr;
  std::vector<ScopedFileHandle> local_fds;
  bool unhandled_cmsgs = false;

  for (cmsghdr* cmsg = CMSG_FIRSTHDR(&msg);
       cmsg;
       cmsg = CMSG_NXTHDR(&msg, cmsg)) {
    if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS) {
      int* fdp = reinterpret_cast<int*>(CMSG_DATA(cmsg));
      size_t fd_count = (reinterpret_cast<char*>(cmsg) + cmsg->cmsg_len -
                         reinterpret_cast<char*>(fdp)) /
                        sizeof(int);
      DCHECK_LE(fd_count, kMaxSendRecvMsgFDs);
      for (size_t index = 0; index < fd_count; ++index) {
        if (fds) {
          local_fds.emplace_back(fdp[index]);
        } else if (IGNORE_EINTR(close(fdp[index])) != 0) {
          PLOG(ERROR) << "close";
        }
      }
      continue;
    }

    if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_CREDENTIALS) {
      DCHECK(!local_creds);
      local_creds = reinterpret_cast<ucred*>(CMSG_DATA(cmsg));
      continue;
    }

    LOG(ERROR) << "unhandled cmsg " << cmsg->cmsg_level << ", "
               << cmsg->cmsg_type;
    unhandled_cmsgs = true;
  }

  if (unhandled_cmsgs) {
    return false;
  }

  if (msg.msg_name != nullptr || msg.msg_namelen != 0) {
    LOG(ERROR) << "unexpected msg name";
    return false;
  }

  if (msg.msg_flags & MSG_TRUNC || msg.msg_flags & MSG_CTRUNC) {
    LOG(ERROR) << "truncated msg";
    return false;
  }

  // Credentials are missing from the message either when the recv socket wasn't
  // configured with SO_PASSCRED or when all sending sockets have been closed.
  // In the latter case, res == 0. This case is also indistinguishable from an
  // empty message sent to a recv socket which hasn't set SO_PASSCRED.
  if (!local_creds) {
    LOG_IF(ERROR, res != 0) << "missing credentials";
    return false;
  }

  if (static_cast<size_t>(res) != buf_size) {
    LOG(ERROR) << "incorrect payload size " << res;
    return false;
  }

  *creds = *local_creds;
  if (fds) {
    fds->swap(local_fds);
  }
  return true;
}

}  // namespace crashpad
