Re: Memory corruption with 2.3.18

Theodore Y. Ts'o (tytso@mit.edu)
Sun, 19 Sep 1999 07:50:18 -0400


>I cannot believe nobody hit it before, I must have missed a linux-kernel
>thread. &secret+3 produces a pointer at three sizes of the array away
>and way over the array boundaries.

Pete, and Andrey,

Good catch! Yup, that's definitely a problem. I have no idea how we've
gone so long without anyone catching this, since the problem exists in
the 2.2 kernels as well.

Alan, here's a patch for the 2.3-ac patches. It includes another
workaround to deal with the problem that the IRDA drivers are calling
get_random_bytes before the random driver is initialized, and this
causes kernel panic. We still need to fix the ordering problem (or IRDA
needs to defer its call to get_random_bytes), but at least this way the
kernel won't crash. The IRDA driver will *not* be getting a random
number for its services, so we do need to fix this before 2.4. But
adding a failsafe to get_random_bytes() is a good idea anyway....

- Ted

Patch generated: on Sun Sep 19 07:50:10 EDT 1999 by tytso@snap.thunk.org
against Linux version 2.3.18

--- drivers/char/random.c 1999/09/19 11:34:36 1.1
+++ drivers/char/random.c 1999/09/19 11:50:07
@@ -1,7 +1,7 @@
/*
* random.c -- A strong random number generator
*
- * Version 1.88, last modified 30-Aug-99
+ * Version 1.89, last modified 19-Sep-99
*
* Copyright Theodore Ts'o, 1994, 1995, 1996, 1997, 1998, 1999. All
* rights reserved.
@@ -1329,8 +1329,14 @@
*/
void get_random_bytes(void *buf, int nbytes)
{
- extract_entropy(sec_random_state, (char *) buf, nbytes,
- EXTRACT_ENTROPY_SECONDARY);
+ if (sec_random_state)
+ extract_entropy(sec_random_state, (char *) buf, nbytes,
+ EXTRACT_ENTROPY_SECONDARY);
+ else if (random_state)
+ extract_entropy(random_state, (char *) buf, nbytes, 0);
+ else
+ printk(KERN_NOTICE "get_random_bytes called before "
+ "random driver initialization\n");
}

/*********************************************************************
@@ -2012,7 +2018,7 @@
if (!rekey_time || (tv.tv_sec - rekey_time) > REKEY_INTERVAL) {
rekey_time = tv.tv_sec;
/* First three words are overwritten below. */
- get_random_bytes(&secret+3, sizeof(secret)-12);
+ get_random_bytes(&secret[3], sizeof(secret)-12);
count = (tv.tv_sec/REKEY_INTERVAL) << HASH_BITS;
}

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/