comphelper/source/misc/random.cxx | 34 ++++++++++++++++++---------------- desktop/source/lib/init.cxx | 4 ++++ include/comphelper/random.hxx | 2 ++ 3 files changed, 24 insertions(+), 16 deletions(-)
New commits: commit a2605a66fdb8ab18018f3a0f8e49043e73854986 Author: Michael Meeks <[email protected]> AuthorDate: Fri May 3 14:17:27 2024 +0100 Commit: Michael Meeks <[email protected]> CommitDate: Tue May 7 09:51:13 2024 +0200 lok: reseed comphelper's random number generator on fork. Also avoid std::random_device it doesn't work in a COOL kit process. Change-Id: Ie2d063611a73e734afd92d6fd779f34a2f316230 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167070 Tested-by: Jenkins Reviewed-by: Michael Meeks <[email protected]> diff --git a/comphelper/source/misc/random.cxx b/comphelper/source/misc/random.cxx index 96d466641dfb..058eb99813eb 100644 --- a/comphelper/source/misc/random.cxx +++ b/comphelper/source/misc/random.cxx @@ -16,6 +16,7 @@ #include <time.h> #include <mutex> #include <random> +#include <rtl/random.h> #include <stdexcept> #if defined HAVE_VALGRIND_HEADERS #include <valgrind/memcheck.h> @@ -40,7 +41,9 @@ struct RandomNumberGenerator { std::mutex mutex; STD_RNG_ALGO global_rng; - RandomNumberGenerator() + RandomNumberGenerator() { reseed(); } + + void reseed() { // make RR easier to use, breaks easily without the RNG being repeatable bool bRepeatable = (getenv("SAL_RAND_REPEATABLE") != nullptr) || (getenv("RR") != nullptr); @@ -56,21 +59,18 @@ struct RandomNumberGenerator return; } - try - { - std::random_device rd; - // initialises the state of the global random number generator - // should only be called once. - // (note, a few std::variate_generator<> (like normal) have their - // own state which would need a reset as well to guarantee identical - // sequence of numbers, e.g. via myrand.distribution().reset()) - global_rng.seed(rd() ^ time(nullptr)); - } - catch (std::runtime_error& e) - { - SAL_WARN("comphelper", "Using std::random_device failed: " << e.what()); - global_rng.seed(time(nullptr)); - } + size_t seed = 0; + rtlRandomPool aRandomPool = rtl_random_createPool(); + if (rtl_random_getBytes(aRandomPool, &seed, sizeof(seed)) != rtl_Random_E_None) + seed = 0; + rtl_random_destroyPool(aRandomPool); + + // initialises the state of the global random number generator + // should only be called once. + // (note, a few std::variate_generator<> (like normal) have their + // own state which would need a reset as well to guarantee identical + // sequence of numbers, e.g. via myrand.distribution().reset()) + global_rng.seed(seed ^ time(nullptr)); } }; @@ -81,6 +81,8 @@ RandomNumberGenerator& GetTheRandomNumberGenerator() } } +void reseed() { GetTheRandomNumberGenerator().reseed(); } + // uniform ints [a,b] distribution int uniform_int_distribution(int a, int b) { diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx index ce1ba38334f6..28ba524ad0eb 100644 --- a/desktop/source/lib/init.cxx +++ b/desktop/source/lib/init.cxx @@ -76,6 +76,7 @@ #include <rtl/uri.hxx> #include <linguistic/misc.hxx> #include <cppuhelper/bootstrap.hxx> +#include <comphelper/random.hxx> #include <comphelper/base64.hxx> #include <comphelper/dispatchcommand.hxx> #include <comphelper/lok.hxx> @@ -7969,7 +7970,10 @@ static int lo_initialize(LibreOfficeKit* pThis, const char* pAppPath, const char } rtl::Bootstrap::set(u"UserInstallation"_ustr, url); if (eStage == SECOND_INIT) + { + comphelper::rng::reseed(); utl::Bootstrap::reloadData(); + } } OUString aAppPath; diff --git a/include/comphelper/random.hxx b/include/comphelper/random.hxx index 345d57c7158d..1fe4dc5fdf58 100644 --- a/include/comphelper/random.hxx +++ b/include/comphelper/random.hxx @@ -17,6 +17,8 @@ namespace comphelper::rng // These functions obey the SAL_RAND_REPEATABLE environment // variable: If it is set, use a fixed seed. +COMPHELPER_DLLPUBLIC void reseed(); + // note that uniform_int_distribution is inclusive of b, i.e. [a,b] while // uniform_real_distribution is exclusive of b, i.e. [a,b), std::nextafter may be your friend there
