Skip to content
Commit ac3bf240 authored by Simon Tatham's avatar Simon Tatham Committed by Colin Watson
Browse files

Fix one-byte buffer overrun in random_add_noise().

The variable 'poolpos' is incremented by two functions: random_byte(),
which reads from the pool, and random_add_noise(), which writes to it.
Both of them must handle the case where poolpos reaches its upper
limit POOLSIZE, wrap poolpos round to the bottom, and trigger a
random_stir().

Unfortunately, random_byte checks that poolpos < POOLSIZE _before_ the
read, so it may leave poolpos==POOLSIZE on exit. And random_add_noise
does it the other way round - it assumes it's safe to write the first
byte _before_ doing the bounds check. So if exactly the right number
of random_byte calls happen before the next add_noise, then a byte of
entropy can be XORed into the thing just beyond the end of pool[].

What _is_ beyond that point is the LSB of poolpos itself! Since
POOLSIZE is not a multiple of 256, this means that poolpos could be
made larger or smaller by this overwrite. If it's made larger, that's
the safe case - the subsequent bounds check will still fail, and then
poolpos will be reset anyway. (And this is also what will happen in
the very likely case that poolpos was cached in a register during that
part of the function.)

The dangerous case is if poolpos is made _smaller_ by that overwrite.
In that situation, the effect will be to rewind the position in the
random pool, delaying a necessary random_stir() and causing
already-output random numbers to either be reused, or to be reused
combined with unhashed input noise. In the latter case, it's just
conceivable that an attacker who was somehow controlling at least one
entropy source might be able to manipulate the RNG output on demand.

Last-Update: 2019-03-16

Patch-Name: random-add-noise-overrun.patch
parent 56d59111
Loading
Loading
Loading
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment