/* Copyright 2019 The BoringSSL Authors
 *
 * 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. */

#include <gtest/gtest.h>
#include <stdlib.h>

#include <optional>

#include <openssl/bytestring.h>
#include <openssl/ctrdrbg.h>
#include <openssl/rand.h>

#include "../internal.h"
#include "getrandom_fillin.h"


#if (defined(OPENSSL_X86_64) || defined(OPENSSL_AARCH64)) &&               \
    !defined(BORINGSSL_SHARED_LIBRARY) && defined(OPENSSL_RAND_URANDOM) && \
    defined(USE_NR_getrandom)

#include <elf.h>
#include <linux/random.h>
#include <sys/ptrace.h>
#include <sys/socket.h>
#include <sys/syscall.h>
#include <sys/uio.h>
#include <sys/un.h>
#include <sys/user.h>

namespace {

#if !defined(PTRACE_O_EXITKILL)
#define PTRACE_O_EXITKILL (1 << 20)
#endif

#if defined(OPENSSL_ANDROID)
static const bool kIsAndroid = true;
#else
static const bool kIsAndroid = false;
#endif

#if defined(BORINGSSL_FIPS)
static const bool kIsFIPS = true;
#else
static const bool kIsFIPS = false;
#endif

static const bool kUsesDaemon = kIsFIPS && kIsAndroid;

// kDaemonWriteLength is the number of bytes that the entropy daemon writes.
static const size_t kDaemonWriteLength = 496;

// This test can be run with $OPENSSL_ia32cap=~0x4000000000000000 in order to
// simulate the absence of RDRAND of machines that have it.

// Event represents a system call from urandom.c that is observed by the ptrace
// code in |GetTrace|.
struct Event {
  enum class Syscall {
    kGetRandom,
    kOpen,
    kUrandomRead,
    kSocket,
    kConnect,
    kSocketRead,
    kSocketClose,
    kAbort,
  };

  explicit Event(Syscall syscall) : type(syscall) {}

  bool operator==(const Event &other) const {
    return type == other.type &&      //
           length == other.length &&  //
           flags == other.flags &&    //
           filename == other.filename;
  }

  static Event GetRandom(size_t length, unsigned flags) {
    Event e(Syscall::kGetRandom);
    e.length = length;
    e.flags = flags;
    return e;
  }

  static Event Open(const std::string &filename) {
    Event e(Syscall::kOpen);
    e.filename = filename;
    return e;
  }

  static Event UrandomRead(size_t length) {
    Event e(Syscall::kUrandomRead);
    e.length = length;
    return e;
  }

  static Event Socket() {
    Event e(Syscall::kSocket);
    return e;
  }

  static Event Connect() {
    Event e(Syscall::kConnect);
    return e;
  }

  static Event SocketRead(size_t length) {
    Event e(Syscall::kSocketRead);
    e.length = length;
    return e;
  }

  static Event SocketClose() {
    Event e(Syscall::kSocketClose);
    return e;
  }

  static Event Abort() {
    Event e(Syscall::kAbort);
    return e;
  }

  std::string String() const {
    char buf[256];

    switch (type) {
      case Syscall::kGetRandom:
        snprintf(buf, sizeof(buf), "getrandom(_, %zu, %u)", length, flags);
        break;

      case Syscall::kOpen:
        snprintf(buf, sizeof(buf), "open(%s, _)", filename.c_str());
        break;

      case Syscall::kUrandomRead:
        snprintf(buf, sizeof(buf), "read(urandom_fd, _, %zu)", length);
        break;

      case Syscall::kSocket:
        return "socket(UNIX, STREAM, _)";

      case Syscall::kConnect:
        return "connect(sock, _, _)";

      case Syscall::kSocketRead:
        snprintf(buf, sizeof(buf), "read(sock_fd, _, %zu)", length);
        break;

      case Syscall::kSocketClose:
        return "close(sock)";

      case Syscall::kAbort:
        return "abort()";
    }

    return std::string(buf);
  }

