// Copyright 2019 The BoringSSL Authors
//
// 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
//
//     https://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 <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
