]> git.ipfire.org Git - thirdparty/shadow.git/commitdiff
lib/csrand.c: Fix the lower part of the domain of csrand_uniform()
authorAlejandro Colomar <alx@kernel.org>
Wed, 19 Jun 2024 17:54:16 +0000 (19:54 +0200)
committerAlejandro Colomar <alx@kernel.org>
Fri, 21 Jun 2024 08:58:22 +0000 (10:58 +0200)
I accidentally broke this code during an un-optimization.  We need to
start from a random value of the width of the limit, that is, 32 bits.

Thanks to Jason for pointing to his similar code in the kernel, which
made me see my mistake.

Fixes: 2a61122b5e8f ("Unoptimize the higher part of the domain of csrand_uniform()")
Closes: <https://github.com/shadow-maint/shadow/issues/1015>
Reported-by: Michael Brunnbauer <https://github.com/michaelbrunnbauer>
Link: <https://git.zx2c4.com/linux-rng/tree/drivers/char/random.c#n535>
Cc: "Jason A. Donenfeld" <Jason@zx2c4.com>
Link: <https://github.com/shadow-maint/shadow/pull/638>
Link: <https://github.com/shadow-maint/shadow/issues/634>
Link: <https://github.com/shadow-maint/shadow/pull/624>
Tested-by: Michael Brunnbauer <https://github.com/michaelbrunnbauer>
Reviewed-by: Michael Brunnbauer <https://github.com/michaelbrunnbauer>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
Cherry-picked-from: 4119a2dce564 ("lib/csrand.c: Fix the lower part of the domain of csrand_uniform()")
Cc: "Serge E. Hallyn" <serge@hallyn.com>
Link: <https://github.com/shadow-maint/shadow/pull/1025>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
lib/csrand.c

index e85eaa8a4b44e83b40e22d1fd3bbbe4f6847f0af..16bcccf01db9685793ab74f13504338485f240c9 100644 (file)
@@ -22,6 +22,7 @@
 #include "shadowlog.h"
 
 
+static uint32_t csrand32(void);
 static uint32_t csrand_uniform32(uint32_t n);
 static unsigned long csrand_uniform_slow(unsigned long n);
 
@@ -96,6 +97,13 @@ csrand_interval(unsigned long min, unsigned long max)
 }
 
 
+static uint32_t
+csrand32(void)
+{
+       return csrand();
+}
+
+
 /*
  * Fast Random Integer Generation in an Interval
  * ACM Transactions on Modeling and Computer Simulation 29 (1), 2019
@@ -108,12 +116,12 @@ csrand_uniform32(uint32_t n)
        uint64_t  r, mult;
 
        if (n == 0)
-               return csrand();
+               return csrand32();
 
        bound = -n % n;  // analogous to `2^32 % n`, since `x % y == (x-y) % y`
 
        do {
-               r = csrand();
+               r = csrand32();
                mult = r * n;
                rem = mult;  // analogous to `mult % 2^32`
        } while (rem < bound);  // p = (2^32 % n) / 2^32;  W.C.: n=2^31+1, p=0.5