COMMAND
kernel
SYSTEMS AFFECTED
Linux
PROBLEM
Andrea Arcangeli posted following. After having read phrak54
about Linux /dev/u?random she was playing a bit with the random
driver it and noticed that was difficult to kill
dd if=/dev/urandom of=/dev/null bs=100000k count=20000
once started. The machine was eavily loaded and the process was
unkillable and the fastest thing to restore the system has been a
reset. It's a bug in random.c that doesn' t check for signal
pending inside the read(2) code, so you have no chance to kill the
process via signals until the read(2) syscall is finished, and it
could take a lot of time before return, if the buffer given to the
read syscall is very big...
SOLUTION
Here the fix against 2.1.132:
Index: linux/drivers/char/random.c
diff -u linux/drivers/char/random.c:1.1.1.1 linux/drivers/char/random.c:1.1.1.1.2.3
--- linux/drivers/char/random.c:1.1.1.1 Fri Nov 20 00:02:25 1998
+++ linux/drivers/char/random.c Sun Dec 27 20:19:16 1998
@@ -232,6 +232,11 @@
* Eastlake, Steve Crocker, and Jeff Schiller.
*/
+/*
+ * Added a check for signal pending in the extract_entropy() loop to allow
+ * the read(2) syscall to be interrupted. Copyright (C) 1998 Andrea Arcangeli
+ */
+
#include <linux/utsname.h>
#include <linux/config.h>
#include <linux/kernel.h>
@@ -1269,7 +1274,14 @@
buf += i;
add_timer_randomness(r, &extract_timer_state, nbytes);
if (to_user && current->need_resched)
+ {
+ if (signal_pending(current))
+ {
+ ret = -EINTR;
+ break;
+ }
schedule();
+ }
}
/* Wipe data just returned from memory */
And here a fix against 2.0.36:
--- linux/drivers/char/random.c.orig Sun Dec 27 20:22:53 1998
+++ linux/drivers/char/random.c Sun Dec 27 20:24:17 1998
@@ -226,6 +226,11 @@
* Eastlake, Steve Crocker, and Jeff Schiller.
*/
+/*
+ * Added a check for signal pending in the extract_entropy() loop to allow
+ * the read(2) syscall to be interrupted. Copyright (C) 1998 Andrea Arcangeli
+ */
+
#include <linux/config.h> /* CONFIG_RST_COOKIES and CONFIG_SYN_COOKIES */
#include <linux/utsname.h>
#include <linux/kernel.h>
@@ -1004,7 +1009,14 @@
buf += i;
add_timer_randomness(r, &extract_timer_state, nbytes);
if (to_user && need_resched)
+ {
+ if (signal_pending(current))
+ {
+ ret = -EINTR;
+ break;
+ }
schedule();
+ }
}
/* Wipe data from memory */