urandom_test: force MADV_WIPEONFORK both ways.
This test could simulate the lack of MADV_WIPEONFORK on systems with it,
but couldn't simulate having it if the kernel didn't support it.
This change makes the presence / absence of
BORINGSSL_IGNORE_MADV_WIPEONFORK control whether MADV_WIPEONFORK is
"supported" in the test environment or not, and corrects the test for
the case where it's missing.
Change-Id: I23876788a0e0a4fd2a148f98b6b94e40880b6fc9
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/57745
Auto-Submit: Adam Langley <agl@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
Commit-Queue: Adam Langley <agl@google.com>
diff --git a/crypto/fipsmodule/rand/fork_detect.c b/crypto/fipsmodule/rand/fork_detect.c
index 51cf18a..58b0687 100644
--- a/crypto/fipsmodule/rand/fork_detect.c
+++ b/crypto/fipsmodule/rand/fork_detect.c
@@ -40,10 +40,11 @@
DEFINE_STATIC_MUTEX(g_fork_detect_lock);
DEFINE_BSS_GET(volatile char *, g_fork_detect_addr);
DEFINE_BSS_GET(uint64_t, g_fork_generation);
-DEFINE_BSS_GET(int, g_ignore_madv_wipeonfork);
+DEFINE_BSS_GET(int, g_force_madv_wipeonfork);
+DEFINE_BSS_GET(int, g_force_madv_wipeonfork_enabled);
static void init_fork_detect(void) {
- if (*g_ignore_madv_wipeonfork_bss_get()) {
+ if (*g_force_madv_wipeonfork_bss_get()) {
return;
}
@@ -93,7 +94,14 @@
// not assume that it has exclusive access to it.
volatile char *const flag_ptr = *g_fork_detect_addr_bss_get();
if (flag_ptr == NULL) {
- // Our kernel is too old to support |MADV_WIPEONFORK|.
+ // Our kernel is too old to support |MADV_WIPEONFORK| or
+ // |g_force_madv_wipeonfork| is set.
+ if (*g_force_madv_wipeonfork_bss_get() &&
+ *g_force_madv_wipeonfork_enabled_bss_get()) {
+ // A constant generation number to simulate support, even if the kernel
+ // doesn't support it.
+ return 42;
+ }
return 0;
}
@@ -125,8 +133,9 @@
return current_generation;
}
-void CRYPTO_fork_detect_ignore_madv_wipeonfork_for_testing(void) {
- *g_ignore_madv_wipeonfork_bss_get() = 1;
+void CRYPTO_fork_detect_force_madv_wipeonfork_for_testing(int on) {
+ *g_force_madv_wipeonfork_bss_get() = 1;
+ *g_force_madv_wipeonfork_enabled_bss_get() = on;
}
#else // !OPENSSL_LINUX
diff --git a/crypto/fipsmodule/rand/fork_detect.h b/crypto/fipsmodule/rand/fork_detect.h
index 8518830..f9bbe02 100644
--- a/crypto/fipsmodule/rand/fork_detect.h
+++ b/crypto/fipsmodule/rand/fork_detect.h
@@ -38,9 +38,10 @@
// should only be used as a hardening measure.
OPENSSL_EXPORT uint64_t CRYPTO_get_fork_generation(void);
-// CRYPTO_fork_detect_ignore_madv_wipeonfork_for_testing is an internal detail
+// CRYPTO_fork_detect_force_madv_wipeonfork_for_testing is an internal detail
// used for testing purposes.
-OPENSSL_EXPORT void CRYPTO_fork_detect_ignore_madv_wipeonfork_for_testing(void);
+OPENSSL_EXPORT void CRYPTO_fork_detect_force_madv_wipeonfork_for_testing(
+ int on);
#if defined(__cplusplus)
} // extern C
diff --git a/crypto/fipsmodule/rand/urandom_test.cc b/crypto/fipsmodule/rand/urandom_test.cc
index d593b90..f92fe94 100644
--- a/crypto/fipsmodule/rand/urandom_test.cc
+++ b/crypto/fipsmodule/rand/urandom_test.cc
@@ -657,7 +657,11 @@
static std::vector<Event> TestFunctionPRNGModel(unsigned flags) {
std::vector<Event> ret;
bool getrandom_ready = false;
- const bool used_daemon = kUsesDaemon && AppendDaemonEvents(&ret, flags);
+ 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));
@@ -714,8 +718,13 @@
const size_t kAdditionalDataLength = 32;
if (!have_rdrand()) {
- if ((!have_fork_detection() && !sysrand(true, kAdditionalDataLength)) ||
- // Initialise CRNGT.
+ 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)) ||
@@ -816,7 +825,9 @@
::testing::InitGoogleTest(&argc, argv);
if (getenv("BORINGSSL_IGNORE_MADV_WIPEONFORK")) {
- CRYPTO_fork_detect_ignore_madv_wipeonfork_for_testing();
+ CRYPTO_fork_detect_force_madv_wipeonfork_for_testing(0);
+ } else {
+ CRYPTO_fork_detect_force_madv_wipeonfork_for_testing(1);
}
return RUN_ALL_TESTS();