tech-kern archive

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

Re: locking against myself panic (cprng_strongreseed, filt_rndread)



Short: Your patch seems to work.

Long: I don't quite understand the behaviour, but at least, it doesn't panic.

I wrote a test programm (my first encounter with kqueue, so probably wrong) 
to exercise EVFILT_READ.
I created a named pipe and it did approximately what I expected (on start, 
it hung in fiford, which I didn't expect).
I wanted to test in on /dev/urandom, it read 512 bytes, then timed out 
(program wrote dots) and paniced (same traceback as originally) after 
about 15 of them.
On /dev/random, it read 512 bytes, wrote dots and didn't panic (at least 
not for 20 seconds). On a second run on /dev/random, it read 512 bytes 
and paniced immediately after.

With the patch, it read behaved identically on the first run; on the second, 
it read about twenty 512-byte chunks and continued writing dots (if I 
remember correctly). In any case, I couldn't make it panic.
#include <stdio.h>
#include <unistd.h>
#include <err.h>
#include <fcntl.h>
#include <sys/event.h>
#include <sys/time.h>

int main(int argc, char *argv[]) {
	int fd;
	int kq;
	struct kevent ev;
	int nev;
	const struct timespec tout = { 1, 0 };
	int i;
	char buf[1024];

	if (argc != 2)
		errx(1, "argc");
	if ((fd = open(argv[1], O_RDONLY)) == -1)
		err(1, "open %s", argv[1]);
	if ((kq = kqueue()) == -1)
		err(1, "kqueue");
	EV_SET(&ev, fd, EVFILT_READ, EV_ADD | EV_ENABLE | EV_CLEAR, 0, 0, 0);
	if (kevent(kq, &ev, 1, NULL, 0, &tout) == -1)
		err(1, "kevent1");
	for (;;) {
		if ((nev = kevent(kq, NULL, 0, &ev, 1, &tout)) == -1)
			err(1, "kevent2");
		if (nev == 0) {
			fputc('.', stdout); fflush(stdout); continue;
		}
		i = ev.data;
		printf("%d", i); fflush(stdout);
		if (i > sizeof buf)
			i = sizeof buf;
		if (read(fd, buf, i) == -1)
			err(1, "read");
	}
	(void)close(kq);
	(void)close(fd);
}


Home | Main Index | Thread Index | Old Index