]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Move random number re-seeding out of the hot path
authorTony Finch <fanf@isc.org>
Fri, 22 Apr 2022 13:35:36 +0000 (14:35 +0100)
committerOndřej Surý <ondrej@isc.org>
Mon, 19 Sep 2022 14:27:12 +0000 (16:27 +0200)
Instead of checking if we need to re-seed for every isc_random call,
seed the random number generator in the libisc global initializer
and the per-thread initializer.

lib/isc/Makefile.am
lib/isc/random.c
lib/isc/random_p.h [new file with mode: 0644]
lib/isc/trampoline.c
tests/isc/random_test.c

index adc147b96835fc3a31102e243adbd8abeb7a05a9..c23ebf31380c661145049144499d17930b8efc12 100644 (file)
@@ -180,6 +180,7 @@ libisc_la_SOURCES =         \
        quota.c                 \
        radix.c                 \
        random.c                \
+       random_p.h              \
        ratelimiter.c           \
        regex.c                 \
        region.c                \
index 842f4e4fe3f9b0e3be394eedefde735c7b8bfa4d..8f804360dbd953846317b1d5ed8aa3403b83cb1b 100644 (file)
@@ -35,7 +35,6 @@
 #include <string.h>
 #include <unistd.h>
 
-#include <isc/once.h>
 #include <isc/random.h>
 #include <isc/result.h>
 #include <isc/thread.h>
@@ -43,6 +42,7 @@
 #include <isc/util.h>
 
 #include "entropy_private.h"
+#include "random_p.h"
 
 /*
  * Written in 2018 by David Blackman and Sebastiano Vigna (vigna@acm.org)
@@ -88,11 +88,8 @@ next(void) {
 
        return (result_starstar);
 }
-
-static thread_local isc_once_t isc_random_once = ISC_ONCE_INIT;
-
-static void
-isc_random_initialize(void) {
+void
+isc__random_initialize(void) {
        int useed[4] = { 0, 0, 0, 1 };
 #if FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
        /*
@@ -108,22 +105,16 @@ isc_random_initialize(void) {
 
 uint8_t
 isc_random8(void) {
-       RUNTIME_CHECK(isc_once_do(&isc_random_once, isc_random_initialize) ==
-                     ISC_R_SUCCESS);
        return ((uint8_t)next());
 }
 
 uint16_t
 isc_random16(void) {
-       RUNTIME_CHECK(isc_once_do(&isc_random_once, isc_random_initialize) ==
-                     ISC_R_SUCCESS);
        return ((uint16_t)next());
 }
 
 uint32_t
 isc_random32(void) {
-       RUNTIME_CHECK(isc_once_do(&isc_random_once, isc_random_initialize) ==
-                     ISC_R_SUCCESS);
        return (next());
 }
 
@@ -135,9 +126,6 @@ isc_random_buf(void *buf, size_t buflen) {
        REQUIRE(buf != NULL);
        REQUIRE(buflen > 0);
 
-       RUNTIME_CHECK(isc_once_do(&isc_random_once, isc_random_initialize) ==
-                     ISC_R_SUCCESS);
-
        for (i = 0; i + sizeof(r) <= buflen; i += sizeof(r)) {
                r = next();
                memmove((uint8_t *)buf + i, &r, sizeof(r));
@@ -149,8 +137,6 @@ isc_random_buf(void *buf, size_t buflen) {
 
 uint32_t
 isc_random_uniform(uint32_t limit) {
-       RUNTIME_CHECK(isc_once_do(&isc_random_once, isc_random_initialize) ==
-                     ISC_R_SUCCESS);
        /*
         * Daniel Lemire's nearly-divisionless unbiased bounded random numbers.
         *
diff --git a/lib/isc/random_p.h b/lib/isc/random_p.h
new file mode 100644 (file)
index 0000000..3e4917f
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+ *
+ * SPDX-License-Identifier: MPL-2.0
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, you can obtain one at https://mozilla.org/MPL/2.0/.
+ *
+ * See the COPYRIGHT file distributed with this work for additional
+ * information regarding copyright ownership.
+ */
+
+#pragma once
+
+#include <isc/lang.h>
+
+/*! \file isc/random_p.h
+ * \brief For automatically seeding and re-seeding when required.
+ */
+
+ISC_LANG_BEGINDECLS
+
+void
+isc__random_initialize(void);
+/*!<
+ * \brief Seed the thread-local random number state with fresh entropy.
+ */
+
+ISC_LANG_ENDDECLS
index b724b7445062746d4efe9d087490affcc31f3c85..c862ba37b0beef6ddbcea2603a307d46de7b9eaa 100644 (file)
@@ -22,6 +22,7 @@
 #include <isc/util.h>
 #include <isc/uv.h>
 
+#include "random_p.h"
 #include "trampoline_p.h"
 
 #define ISC__TRAMPOLINE_UNUSED 0
@@ -87,6 +88,8 @@ isc__trampoline_initialize(void) {
                trampolines[i] = NULL;
        }
        isc__trampoline_min = 1;
+
+       isc__random_initialize();
 }
 
 void
@@ -175,6 +178,12 @@ isc__trampoline_attach(isc__trampoline_t *trampoline) {
         * malloc() + free() calls altogether, as it would foil the fix.
         */
        trampoline->jemalloc_enforce_init = malloc(8);
+
+       /*
+        * Re-seed the random number generator in each thread.
+        */
+       isc__random_initialize();
+
        uv_mutex_unlock(&isc__trampoline_lock);
 }
 
index 8c41e9713826777ddb60bd2f1ba27cd16cf08a77..1651dbba748cc3e6a7ba9e0c585a41707381eea1 100644 (file)
@@ -640,6 +640,13 @@ binarymatrixrank(uint16_t *values, size_t length) {
  *** Tests for isc_random32() function
  ***/
 
+/* Ensure the RNG has been automatically seeded. */
+ISC_RUN_TEST_IMPL(isc_random32_initialized) {
+       UNUSED(state);
+
+       assert_int_not_equal(isc_random32(), 0);
+}
+
 /* Monobit test for the RANDOM */
 ISC_RUN_TEST_IMPL(isc_random32_monobit) {
        UNUSED(state);
@@ -764,6 +771,7 @@ ISC_RUN_TEST_IMPL(isc_nonce_bytes_binarymatrixrank) {
 
 ISC_TEST_LIST_START
 
+ISC_TEST_ENTRY(isc_random32_initialized)
 ISC_TEST_ENTRY(isc_random32_monobit)
 ISC_TEST_ENTRY(isc_random32_runs)
 ISC_TEST_ENTRY(isc_random32_blockfrequency)