]> git.ipfire.org Git - people/arne_f/kernel.git/commitdiff
random: fix bound check ordering (CVE-2007-3105)
authorMatt Mackall <mpm@selenic.com>
Sat, 6 Oct 2007 22:27:53 +0000 (00:27 +0200)
committerAdrian Bunk <bunk@kernel.org>
Sat, 6 Oct 2007 22:27:53 +0000 (00:27 +0200)
If root raised the default wakeup threshold over the size of the
output pool, the pool transfer function could overflow the stack with
RNG bytes, causing a DoS or potential privilege escalation.

(Bug reported by the PaX Team <pageexec@freemail.hu>)

Signed-off-by: Matt Mackall <mpm@selenic.com>
Signed-off-by: Adrian Bunk <bunk@kernel.org>
drivers/char/random.c

index f162618d0f7ff753f8d5a852d8f6d82ba41dcc1e..3b0f11d684086da44da6b1472b253557c32ad145 100644 (file)
@@ -691,9 +691,14 @@ static void xfer_secondary_pool(struct entropy_store *r, size_t nbytes)
 
        if (r->pull && r->entropy_count < nbytes * 8 &&
            r->entropy_count < r->poolinfo->POOLBITS) {
-               int bytes = max_t(int, random_read_wakeup_thresh / 8,
-                               min_t(int, nbytes, sizeof(tmp)));
+               /* If we're limited, always leave two wakeup worth's BITS */
                int rsvd = r->limit ? 0 : random_read_wakeup_thresh/4;
+               int bytes = nbytes;
+
+               /* pull at least as many as BYTES as wakeup BITS */
+               bytes = max_t(int, bytes, random_read_wakeup_thresh / 8);
+               /* but never more than the buffer size */
+               bytes = min_t(int, bytes, sizeof(tmp));
 
                DEBUG_ENT("going to reseed %s with %d bits "
                          "(%d of %d requested)\n",