]> 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)
committerTony Finch <fanf@isc.org>
Fri, 22 Apr 2022 15:40:37 +0000 (16:40 +0100)
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/lib.c
lib/isc/random.c
lib/isc/random_p.h [new file with mode: 0644]
lib/isc/tests/random_test.c
lib/isc/trampoline.c

index c0bb69fa4ab3d33c33cc1c99a4192656146409a4..94f0a74d3f6d7215fdedbfda23e52d4178ba7b08 100644 (file)
@@ -170,6 +170,7 @@ libisc_la_SOURCES =         \
        quota.c                 \
        radix.c                 \
        random.c                \
+       random_p.h              \
        ratelimiter.c           \
        regex.c                 \
        region.c                \
index 7f6b12c4aa08235c8e726cefc439f114e0e0f24b..4d52c5bc2fcb7941006e5e7f400e9a5cc321bbca 100644 (file)
@@ -22,6 +22,7 @@
 #include "config.h"
 #include "mem_p.h"
 #include "os_p.h"
+#include "random_p.h"
 #include "tls_p.h"
 #include "trampoline_p.h"
 
@@ -42,6 +43,7 @@ void
 isc__initialize(void) {
        isc__os_initialize();
        isc__mem_initialize();
+       isc__random_initialize();
        isc__tls_initialize();
        isc__trampoline_initialize();
        (void)isc_os_ncpus();
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 040e1a5f7735bd0f5f8f0b2f048e6dd3a620124b..3d8cfdb260e38d261bbe2305627a35e392e77103 100644 (file)
@@ -87,6 +87,11 @@ _setup(void **state) {
        result = isc_test_begin(NULL, true, 0);
        assert_int_equal(result, ISC_R_SUCCESS);
 
+       /*
+        * Ensure the RNG has been seeded.
+        */
+       assert_int_not_equal(isc_random32(), 0);
+
        return (0);
 }
 
index fe01394b9e3c2c629f445af54e4b473a563e7f7c..a718e097e2a41de999fdcc471b38c4cecdb0e498 100644 (file)
@@ -22,6 +22,7 @@
 #include <isc/thread.h>
 #include <isc/util.h>
 
+#include "random_p.h"
 #include "trampoline_p.h"
 
 #define ISC__TRAMPOLINE_UNUSED 0
@@ -185,6 +186,11 @@ 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();
 }
 
 isc_threadresult_t