chromium/third_party/boringssl/src/crypto/rand_extra/fork_detect.c

/* Copyright (c) 2020, Google Inc.
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */

#if !defined(_GNU_SOURCE)
#define _GNU_SOURCE
#endif

#include "../bcm_support.h"

#if defined(OPENSSL_FORK_DETECTION_MADVISE)
#include <unistd.h>
#include <stdlib.h>
#include <assert.h>
#include <sys/mman.h>
#if defined(MADV_WIPEONFORK)
static_assert;
#else
#define MADV_WIPEONFORK
#endif
#elif defined(OPENSSL_FORK_DETECTION_PTHREAD_ATFORK)
#include <unistd.h>
#include <stdlib.h>
#include <pthread.h>
#endif // OPENSSL_FORK_DETECTION_MADVISE

#include "../internal.h"

#if defined(OPENSSL_FORK_DETECTION_MADVISE)
static int g_force_madv_wipeonfork;
static int g_force_madv_wipeonfork_enabled;
static CRYPTO_once_t g_fork_detect_once =;
static CRYPTO_MUTEX g_fork_detect_lock =;
static CRYPTO_atomic_u32 * g_fork_detect_addr;
static uint64_t g_fork_generation;

static void init_fork_detect(void) {}

uint64_t CRYPTO_get_fork_generation(void) {}

void CRYPTO_fork_detect_force_madv_wipeonfork_for_testing(int on) {}

#elif defined(OPENSSL_FORK_DETECTION_PTHREAD_ATFORK)

static CRYPTO_once_t g_pthread_fork_detection_once = CRYPTO_ONCE_INIT;
static uint64_t g_atfork_fork_generation;

static void we_are_forked(void) {
  // Immediately after a fork, the process must be single-threaded.
  uint64_t value = g_atfork_fork_generation + 1;
  if (value == 0) {
    value = 1;
  }
  g_atfork_fork_generation = value;
}

static void init_pthread_fork_detection(void) {
  if (pthread_atfork(NULL, NULL, we_are_forked) != 0) {
    abort();
  }
  g_atfork_fork_generation = 1;
}

uint64_t CRYPTO_get_fork_generation(void) {
  CRYPTO_once(&g_pthread_fork_detection_once, init_pthread_fork_detection);

  return g_atfork_fork_generation;
}

#elif defined(OPENSSL_DOES_NOT_FORK)

// These platforms are guaranteed not to fork, and therefore do not require
// fork detection support. Returning a constant non zero value makes BoringSSL
// assume address space duplication is not a concern and adding entropy to
// every RAND_bytes call is not needed.
uint64_t CRYPTO_get_fork_generation(void) { return 0xc0ffee; }

#else

// These platforms may fork, but we do not have a mitigation mechanism in
// place.  Returning a constant zero value makes BoringSSL assume that address
// space duplication could have occured on any call entropy must be added to
// every RAND_bytes call.
uint64_t CRYPTO_get_fork_generation(void) { return 0; }

#endif