mirror of
https://github.com/zeek/zeek.git
synced 2025-10-09 10:08:20 +00:00
GH-1076: Fix bro_prng() implementation
The intermediate result of the PRNG used unsigned storage, preventing the ( result < 0 ) branch from ever being evaluated. This could cause return values to exceed the modulus as well as RAND_MAX. One interesting effect of this is potential for the rand() BIF to return values outside the requested maximum limit. Another interesting effect of this is that a PacketFilter may start randomly dropping packets even if it was not configured for random-packet-drops.
This commit is contained in:
parent
dba764386b
commit
0f4eb9af02
3 changed files with 30 additions and 13 deletions
22
src/util.cc
22
src/util.cc
|
@ -1186,18 +1186,22 @@ bool have_random_seed()
|
|||
unsigned int bro_prng(unsigned int state)
|
||||
{
|
||||
// Use our own simple linear congruence PRNG to make sure we are
|
||||
// predictable across platforms.
|
||||
static const long int m = 2147483647;
|
||||
static const long int a = 16807;
|
||||
const long int q = m / a;
|
||||
const long int r = m % a;
|
||||
// predictable across platforms. (Lehmer RNG, Schrage's method)
|
||||
constexpr uint32_t m = 2147483647;
|
||||
constexpr uint32_t a = 16807;
|
||||
constexpr uint32_t q = m / a;
|
||||
constexpr uint32_t r = m % a;
|
||||
|
||||
state = a * ( state % q ) - r * ( state / q );
|
||||
uint32_t rem = state % q;
|
||||
uint32_t div = state / q;
|
||||
int32_t s = a * rem;
|
||||
int32_t t = r * div;
|
||||
int32_t res = s - t;
|
||||
|
||||
if ( state <= 0 )
|
||||
state += m;
|
||||
if ( res < 0 )
|
||||
res += m;
|
||||
|
||||
return state;
|
||||
return res;
|
||||
}
|
||||
|
||||
long int bro_random()
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue