srand() should be called only once
| Vulnerability potential | Low |
| DDoS potential | None |
srand() shouldn’t be called more than once
Impact
srand sets the seed of the C library’s pseudo-random generator. It is meant
to be called exactly once, at startup. Calling it repeatedly — especially inside
a loop or before every rand — resets the generator’s state each time, so the
sequence restarts instead of advancing. A very common form is
srand(time(NULL)) called in a tight loop: time has one-second resolution,
so every iteration within the same second reseeds with the identical value and
rand returns the same number over and over. The result is output that looks
random across runs but is highly repetitive within a run, with far less entropy
than intended. Code that depends on distinct values — shuffles, sampling, jitter,
unique-ish tokens, backoff timers — quietly misbehaves.
Vulnerability potential
rand/srand are not cryptographically secure regardless of seeding, so
this defect should never affect security-critical values; if it does, the real
bug is using rand for security at all. Within that limitation, the reseeding
makes the output even more predictable, which can matter where weak randomness is
already (wrongly) relied upon — for example reusing the same “random” token,
nonce or temporary filename because the same seed produced the same first value.
There is no memory-safety or availability impact, hence no DoS dimension.
Technical details
The standard PRNG keeps internal state that rand advances on each call;
srand(seed) overwrites that state with a deterministic function of seed.
Reseeding therefore discards all the advancement done since the last seed.
time(NULL) granularity
time returns whole seconds. Reseeding from it more than once per second
yields identical seeds, so the first rand after each reseed is identical.
This is the classic “my random numbers are all the same” bug.
Determinism is sometimes intended
Seeding once with a fixed value for reproducible tests is legitimate; the defect is re-seeding during normal operation, which neither improves randomness nor adds entropy — the entropy of the output is bounded by the entropy of the seed, not by how often you apply it.
Modern alternatives
C++ <random> (std::mt19937 seeded once from std::random_device) and
POSIX random/srandom have the same once-only seeding rule. For security,
use a CSPRNG (getrandom, arc4random, /dev/urandom), not rand.
Catching the issue
Static analysis
PVS-Studio (V1041-class checks), Clang-Tidy, Coverity and PC-lint flag srand
called inside a loop or more than once. A simple code-review rule — “exactly one
srand near program start” — catches most cases.
Review and runtime
Search the codebase for multiple srand call sites; there should be one.
Observing repeated identical rand outputs within a single run is the runtime
symptom. Move the single srand to initialization and never call it again.
How to reproduce
Run the program; every printed value is identical because the loop reseeds with the same one-second timestamp each iteration.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(void)
{
for (int i = 0; i < 5; i++) {
srand(time(NULL)); /* WRONG: reseeds every iteration */
printf("%d\n", rand()); /* prints the same number five times */
}
return 0;
}