  const Syscall type;
  size_t length = 0;
  unsigned flags = 0;
  std::string filename;
};

static std::string ToString(const std::vector<Event> &trace) {
  std::string ret;
  for (const auto &event : trace) {
    if (!ret.empty()) {
      ret += ", ";
    }
    ret += event.String();
  }
  return ret;
}

// The following are flags to tell |GetTrace| to inject faults, using ptrace,
// into the entropy-related system calls.

// getrandom gives |ENOSYS|.
static const unsigned NO_GETRANDOM = 1;
// opening /dev/urandom fails.
static const unsigned NO_URANDOM = 2;
// getrandom always returns |EAGAIN| if given |GRNG_NONBLOCK|.
static const unsigned GETRANDOM_NOT_READY = 4;
// getrandom gives |EINVAL| unless |NO_GETRANDOM| is set.
static const unsigned GETRANDOM_ERROR = 8;
// Reading from /dev/urandom gives |EINVAL|.
static const unsigned URANDOM_ERROR = 16;
static const unsigned SOCKET_ERROR = 32;
static const unsigned CONNECT_ERROR = 64;
static const unsigned SOCKET_READ_ERROR = 128;
static const unsigned SOCKET_READ_SHORT = 256;
static const unsigned NEXT_FLAG = 512;

// regs_read fetches the registers of |child_pid| and writes them to |out_regs|.
// That structure will contain at least the following members:
//   syscall: the syscall number, if registers were read just before entering
//       one.
//   args[0..2]: syscall arguments, if registers were read just before
//       entering one.
//   ret: the syscall return value, if registers were read just after finishing
//       one.
//
// This call returns true on success and false otherwise.
static bool regs_read(struct regs *out_regs, int child_pid);

// regs_set_ret sets the return value of the system call that |child_pid| has
// just finished, to |ret|. It returns true on success and false otherwise.
static bool regs_set_ret(int child_pid, int ret);

// regs_break_syscall causes the system call that |child_pid| is about to enter
// to fail to run.
static bool regs_break_syscall(int child_pid, const struct regs *orig_regs);

struct regs {
  uintptr_t syscall;
  uintptr_t args[3];
  uintptr_t ret;
  struct user_regs_struct regs;
};

#if defined(OPENSSL_X86_64)

static bool regs_read(struct regs *out_regs, int child_pid) {
  if (ptrace(PTRACE_GETREGS, child_pid, nullptr, &out_regs->regs) != 0) {
    return false;
  }

  out_regs->syscall = out_regs->regs.orig_rax;
  out_regs->ret = out_regs->regs.rax;
  out_regs->args[0] = out_regs->regs.rdi;
  out_regs->args[1] = out_regs->regs.rsi;
  out_regs->args[2] = out_regs->regs.rdx;
  return true;
}

static bool regs_set_ret(int child_pid, int ret) {
  struct regs regs;
  if (!regs_read(&regs, child_pid)) {
    return false;
  }
  regs.regs.rax = ret;
  return ptrace(PTRACE_SETREGS, child_pid, nullptr, &regs.regs) == 0;
}

static bool regs_break_syscall(int child_pid, const struct regs *orig_regs) {
  // Replace the syscall number with -1 to cause the kernel to fail the call.
  struct user_regs_struct regs = orig_regs->regs;
  regs.orig_rax = -1;
  return ptrace(PTRACE_SETREGS, child_pid, nullptr, &regs) == 0;
}

#elif defined(OPENSSL_AARCH64)

static bool regs_read(struct regs *out_regs, int child_pid) {
  struct iovec io;
  io.iov_base = &out_regs->regs;
  io.iov_len = sizeof(out_regs->regs);
  if (ptrace(PTRACE_GETREGSET, child_pid, NT_PRSTATUS, &io) != 0) {
    return false;
  }

  out_regs->syscall = out_regs->regs.regs[8];
  out_regs->ret = out_regs->regs.regs[0];
  out_regs->args[0] = out_regs->regs.regs[0];
  out_regs->args[1] = out_regs->regs.regs[1];
  out_regs->args[2] = out_regs->regs.regs[2];

  return true;
}

static bool set_regset(int child_pid, int regset, const void *data,
                       size_t len) {
  struct iovec io;
  io.iov_base = const_cast<void *>(data);
  io.iov_len = len;
  return ptrace(PTRACE_SETREGSET, child_pid, reinterpret_cast<void *>(regset),
                &io) == 0;
}

static bool regs_set_ret(int child_pid, int ret) {
  struct regs regs;
  if (!regs_read(&regs, child_pid)) {
    return false;
  }
  regs.regs.regs[0] = ret;
  return set_regset(child_pid, NT_PRSTATUS, &regs.regs, sizeof(regs.regs));
}

static bool regs_break_syscall(int child_pid, const struct regs *orig_regs) {
  // Replace the syscall number with -1 to cause the kernel to fail the call.
  int syscall = -1;
  return set_regset(child_pid, NT_ARM_SYSTEM_CALL, &syscall, sizeof(syscall));
}

#endif

// memcpy_to_remote copies |n| bytes from |in_src| in the local address space,
// to |dest| in the address space of |child_pid|.
static void memcpy_to_remote(int child_pid, uint64_t dest, const void *in_src,
                             size_t n) {
  const uint8_t *src = reinterpret_cast<const uint8_t *>(in_src);

  // ptrace always works with ill-defined "words", which appear to be 64-bit
  // on 64-bit systems.
#if !defined(OPENSSL_64_BIT)
#error "This code probably doesn't work"
#endif

  while (n) {
    const uintptr_t aligned_addr = dest & ~7;
    const uintptr_t offset = dest - aligned_addr;
    const size_t space = 8 - offset;
    size_t todo = n;
    if (todo > space) {
      todo = space;
    }

    uint64_t word;
    if (offset == 0 && todo == 8) {
      word = CRYPTO_load_u64_le(src);
    } else {
      uint8_t bytes[8];
      CRYPTO_store_u64_le(
          bytes, ptrace(PTRACE_PEEKDATA, child_pid,
                        reinterpret_cast<void *>(aligned_addr), nullptr));
      memcpy(&bytes[offset], src, todo);
      word = CRYPTO_load_u64_le(bytes);
    }

    ASSERT_EQ(0, ptrace(PTRACE_POKEDATA, child_pid,
                        reinterpret_cast<void *>(aligned_addr),
                        reinterpret_cast<void *>(word)));

    src += todo;
    n -= todo;
    dest += todo;
  }
}

static uint8_t get_byte_from_remote(int child_pid, uint64_t ptr) {
  // ptrace always works with ill-defined "words", which appear to be 64-bit
  // on 64-bit systems.
#if !defined(OPENSSL_64_BIT)
#error "This code probably doesn't work"
#endif

  const uintptr_t aligned_addr = ptr & ~7;
  const uintptr_t offset = ptr - aligned_addr;

  uint64_t word = ptrace(PTRACE_PEEKDATA, child_pid,
                         reinterpret_cast<void *>(aligned_addr), 0);
  uint8_t bytes[8];
  CRYPTO_store_u64_le(bytes, word);
  return bytes[offset];
}

static std::string get_string_from_remote(int child_pid, uint64_t ptr) {
  std::string ret;

  for (;;) {
    const uint8_t byte = get_byte_from_remote(child_pid, ptr);
    if (byte == 0) {
      break;
    }
    ret.push_back((char)byte);
    ptr++;
  }

  return ret;
}

// GetTrace runs |thunk| in a forked process and observes the resulting system
// calls using ptrace. It simulates a variety of failures based on the contents
// of |flags| and records the observed events by appending to |out_trace|.
static void GetTrace(std::vector<Event> *out_trace, unsigned flags,
                     std::function<void()> thunk) {
  const int child_pid = fork();
  ASSERT_NE(-1, child_pid);

  if (child_pid == 0) {
    // Child process
    if (ptrace(PTRACE_TRACEME, 0, 0, 0) != 0) {
      perror("PTRACE_TRACEME");
      _exit(1);
    }
    raise(SIGSTOP);
    thunk();
    _exit(0);
  }

  // Parent process
  int status;
  ASSERT_EQ(child_pid, waitpid(child_pid, &status, 0));
  ASSERT_TRUE(WIFSTOPPED(status) && WSTOPSIG(status) == SIGSTOP)
      << "Child was not stopped with SIGSTOP: " << status;

  // Set options so that:
  //   a) the child process is killed once this process dies.
  //   b) System calls result in a WSTOPSIG value of (SIGTRAP | 0x80) rather
  //      than just SIGTRAP. (This doesn't matter here, but it's recommended
  //      practice so that it's distinct from the signal itself.)
  ASSERT_EQ(0, ptrace(PTRACE_SETOPTIONS, child_pid, nullptr,
                      PTRACE_O_EXITKILL | PTRACE_O_TRACESYSGOOD))
      << strerror(errno);

  // urandom_fd tracks the file descriptor number for /dev/urandom in the child
  // process, if it opens it.
  int urandom_fd = -1;

  // sock_fd tracks the file descriptor number for the socket to the entropy
  // daemon, if one is opened.
  int sock_fd = -1;

  for (;;) {
    // Advance the child to the next system call.
    ASSERT_EQ(0, ptrace(PTRACE_SYSCALL, child_pid, 0, 0));
    ASSERT_EQ(child_pid, waitpid(child_pid, &status, 0));

    // The child may have aborted rather than made a system call.
    if (WIFSTOPPED(status) && WSTOPSIG(status) == SIGABRT) {
      out_trace->push_back(Event::Abort());
      break;
    }

    // Otherwise the only valid ptrace event is a system call stop.
    ASSERT_TRUE(WIFSTOPPED(status) && WSTOPSIG(status) == (SIGTRAP | 0x80))
        << "Child was not stopped with a syscall stop: " << status;

    struct regs regs;
    ASSERT_TRUE(regs_read(&regs, child_pid));

    bool is_opening_urandom = false;
    bool is_socket_call = false;
    bool is_socket_read = false;
    uint64_t socket_read_bytes = 0;
    // force_result is unset to indicate that the system call should run
    // normally. Otherwise it's, e.g. -EINVAL, to indicate that the system call
    // should not run and that the given value should be injected on return.
    std::optional<int> force_result;

    switch (regs.syscall) {
      case __NR_getrandom:
        if (flags & NO_GETRANDOM) {
          force_result = -ENOSYS;
        } else if (flags & GETRANDOM_ERROR) {
          force_result = -EINVAL;
        } else if (flags & GETRANDOM_NOT_READY) {
          if (regs.args[2] & GRND_NONBLOCK) {
            force_result = -EAGAIN;
          }
        }
        out_trace->push_back(
            Event::GetRandom(/*length=*/regs.args[1], /*flags=*/regs.args[2]));
        break;

      case __NR_openat:
#if defined(OPENSSL_X86_64)
      case __NR_open:
#endif
      {
        uintptr_t filename_ptr =
            (regs.syscall == __NR_openat) ? regs.args[1] : regs.args[0];
        const std::string filename =
            get_string_from_remote(child_pid, filename_ptr);
        if (filename.find("/dev/__properties__/") == 0) {
          // Android may try opening these files as part of SELinux support.
          // They are ignored here.
        } else {
          out_trace->push_back(Event::Open(filename));
        }
        is_opening_urandom = (filename == "/dev/urandom");
        if (is_opening_urandom && (flags & NO_URANDOM)) {
          force_result = -ENOENT;
        }
        break;
      }

      case __NR_read: {
        const int read_fd = regs.args[0];
        if (urandom_fd >= 0 && urandom_fd == read_fd) {
          out_trace->push_back(Event::UrandomRead(/*length=*/regs.args[2]));
          if (flags & URANDOM_ERROR) {
            force_result = -EINVAL;
          }
        } else if (sock_fd >= 0 && sock_fd == read_fd) {
          uint64_t length = regs.args[2];
          out_trace->push_back(Event::SocketRead(length));
          if (flags & SOCKET_READ_ERROR) {
            force_result = -EINVAL;
          } else {
            is_socket_read = true;
            socket_read_bytes = length;

            if (flags & SOCKET_READ_SHORT) {
              ASSERT_GT(socket_read_bytes, 0u);
              socket_read_bytes--;
              flags &= ~SOCKET_READ_SHORT;
            }
          }
        }
        break;
      }

      case __NR_close: {
        if (sock_fd >= 0 && static_cast<int>(regs.args[0]) == sock_fd) {
          out_trace->push_back(Event::SocketClose());
          sock_fd = -1;
        }
        break;
      }

      case __NR_socket: {
        const int family = regs.args[0];
        const int type = regs.args[1];
        if (family == AF_UNIX && type == SOCK_STREAM) {
          out_trace->push_back(Event::Socket());
          is_socket_call = true;
          if (flags & SOCKET_ERROR) {
            force_result = -EINVAL;
          }
        }
        break;
      }

      case __NR_connect: {
        const int connect_fd = regs.args[0];
        if (sock_fd >= 0 && connect_fd == sock_fd) {
          out_trace->push_back(Event::Connect());
          if (flags & CONNECT_ERROR) {
            force_result = -EINVAL;
          } else {
            // The test system might not have an entropy daemon running so
            // inject a success result.
            force_result = 0;
          }
        }

        break;
      }
    }

    if (force_result.has_value()) {
      ASSERT_TRUE(regs_break_syscall(child_pid, &regs));
    }

    ASSERT_EQ(0, ptrace(PTRACE_SYSCALL, child_pid, 0, 0));
    ASSERT_EQ(child_pid, waitpid(child_pid, &status, 0));
    // If the system call was exit/exit_group, the process may be terminated
    // rather than have exited the system call.
    if (WIFEXITED(status)) {
      ASSERT_EQ(0, WEXITSTATUS(status));
      return;
    }

    // Otherwise the next state must be a system call exit stop. This is
    // indistinguishable from a system call entry, we just have to keep track
    // and know that these events happen in pairs.
    ASSERT_TRUE(WIFSTOPPED(status) && WSTOPSIG(status) == (SIGTRAP | 0x80));

    if (force_result.has_value()) {
      ASSERT_TRUE(regs_set_ret(child_pid, force_result.value()));
    } else if (is_opening_urandom) {
      ASSERT_TRUE(regs_read(&regs, child_pid));
      urandom_fd = regs.ret;
    } else if (is_socket_call) {
      ASSERT_TRUE(regs_read(&regs, child_pid));
      sock_fd = regs.ret;
    } else if (is_socket_read) {
      // Simulate a response from the entropy daemon since it might not be
      // running on the current system.
      uint8_t entropy[kDaemonWriteLength];
      ASSERT_LE(socket_read_bytes, sizeof(entropy));

      for (size_t i = 0; i < sizeof(entropy); i++) {
        entropy[i] = i & 0xff;
      }
      memcpy_to_remote(child_pid, regs.args[1], entropy, socket_read_bytes);

      ASSERT_TRUE(regs_set_ret(child_pid, socket_read_bytes));
    }
  }
}

// TestFunction is the function that |GetTrace| is asked to trace.
static void TestFunction() {
  uint8_t byte;
  RAND_bytes(&byte, sizeof(byte));
  RAND_bytes(&byte, sizeof(byte));
}

static bool have_fork_detection() { return CRYPTO_get_fork_generation() != 0; }

static bool AppendDaemonEvents(std::vector<Event> *events, unsigned flags) {
  events->push_back(Event::Socket());
  if (flags & SOCKET_ERROR) {
    return false;
  }

  bool ret = false;
  events->push_back(Event::Connect());
  if (flags & CONNECT_ERROR) {
    goto out;
  }

  events->push_back(Event::SocketRead(kDaemonWriteLength));
  if (flags & SOCKET_READ_ERROR) {
    goto out;
  }

  if (flags & SOCKET_READ_SHORT) {
    events->push_back(Event::SocketRead(1));
  }

  ret = true;

out:
  events->push_back(Event::SocketClose());
  return ret;
}

// TestFunctionPRNGModel is a model of how the urandom.c code will behave when
// |TestFunction| is run. It should return the same trace of events that
// |GetTrace| will observe the real code making.
static std::vector<Event> TestFunctionPRNGModel(unsigned flags) {
  std::vector<Event> ret;
  bool getrandom_ready = false;
  bool used_daemon = false;

  if (have_fork_detection()) {
    used_daemon = kUsesDaemon && AppendDaemonEvents(&ret, flags);
  }

  // Probe for getrandom support
  ret.push_back(Event::GetRandom(1, GRND_NONBLOCK));
  std::function<void()> wait_for_entropy;
  std::function<bool(bool, size_t)> sysrand;

  if (flags & NO_GETRANDOM) {
    if (kIsFIPS) {
      // FIPS builds require getrandom.
      ret.push_back(Event::Abort());
      return ret;
    }

    ret.push_back(Event::Open("/dev/urandom"));
    if (flags & NO_URANDOM) {
      ret.push_back(Event::Abort());
      return ret;
    }

    sysrand = [&ret, flags](bool block, size_t len) {
      ret.push_back(Event::UrandomRead(len));
      if (flags & URANDOM_ERROR) {
        ret.push_back(Event::Abort());
        return false;
      }
      return true;
    };
  } else {
    if (flags & GETRANDOM_ERROR) {
      ret.push_back(Event::Abort());
      return ret;
    }

    getrandom_ready = (flags & GETRANDOM_NOT_READY) == 0;
    wait_for_entropy = [&ret, &getrandom_ready] {
      if (getrandom_ready) {
        return;
      }

      ret.push_back(Event::GetRandom(1, GRND_NONBLOCK));
      ret.push_back(Event::GetRandom(1, 0));
      getrandom_ready = true;
    };
    sysrand = [&ret, &wait_for_entropy](bool block, size_t len) {
      if (block) {
        wait_for_entropy();
      }
      ret.push_back(Event::GetRandom(len, block ? 0 : GRND_NONBLOCK));
      return true;
    };
  }

  const size_t kSeedLength = CTR_DRBG_ENTROPY_LEN * (kIsFIPS ? 10 : 1);
  const size_t kAdditionalDataLength = 32;

  if (!have_rdrand()) {
    if (!have_fork_detection()) {
      if (!sysrand(true, kAdditionalDataLength)) {
        return ret;
      }
      used_daemon = kUsesDaemon && AppendDaemonEvents(&ret, flags);
    }
    if (  // Initialise CRNGT.
        (!used_daemon && !sysrand(true, kSeedLength + (kIsFIPS ? 16 : 0))) ||
        // Personalisation draw if the daemon was used.
        (used_daemon && !sysrand(false, CTR_DRBG_ENTROPY_LEN)) ||
        // Second entropy draw.
        (!have_fork_detection() && !sysrand(true, kAdditionalDataLength))) {
      return ret;
    }
  } else if (
      // First additional data. If fast RDRAND isn't available then a
      // non-blocking OS entropy draw will be tried.
      (!have_fast_rdrand() && !have_fork_detection() &&
       !sysrand(false, kAdditionalDataLength)) ||
      // Opportuntistic entropy draw in FIPS mode because RDRAND was used.
      // In non-FIPS mode it's just drawn from |CRYPTO_sysrand| in a blocking
      // way.
      !sysrand(!kIsFIPS, CTR_DRBG_ENTROPY_LEN) ||
      // Second entropy draw's additional data.
      (!have_fast_rdrand() && !have_fork_detection() &&
       !sysrand(false, kAdditionalDataLength))) {
    return ret;
  }

  return ret;
}

static void CheckInvariants(const std::vector<Event> &events) {
  // If RDRAND is available then there should be no blocking syscalls in FIPS
  // mode.
#if defined(BORINGSSL_FIPS)
  if (have_rdrand()) {
    for (const auto &event : events) {
      switch (event.type) {
        case Event::Syscall::kGetRandom:
          if ((event.flags & GRND_NONBLOCK) == 0) {
            ADD_FAILURE() << "Blocking getrandom found with RDRAND: "
                          << ToString(events);
          }
          break;

        default:
          break;
      }
    }
  }
#endif
}

// Tests that |TestFunctionPRNGModel| is a correct model for the code in
// urandom.c, at least to the limits of the the |Event| type.
TEST(URandomTest, Test) {
  char buf[256];

  // Some Android systems lack getrandom.
  uint8_t scratch[1];
  const bool has_getrandom =
      (syscall(__NR_getrandom, scratch, sizeof(scratch), GRND_NONBLOCK) != -1 ||
       errno != ENOSYS);

#define TRACE_FLAG(flag)                                         \
  snprintf(buf, sizeof(buf), #flag ": %d", (flags & flag) != 0); \
  SCOPED_TRACE(buf);

  for (unsigned flags = 0; flags < NEXT_FLAG; flags++) {
    if (!kUsesDaemon && (flags & (SOCKET_ERROR | CONNECT_ERROR |
                                  SOCKET_READ_ERROR | SOCKET_READ_SHORT))) {
      // These cases are meaningless unless the code will try to use the entropy
      // daemon.
      continue;
    }

    if (!has_getrandom && !(flags & NO_GETRANDOM)) {
      continue;
    }

    TRACE_FLAG(NO_GETRANDOM);
    TRACE_FLAG(NO_URANDOM);
    TRACE_FLAG(GETRANDOM_NOT_READY);
    TRACE_FLAG(GETRANDOM_ERROR);
    TRACE_FLAG(URANDOM_ERROR);
    TRACE_FLAG(SOCKET_ERROR);
    TRACE_FLAG(CONNECT_ERROR);
    TRACE_FLAG(SOCKET_READ_ERROR);
    TRACE_FLAG(SOCKET_READ_SHORT);

    const std::vector<Event> expected_trace = TestFunctionPRNGModel(flags);
    CheckInvariants(expected_trace);
    std::vector<Event> actual_trace;
    GetTrace(&actual_trace, flags, TestFunction);

    if (expected_trace != actual_trace) {
      ADD_FAILURE() << "Expected: " << ToString(expected_trace)
                    << "\nFound:    " << ToString(actual_trace);
    }
  }
}

}  // namespace

int main(int argc, char **argv) {
  ::testing::InitGoogleTest(&argc, argv);

  if (getenv("BORINGSSL_IGNORE_MADV_WIPEONFORK")) {
    CRYPTO_fork_detect_force_madv_wipeonfork_for_testing(0);
  } else {
    CRYPTO_fork_detect_force_madv_wipeonfork_for_testing(1);
  }

  return RUN_ALL_TESTS();
}

#else

int main(int argc, char **argv) {
  printf("PASS\n");
  return 0;
}

#endif  // (X86_64 || AARCH64) && !SHARED_LIBRARY &&
        // !UNSAFE_DETERMINISTIC_MODE && USE_NR_getrandom
