mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 06:38:20 +00:00
util/init_random_seed: write_file implies deterministic
This makes Zeek run in deterministic mode with --save-seeds usage and reworks all the extra indirections used in init_random_seed() to make it easier to follow the control flow. Fixes #4209
This commit is contained in:
parent
280e7acc6e
commit
a7cf057a63
5 changed files with 50 additions and 27 deletions
4
NEWS
4
NEWS
|
@ -27,6 +27,10 @@ Changed Functionality
|
||||||
then prompt to use --help. The --help usage will now print to standard output
|
then prompt to use --help. The --help usage will now print to standard output
|
||||||
rather than standard error.
|
rather than standard error.
|
||||||
|
|
||||||
|
- Saving seeds with ``--save-seeds`` will now put Zeek into deterministic mode.
|
||||||
|
A subsequent ``--load-seeds`` run with the same scripts and traces will produce
|
||||||
|
identical UID values as the original ``--save-seeds` run.
|
||||||
|
|
||||||
Removed Functionality
|
Removed Functionality
|
||||||
---------------------
|
---------------------
|
||||||
|
|
||||||
|
|
51
src/util.cc
51
src/util.cc
|
@ -363,9 +363,8 @@ static long int zeek_rand_state = 0;
|
||||||
static bool first_seed_saved = false;
|
static bool first_seed_saved = false;
|
||||||
static unsigned int first_seed = 0;
|
static unsigned int first_seed = 0;
|
||||||
|
|
||||||
static void zeek_srandom(unsigned int seed, bool deterministic) {
|
static void zeek_srandom(unsigned int seed) {
|
||||||
zeek_rand_state = seed == 0 ? 1 : seed;
|
zeek_rand_state = seed == 0 ? 1 : seed;
|
||||||
zeek_rand_deterministic = deterministic;
|
|
||||||
|
|
||||||
srandom(seed);
|
srandom(seed);
|
||||||
}
|
}
|
||||||
|
@ -380,26 +379,28 @@ void seed_random(unsigned int seed) {
|
||||||
void init_random_seed(const char* read_file, const char* write_file, bool use_empty_seeds,
|
void init_random_seed(const char* read_file, const char* write_file, bool use_empty_seeds,
|
||||||
const std::string& seed_string) {
|
const std::string& seed_string) {
|
||||||
std::array<uint32_t, zeek::detail::KeyedHash::SEED_INIT_SIZE> buf = {};
|
std::array<uint32_t, zeek::detail::KeyedHash::SEED_INIT_SIZE> buf = {};
|
||||||
size_t pos = 0; // accumulates entropy
|
|
||||||
bool seeds_done = false;
|
|
||||||
uint32_t seed = 0;
|
uint32_t seed = 0;
|
||||||
|
|
||||||
if ( read_file ) {
|
if ( write_file )
|
||||||
if ( ! read_random_seeds(read_file, &seed, buf) )
|
// run in deterministic mode when we write a file
|
||||||
reporter->FatalError("Could not load seeds from file '%s'.", read_file);
|
zeek_rand_deterministic = true;
|
||||||
else
|
|
||||||
seeds_done = true;
|
if ( read_file || use_empty_seeds || ! seed_string.empty() ) {
|
||||||
}
|
// if a seed is provided - run Zeek in deterministic mode
|
||||||
else if ( ! seed_string.empty() ) {
|
zeek_rand_deterministic = true;
|
||||||
if ( ! fill_random_seeds(seed_string, &seed, buf) )
|
|
||||||
reporter->FatalError("Could not load seeds from string");
|
if ( read_file ) {
|
||||||
else
|
if ( ! read_random_seeds(read_file, &seed, buf) )
|
||||||
seeds_done = true;
|
reporter->FatalError("Could not load seeds from file '%s'.", read_file);
|
||||||
}
|
}
|
||||||
else if ( use_empty_seeds )
|
else if ( ! seed_string.empty() ) {
|
||||||
seeds_done = true;
|
if ( ! fill_random_seeds(seed_string, &seed, buf) )
|
||||||
|
reporter->FatalError("Could not load seeds from string");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else { // no seed provided
|
||||||
|
size_t pos = 0; // accumulates entropy
|
||||||
|
|
||||||
if ( ! seeds_done ) {
|
|
||||||
#ifdef HAVE_GETRANDOM
|
#ifdef HAVE_GETRANDOM
|
||||||
// getrandom() guarantees reads up to 256 bytes are always successful,
|
// getrandom() guarantees reads up to 256 bytes are always successful,
|
||||||
assert(sizeof(buf) < 256);
|
assert(sizeof(buf) < 256);
|
||||||
|
@ -437,17 +438,13 @@ void init_random_seed(const char* read_file, const char* write_file, bool use_em
|
||||||
reporter->FatalError("Could not read enough random data. Wanted %d, got %zu",
|
reporter->FatalError("Could not read enough random data. Wanted %d, got %zu",
|
||||||
zeek::detail::KeyedHash::SEED_INIT_SIZE, pos);
|
zeek::detail::KeyedHash::SEED_INIT_SIZE, pos);
|
||||||
|
|
||||||
if ( ! seed ) {
|
for ( size_t i = 0; i < pos; ++i ) {
|
||||||
for ( size_t i = 0; i < pos; ++i ) {
|
seed ^= buf[i];
|
||||||
seed ^= buf[i];
|
seed = (seed << 1) | (seed >> 31);
|
||||||
seed = (seed << 1) | (seed >> 31);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
seeds_done = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
zeek_srandom(seed, seeds_done);
|
zeek_srandom(seed);
|
||||||
|
|
||||||
if ( ! first_seed_saved ) {
|
if ( ! first_seed_saved ) {
|
||||||
first_seed = seed;
|
first_seed = seed;
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63.
|
||||||
|
uid history service
|
||||||
|
CHhAvVGS1DHFjwGM9 ShADadFf http
|
|
@ -0,0 +1,3 @@
|
||||||
|
### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63.
|
||||||
|
uid history service
|
||||||
|
CHhAvVGS1DHFjwGM9 ShADadFf http
|
16
testing/btest/core/save-load-seeds.zeek
Normal file
16
testing/btest/core/save-load-seeds.zeek
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
# @TEST-DOC: Save seeds and read and assure the UIDs are the same. Regression test for #4209
|
||||||
|
#
|
||||||
|
# @TEST-EXEC: zeek --save-seeds myseeds -r $TRACES/http/get.trace %INPUT
|
||||||
|
# @TEST-EXEC: mkdir save && mv *log save
|
||||||
|
# @TEST-EXEC: zeek-cut -m uid history service < save/conn.log >save/conn.log.cut
|
||||||
|
#
|
||||||
|
# @TEST-EXEC: zeek --load-seeds myseeds -r $TRACES/http/get.trace %INPUT
|
||||||
|
# @TEST-EXEC: mkdir load && mv *log load
|
||||||
|
# @TEST-EXEC: zeek-cut -m uid history service < load/conn.log >load/conn.log.cut
|
||||||
|
#
|
||||||
|
# @TEST-EXEC: btest-diff load/conn.log.cut
|
||||||
|
# @TEST-EXEC: btest-diff save/conn.log.cut
|
||||||
|
# @TEST-EXEC: diff load/conn.log.cut save/conn.log.cut
|
||||||
|
|
||||||
|
@load base/protocols/conn
|
||||||
|
@load base/protocols/http
|
Loading…
Add table
Add a link
Reference in a new issue