/*
 * Copyright (C) 2008 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 "libc_init_common.h"

#include <async_safe/log.h>
#include <elf.h>
#include <errno.h>
#include <fcntl.h>
#include <inttypes.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/auxv.h>
#include <sys/personality.h>
#include <sys/time.h>
#include <unistd.h>

#include "heap_tagging.h"
#include "private/ScopedPthreadMutexLocker.h"
#include "private/WriteProtected.h"
#include "private/bionic_defs.h"
#include "private/bionic_globals.h"
#include "private/bionic_tls.h"
#include "private/thread_private.h"
#include "pthread_internal.h"

extern "C" int __system_properties_init(void);
extern "C" void scudo_malloc_set_zero_contents(int);
extern "C" void scudo_malloc_set_pattern_fill_contents(int);

__LIBC_HIDDEN__ constinit WriteProtected<libc_globals> __libc_globals;
__LIBC_HIDDEN__ constinit _Atomic(bool) __libc_memtag_stack;
__LIBC_HIDDEN__ constinit bool __libc_memtag_stack_abi;

// Not public, but well-known in the BSDs.
__BIONIC_WEAK_VARIABLE_FOR_NATIVE_BRIDGE
const char* __progname;

#if defined(__i386__) || defined(__x86_64__)
// Default sizes based on the old hard-coded values for Atom/Silvermont (x86) and Core 2 (x86-64)...
size_t __x86_data_cache_size = 24 * 1024;
size_t __x86_data_cache_size_half = __x86_data_cache_size / 2;
size_t __x86_shared_cache_size = sizeof(long) == 8 ? 4096 * 1024 : 1024 * 1024;
size_t __x86_shared_cache_size_half = __x86_shared_cache_size / 2;
// ...overwritten at runtime based on the cpu's reported cache sizes.
static void __libc_init_x86_cache_info() {
  // Handle the case where during early boot /sys fs may not yet be ready,
  // resulting in sysconf() returning 0, leading to crashes.
  // In that case (basically just init), we keep the defaults.
  if (sysconf(_SC_LEVEL1_DCACHE_SIZE) != 0) {
    __x86_data_cache_size = sysconf(_SC_LEVEL1_DCACHE_SIZE);
    __x86_data_cache_size_half = __x86_data_cache_size / 2;
  }
  if (sysconf(_SC_LEVEL2_CACHE_SIZE) != 0) {
    __x86_shared_cache_size = sysconf(_SC_LEVEL2_CACHE_SIZE);
    __x86_shared_cache_size_half = __x86_shared_cache_size / 2;
  }
}
#endif

void __libc_init_globals() {
  // Initialize libc globals that are needed in both the linker and in libc.
  // In dynamic binaries, this is run at least twice for different copies of the
  // globals, once for the linker's copy and once for the one in libc.so.
  __libc_globals.initialize();
  __libc_globals.mutate([](libc_globals* globals) {
    __libc_init_vdso(globals);
    __libc_init_setjmp_cookie(globals);
  });
}

#if !defined(__LP64__)
static void __check_max_thread_id() {
  if (gettid() > 65535) {
    async_safe_fatal("32-bit pthread_mutex_t only supports pids <= 65535; "
                     "current pid %d; "
                     "`echo 65535 > /proc/sys/kernel/pid_max` as root",
                     gettid());
  }
}
#endif

static void arc4random_fork_handler() {
  _rs_forked = 1;
  _thread_arc4_lock();
}

__BIONIC_WEAK_FOR_NATIVE_BRIDGE
void __libc_init_scudo() {
  // Heap tagging level *must* be set before interacting with Scudo, otherwise
  // the primary will be mapped with PROT_MTE even if MTE is is not enabled in
  // this process.
  SetDefaultHeapTaggingLevel();

// TODO(b/158870657) make this unconditional when all devices support SCUDO.
#if defined(USE_SCUDO) && !__has_feature(hwaddress_sanitizer)
#if defined(SCUDO_PATTERN_FILL_CONTENTS)
  scudo_malloc_set_pattern_fill_contents(1);
#elif defined(SCUDO_ZERO_CONTENTS)
  scudo_malloc_set_zero_contents(1);
#endif
#endif
}

__BIONIC_WEAK_FOR_NATIVE_BRIDGE
__attribute__((no_sanitize("hwaddress", "memtag"))) void
__libc_init_mte_late() {
#if defined(__aarch64__)
  if (!__libc_shared_globals()->heap_tagging_upgrade_timer_sec) {
    return;
  }
  struct sigevent event = {};
  static timer_t timer;
  event.sigev_notify = SIGEV_THREAD;
  event.sigev_notify_function = [](union sigval) {
    async_safe_format_log(ANDROID_LOG_INFO, "libc",
                          "Downgrading MTE to async.");
    ScopedPthreadMutexLocker l(&g_heap_tagging_lock);
    SetHeapTaggingLevel(M_HEAP_TAGGING_LEVEL_ASYNC);
    timer_delete(timer);
  };

  if (timer_create(CLOCK_REALTIME, &event, &timer) == -1) {
    async_safe_format_log(ANDROID_LOG_ERROR, "libc",
                          "Failed to create MTE downgrade timer: %m");
    // Revert back to ASYNC. If we fail to create or arm the timer, otherwise
    // the process would be indefinitely stuck in SYNC.
    SetHeapTaggingLevel(M_HEAP_TAGGING_LEVEL_ASYNC);
    return;
  }

  struct itimerspec timerspec = {};
  timerspec.it_value.tv_sec =
      __libc_shared_globals()->heap_tagging_upgrade_timer_sec;
  if (timer_settime(timer, /* flags= */ 0, &timerspec, nullptr) == -1) {
    async_safe_format_log(ANDROID_LOG_ERROR, "libc",
                          "Failed to arm MTE downgrade timer: %m");
    // Revert back to ASYNC. If we fail to create or arm the timer, otherwise
    // the process would be indefinitely stuck in SYNC.
    SetHeapTaggingLevel(M_HEAP_TAGGING_LEVEL_ASYNC);
    timer_delete(timer);
    return;
  }
  async_safe_format_log(
      ANDROID_LOG_INFO, "libc", "Armed MTE downgrade timer for %" PRId64 " s",
      __libc_shared_globals()->heap_tagging_upgrade_timer_sec);
#endif
}

__BIONIC_WEAK_FOR_NATIVE_BRIDGE
void __libc_add_main_thread() {
  // Get the main thread from TLS and add it to the thread list.
  pthread_internal_t* main_thread = __get_thread();
  __pthread_internal_add(main_thread);
}

void __libc_init_common() {
  // Initialize various globals.
  environ = __libc_shared_globals()->init_environ;
  errno = 0;
  setprogname(__libc_shared_globals()->init_progname ?: "<unknown>");

#if !defined(__LP64__)
  __check_max_thread_id();
#endif

  __libc_add_main_thread();

  __system_properties_init(); // Requires 'environ'.
  __libc_init_fdsan(); // Requires system properties (for debug.fdsan).
  __libc_init_fdtrack();

#if defined(__i386__) || defined(__x86_64__)
  __libc_init_x86_cache_info();
#endif
}

void __libc_init_fork_handler() {
  // Register atfork handlers to take and release the arc4random lock.
  pthread_atfork(arc4random_fork_handler, _thread_arc4_unlock, _thread_arc4_unlock);
}

extern "C" void scudo_malloc_set_add_large_allocation_slack(int add_slack);

__BIONIC_WEAK_FOR_NATIVE_BRIDGE void __libc_set_target_sdk_version(int target_api_level __unused) {
#if defined(USE_SCUDO) && !__has_feature(hwaddress_sanitizer)
  scudo_malloc_set_add_large_allocation_slack(target_api_level < 31);
#endif
}

__noreturn static void __early_abort(size_t line) {
  // We can't write to stdout or stderr because we're aborting before we've checked that
  // it's safe for us to use those file descriptors. We probably can't strace either, so
  // we rely on the fact that if we dereference a low address, either debuggerd or the
  // kernel's crash dump will show the fault address.
  *reinterpret_cast<int*>(line) = 0;
  _exit(EXIT_FAILURE);
}

// Force any of the stdin/stdout/stderr file descriptors that aren't
// open to be associated with /dev/null.
static void __nullify_closed_stdio() {
  for (int i = 0; i < 3; i++) {
    if (TEMP_FAILURE_RETRY(fcntl(i, F_GETFL)) == -1) {
      // The only error we allow is that the file descriptor does not exist.
      if (errno != EBADF) __early_abort(__LINE__);

      // This file descriptor wasn't open, so open /dev/null.
      // init won't have /dev/null available, but SELinux provides an equivalent.
      // This takes advantage of the fact that open() will take the lowest free
      // file descriptor, and we're iterating in order from 0, but we'll
      // double-check we got the right fd anyway...
      int fd;
      if (((fd = TEMP_FAILURE_RETRY(open("/dev/null", O_RDWR))) == -1 &&
           (fd = TEMP_FAILURE_RETRY(open("/sys/fs/selinux/null", O_RDWR))) == -1) ||
          fd != i) {
        __early_abort(__LINE__);
      }
    }
  }
}

// Check if the environment variable definition at 'envstr'
// starts with '<name>=', and if so return the address of the
// first character after the equal sign. Otherwise return null.
static const char* env_match(const char* envstr, const char* name) {
  size_t i = 0;

  while (envstr[i] == name[i] && name[i] != '\0') {
    ++i;
  }

  if (name[i] == '\0' && envstr[i] == '=') {
    return envstr + i + 1;
  }

  return nullptr;
}

static bool __is_valid_environment_variable(const char* name) {
  // According to the kernel source, by default the kernel uses 32*PAGE_SIZE
  // as the maximum size for an environment variable definition.
  const int MAX_ENV_LEN = 32*4096;

  if (name == nullptr) {
    return false;
  }

  // Parse the string, looking for the first '=' there, and its size.
  int pos = 0;
  int first_equal_pos = -1;
  while (pos < MAX_ENV_LEN) {
    if (name[pos] == '\0') {
      break;
    }
    if (name[pos] == '=' && first_equal_pos < 0) {
      first_equal_pos = pos;
    }
    pos++;
  }

  // Check that it's smaller than MAX_ENV_LEN (to detect non-zero terminated strings).
  if (pos >= MAX_ENV_LEN) {
    return false;
  }

  // Check that it contains at least one equal sign that is not the first character
  if (first_equal_pos < 1) {
    return false;
  }

  return true;
}

static bool __is_unsafe_environment_variable(const char* name) {
  // None of these should be allowed when the AT_SECURE auxv
  // flag is set. This flag is set to inform userspace that a
  // security transition has occurred, for example, as a result
  // of executing a setuid program or the result of an SELinux
  // security transition.
  static constexpr const char* UNSAFE_VARIABLE_NAMES[] = {
      "ANDROID_DNS_MODE",
      "GCONV_PATH",
      "GETCONF_DIR",
      "HOSTALIASES",
      "JE_MALLOC_CONF",
      "LD_AOUT_LIBRARY_PATH",
      "LD_AOUT_PRELOAD",
      "LD_AUDIT",
      "LD_CONFIG_FILE",
      "LD_DEBUG",
      "LD_DEBUG_OUTPUT",
      "LD_DYNAMIC_WEAK",
      "LD_HWASAN",
      "LD_LIBRARY_PATH",
      "LD_ORIGIN_PATH",
      "LD_PRELOAD",
      "LD_PROFILE",
      "LD_SHOW_AUXV",
      "LD_USE_LOAD_BIAS",
      "LIBC_DEBUG_MALLOC_OPTIONS",
      "LIBC_HOOKS_ENABLE",
      "LOCALDOMAIN",
      "LOCPATH",
      "MALLOC_CHECK_",
      "MALLOC_CONF",
      "MALLOC_TRACE",
      "NIS_PATH",
      "NLSPATH",
      "RESOLV_HOST_CONF",
      "RES_OPTIONS",
      "SCUDO_OPTIONS",
      "TMPDIR",
      "TZDIR",
  };
  for (const auto& unsafe_variable_name : UNSAFE_VARIABLE_NAMES) {
    if (env_match(name, unsafe_variable_name) != nullptr) {
      return true;
    }
  }
  return false;
}

