/*
 * Copyright (C) 2018 The Android Open Source Project
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *  * Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *  * Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

#include <android/fdsan.h>

#include <errno.h>
#include <inttypes.h>
#include <signal.h>
#include <stdarg.h>
#include <stdatomic.h>
#include <string.h>
#include <sys/cdefs.h>
#include <sys/mman.h>
#include <sys/syscall.h>
#include <unistd.h>

#include <async_safe/log.h>
#include <platform/bionic/reserved_signals.h>
#include <sys/system_properties.h>

#include "private/bionic_fdtrack.h"
#include "private/bionic_globals.h"
#include "private/bionic_inline_raise.h"
#include "pthread_internal.h"

extern "C" int __close(int fd);
pid_t __get_cached_pid();

static constexpr const char* kFdsanPropertyName = "debug.fdsan";

template<size_t inline_fds>
FdEntry* FdTableImpl<inline_fds>::at(size_t idx) {
  if (idx < inline_fds) {
    return &entries[idx];
  }

  // Try to create the overflow table ourselves.
  FdTableOverflow* local_overflow = atomic_load(&overflow);
  if (__predict_false(!local_overflow)) {
    struct rlimit rlim = { .rlim_max = 32768 };
    getrlimit(RLIMIT_NOFILE, &rlim);
    rlim_t max = rlim.rlim_max;

    if (max == RLIM_INFINITY) {
      // This isn't actually possible (the kernel has a hard limit), but just
      // in case...
      max = 32768;
    }

    if (idx > max) {
      // This can happen if an fd is created and then the rlimit is lowered.
      // In this case, just return nullptr and ignore the fd.
      return nullptr;
    }

    size_t required_count = max - inline_fds;
    size_t required_size = sizeof(FdTableOverflow) + required_count * sizeof(FdEntry);
    size_t aligned_size = __BIONIC_ALIGN(required_size, PAGE_SIZE);
    size_t aligned_count = (aligned_size - sizeof(FdTableOverflow)) / sizeof(FdEntry);

    void* allocation =
        mmap(nullptr, aligned_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
    if (allocation == MAP_FAILED) {
      async_safe_fatal("fdsan: mmap failed: %s", strerror(errno));
    }

    FdTableOverflow* new_overflow = reinterpret_cast<FdTableOverflow*>(allocation);
    new_overflow->len = aligned_count;

    if (atomic_compare_exchange_strong(&overflow, &local_overflow, new_overflow)) {
      local_overflow = new_overflow;
    } else {
      // Someone beat us to it. Deallocate and use theirs.
      munmap(allocation, aligned_size);
    }
  }

  size_t offset = idx - inline_fds;
  if (local_overflow->len <= offset) {
    return nullptr;
  }
  return &local_overflow->entries[offset];
}

void __libc_init_fdsan() {
  constexpr auto default_level = ANDROID_FDSAN_ERROR_LEVEL_FATAL;
  android_fdsan_set_error_level_from_property(default_level);
}

static FdTable& GetFdTable() {
  return __libc_shared_globals()->fd_table;
}

// Exposed to the platform to allow crash_dump to print out the fd table.
extern "C" void* android_fdsan_get_fd_table() {
  return &GetFdTable();
}

static FdEntry* GetFdEntry(int fd) {
  if (fd < 0) {
    return nullptr;
  }

  return GetFdTable().at(fd);
}

__printflike(1, 0) static void fdsan_error(const char* fmt, ...) {
  auto& fd_table = GetFdTable();

  auto error_level = atomic_load(&fd_table.error_level);
  if (error_level == ANDROID_FDSAN_ERROR_LEVEL_DISABLED) {
    return;
  }

  struct {
    size_t size;
    char buf[512];
  } abort_message;

  va_list va;
  va_start(va, fmt);
  if (error_level == ANDROID_FDSAN_ERROR_LEVEL_FATAL) {
    async_safe_fatal_va_list("fdsan", fmt, va);
  } else {
    async_safe_format_log_va_list(ANDROID_LOG_ERROR, "fdsan", fmt, va);
    va_end(va);
    va_start(va, fmt);
    size_t len =
        async_safe_format_buffer_va_list(abort_message.buf, sizeof(abort_message.buf), fmt, va);
    abort_message.size = len + sizeof(size_t);
  }
  va_end(va);

  switch (error_level) {
    case ANDROID_FDSAN_ERROR_LEVEL_WARN_ONCE:
      atomic_compare_exchange_strong(&fd_table.error_level, &error_level,
                                     ANDROID_FDSAN_ERROR_LEVEL_DISABLED);
      __BIONIC_FALLTHROUGH;
    case ANDROID_FDSAN_ERROR_LEVEL_WARN_ALWAYS:
      inline_raise(BIONIC_SIGNAL_DEBUGGER, &abort_message);
      break;

    case ANDROID_FDSAN_ERROR_LEVEL_FATAL:
      inline_raise(SIGABRT);
      abort();

    case ANDROID_FDSAN_ERROR_LEVEL_DISABLED:
      break;
  }
}

uint64_t android_fdsan_create_owner_tag(android_fdsan_owner_type type, uint64_t tag) {
  if (tag == 0) {
    return 0;
  }

  if (__predict_false((type & 0xff) != type)) {
    async_safe_fatal("invalid android_fdsan_owner_type value: %x", type);
  }

  uint64_t result = static_cast<uint64_t>(type) << 56;
  uint64_t mask = (static_cast<uint64_t>(1) << 56) - 1;
  result |= tag & mask;
  return result;
}

const char* android_fdsan_get_tag_type(uint64_t tag) {
  uint64_t type = tag >> 56;
  switch (type) {
    case ANDROID_FDSAN_OWNER_TYPE_FILE:
      return "FILE*";
    case ANDROID_FDSAN_OWNER_TYPE_DIR:
      return "DIR*";
    case ANDROID_FDSAN_OWNER_TYPE_UNIQUE_FD:
      return "unique_fd";
    case ANDROID_FDSAN_OWNER_TYPE_FILEINPUTSTREAM:
      return "FileInputStream";
    case ANDROID_FDSAN_OWNER_TYPE_FILEOUTPUTSTREAM:
      return "FileOutputStream";
    case ANDROID_FDSAN_OWNER_TYPE_RANDOMACCESSFILE:
      return "RandomAccessFile";
    case ANDROID_FDSAN_OWNER_TYPE_PARCELFILEDESCRIPTOR:
      return "ParcelFileDescriptor";
    case ANDROID_FDSAN_OWNER_TYPE_SQLITE:
      return "sqlite";
    case ANDROID_FDSAN_OWNER_TYPE_ART_FDFILE:
      return "ART FdFile";
    case ANDROID_FDSAN_OWNER_TYPE_DATAGRAMSOCKETIMPL:
      return "DatagramSocketImpl";
    case ANDROID_FDSAN_OWNER_TYPE_SOCKETIMPL:
      return "SocketImpl";
    case ANDROID_FDSAN_OWNER_TYPE_ZIPARCHIVE:
      return "ZipArchive";
    case ANDROID_FDSAN_OWNER_TYPE_NATIVE_HANDLE:
      return "native_handle_t";

    case ANDROID_FDSAN_OWNER_TYPE_GENERIC_00:
    default:
      return "native object of unknown type";

    case ANDROID_FDSAN_OWNER_TYPE_GENERIC_FF:
      // If bits 48 to 56 are set, this is a sign-extended generic native pointer
      uint64_t high_bits = tag >> 48;
      if (high_bits == (1 << 16) - 1) {
        return "native object of unknown type";
      }

      return "Java object of unknown type";
  }
}

uint64_t android_fdsan_get_tag_value(uint64_t tag) {
  // Lop off the most significant byte and sign extend.
  return static_cast<uint64_t>(static_cast<int64_t>(tag << 8) >> 8);
}

int android_fdsan_close_with_tag(int fd, uint64_t expected_tag) {
  if (__get_thread()->is_vforked()) {
    return __close(fd);
  }

  FDTRACK_CLOSE(fd);
  FdEntry* fde = GetFdEntry(fd);
  if (!fde) {
    return __close(fd);
  }

  uint64_t tag = expected_tag;
  if (!atomic_compare_exchange_strong(&fde->close_tag, &tag, 0)) {
    const char* expected_type = android_fdsan_get_tag_type(expected_tag);
    uint64_t expected_owner = android_fdsan_get_tag_value(expected_tag);
    const char* actual_type = android_fdsan_get_tag_type(tag);
    uint64_t actual_owner = android_fdsan_get_tag_value(tag);
    if (expected_tag && tag) {
      fdsan_error(
          "attempted to close file descriptor %d, "
          "expected to be owned by %s 0x%" PRIx64 ", actually owned by %s 0x%" PRIx64,
          fd, expected_type, expected_owner, actual_type, actual_owner);
    } else if (expected_tag && !tag) {
      fdsan_error(
          "attempted to close file descriptor %d, "
          "expected to be owned by %s 0x%" PRIx64 ", actually unowned",
          fd, expected_type, expected_owner);
    } else if (!expected_tag && tag) {
      fdsan_error(
          "attempted to close file descriptor %d, "
          "expected to be unowned, actually owned by %s 0x%" PRIx64,
          fd, actual_type, actual_owner);
    } else if (!expected_tag && !tag) {
      // This should never happen: our CAS failed, but expected == actual?
      async_safe_fatal("fdsan atomic_compare_exchange_strong failed unexpectedly while closing");
    }
  }

  int rc = __close(fd);
  // If we were expecting to close with a tag, abort on EBADF.
  if (expected_tag && rc == -1 && errno == EBADF) {
    fdsan_error("double-close of file descriptor %d detected", fd);
  }
  return rc;
}

uint64_t android_fdsan_get_owner_tag(int fd) {
  FdEntry* fde = GetFdEntry(fd);
  if (!fde) {
    return 0;
  }
  return fde->close_tag;
}

void android_fdsan_exchange_owner_tag(int fd, uint64_t expected_tag, uint64_t new_tag) {
  if (__get_thread()->is_vforked()) {
    return;
  }

  FdEntry* fde = GetFdEntry(fd);
  if (!fde) {
    return;
  }

  uint64_t tag = expected_tag;
  if (!atomic_compare_exchange_strong(&fde->close_tag, &tag, new_tag)) {
    if (expected_tag && tag) {
      fdsan_error(
          "failed to exchange ownership of file descriptor: fd %d is "
          "owned by %s 0x%" PRIx64 ", was expected to be owned by %s 0x%" PRIx64,
          fd, android_fdsan_get_tag_type(tag), android_fdsan_get_tag_value(tag),
          android_fdsan_get_tag_type(expected_tag), android_fdsan_get_tag_value(expected_tag));
    } else if (expected_tag && !tag) {
      fdsan_error(
          "failed to exchange ownership of file descriptor: fd %d is "
          "unowned, was expected to be owned by %s 0x%" PRIx64,
          fd, android_fdsan_get_tag_type(expected_tag), android_fdsan_get_tag_value(expected_tag));
    } else if (!expected_tag && tag) {
      fdsan_error(
          "failed to exchange ownership of file descriptor: fd %d is "
          "owned by %s 0x%" PRIx64 ", was expected to be unowned",
          fd, android_fdsan_get_tag_type(tag), android_fdsan_get_tag_value(tag));
    } else if (!expected_tag && !tag) {
      // This should never happen: our CAS failed, but expected == actual?
      async_safe_fatal(
          "fdsan atomic_compare_exchange_strong failed unexpectedly while exchanging owner tag");
    }
  }
}

android_fdsan_error_level android_fdsan_get_error_level() {
  return GetFdTable().error_level;
}

android_fdsan_error_level android_fdsan_set_error_level(android_fdsan_error_level new_level) {
  if (__get_thread()->is_vforked()) {
    return android_fdsan_get_error_level();
  }

  return atomic_exchange(&GetFdTable().error_level, new_level);
}

android_fdsan_error_level android_fdsan_set_error_level_from_property(
    android_fdsan_error_level default_level) {
  const prop_info* pi = __system_property_find(kFdsanPropertyName);
  if (!pi) {
    return android_fdsan_set_error_level(default_level);
  }

  struct callback_data {
    android_fdsan_error_level default_value;
    android_fdsan_error_level result;
  };

  callback_data data;
  data.default_value = default_level;

  __system_property_read_callback(
      pi,
      [](void* arg, const char*, const char* value, uint32_t) {
        callback_data* data = static_cast<callback_data*>(arg);

        if (strcasecmp(value, "1") == 0 || strcasecmp(value, "fatal") == 0) {
          data->result = android_fdsan_set_error_level(ANDROID_FDSAN_ERROR_LEVEL_FATAL);
        } else if (strcasecmp(value, "warn") == 0) {
          data->result = android_fdsan_set_error_level(ANDROID_FDSAN_ERROR_LEVEL_WARN_ALWAYS);
        } else if (strcasecmp(value, "warn_once") == 0) {
          data->result = android_fdsan_set_error_level(ANDROID_FDSAN_ERROR_LEVEL_WARN_ONCE);
        } else {
          if (strlen(value) != 0 && strcasecmp(value, "0") != 0) {
            async_safe_format_log(ANDROID_LOG_ERROR, "libc",
                                  "debug.fdsan set to unknown value '%s', disabling", value);
          }
          data->result = android_fdsan_set_error_level(data->default_value);
        }
      },
      &data);

  return data.result;
}

int close(int fd) {
  int rc = android_fdsan_close_with_tag(fd, 0);
  if (rc == -1 && errno == EINTR) {
    return 0;
  }
  return rc;
}
