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 */