static void __sanitize_environment_variables(char** env) {
  char** src = env;
  char** dst = env;
  for (; src[0] != nullptr; ++src) {
    if (!__is_valid_environment_variable(src[0])) {
      continue;
    }
    // Remove various unsafe environment variables if we're loading a setuid program.
    if (__is_unsafe_environment_variable(src[0])) {
      continue;
    }
    dst[0] = src[0];
    ++dst;
  }
  dst[0] = nullptr;
}

static void __initialize_personality() {
#if !defined(__LP64__)
  int old_value = personality(0xffffffff);
  if (old_value == -1) {
    async_safe_fatal("error getting old personality value: %m");
  }

  if (personality((static_cast<unsigned int>(old_value) & ~PER_MASK) | PER_LINUX32) == -1) {
    async_safe_fatal("error setting PER_LINUX32 personality: %m");
  }
#endif
}

void __libc_init_AT_SECURE(char** env) {
  // Check that the kernel provided a value for AT_SECURE.
  errno = 0;
  unsigned long is_AT_SECURE = getauxval(AT_SECURE);
  if (errno != 0) __early_abort(__LINE__);

  // Always ensure that STDIN/STDOUT/STDERR exist. This prevents file
  // descriptor confusion bugs where a parent process closes
  // STD*, the exec()d process calls open() for an unrelated reason,
  // the newly created file descriptor is assigned
  // 0<=FD<=2, and unrelated code attempts to read / write to the STD*
  // FDs.
  // In particular, this can be a security bug for setuid/setgid programs.
  // For example:
  // https://www.freebsd.org/security/advisories/FreeBSD-SA-02:23.stdio.asc
  // However, for robustness reasons, we don't limit these protections to
  // just security critical executables.
  //
  // Init is excluded from these protections unless AT_SECURE is set, as
  // /dev/null and/or /sys/fs/selinux/null will not be available at
  // early boot.
  if ((getpid() != 1) || is_AT_SECURE) {
    __nullify_closed_stdio();
  }

  if (is_AT_SECURE) {
    __sanitize_environment_variables(env);
  }

  // Now the environment has been sanitized, make it available.
  environ = __libc_shared_globals()->init_environ = env;

  __initialize_personality();
}

/* This function will be called during normal program termination
 * to run the destructors that are listed in the .fini_array section
 * of the executable, if any.
 *
 * 'fini_array' points to a list of function addresses. The first
 * entry in the list has value -1, the last one has value 0.
 */
void __libc_fini(void* array) {
  typedef void (*Dtor)();
  Dtor* fini_array = reinterpret_cast<Dtor*>(array);
  const Dtor minus1 = reinterpret_cast<Dtor>(static_cast<uintptr_t>(-1));

  // Validity check: the first entry must be -1.
  if (array == nullptr || fini_array[0] != minus1) return;

  // Skip over it.
  fini_array += 1;

  // Count the number of destructors.
  int count = 0;
  while (fini_array[count] != nullptr) {
    ++count;
  }

  // Now call each destructor in reverse order, ignoring any -1s.
  while (count > 0) {
    Dtor dtor = fini_array[--count];
    if (dtor != minus1) dtor();
  }
}
