NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

kern/44190: Kernel crash when using ioctl(RNDADDDATA) on /dev/random



>Number:         44190
>Category:       kern
>Synopsis:       Kernel crash when using ioctl(RNDADDDATA) on /dev/random
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    kern-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Fri Dec 03 17:10:01 +0000 2010
>Originator:     Michael Graff
>Release:        5.1
>Organization:
>Environment:
NetBSD not.flame.org 5.1 NetBSD 5.1 (GENERIC) #0: Sat Nov 20 17:35:12 UCT 2010  
root%netbsd-amd64-5.lab.flame.org@localhost:/u1/os-build/amd64/obj/sys/arch/amd64/compile/GENERIC
 amd64
>Description:
I can crash my NetBSD kernel reliably by using the ioctl(RNDADDDATA) call on 
/dev/random.
>How-To-Repeat:
This code attempts to read from a hardware generator and feed that data into 
the random pool.

#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/rnd.h>

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <err.h>
#include <string.h>

int
get_stored_entropy(int fd)
{
        rndpoolstat_t rs;

        if (ioctl(fd, RNDGETPOOLSTAT, &rs) < 0)
                err(1, "ioctl(RNDGETPOOLSTAT)");

        return (rs.maxentropy - rs.curentropy);
}

#define min(a, b) ((a) < (b) ? (a) : (b))

void
fill(int devrandom, int trng, int bits)
{
        rnddata_t rnddata;
        int read_bytes;

        int bytes = bits / 8;

        bytes = min(bytes, sizeof(rnddata.data));
        printf("Filling %d bytes\n", bytes);

        read_bytes = read(trng, &rnddata.data, bytes);
        rnddata.len = read_bytes;
        rnddata.entropy = read_bytes * 8; // pure trng data

        if (bytes != read_bytes)
                printf("short read: wanted %d, read %d\n", bytes, read_bytes);

        if (ioctl(devrandom, RNDADDDATA, &rnddata) < 0)
                err(1, "ioctl(RNDADDDATA)");
}       

int
main(int argc, char **argv)
{
        int fd;
        int hw;
        int bits;

        fd = open("/dev/urandom", O_RDONLY, 0644);
        if (fd < 0)
                err(1, "open");


        hw = open("/dev/ugen0.01", O_RDONLY, 0644);
        if (fd < 0)
                err(1, "open");

        while (1) {
                bits = get_stored_entropy(fd);
                if (bits > 1024)
                        fill(fd, hw, bits);
                else
                        usleep(1000);
        }

        close(fd);
}
>Fix:



Home | Main Index | Thread Index | Old Index