NetBSD-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: kern/48119 (/dev/random kernel crash)
The following reply was made to PR kern/48119; it has been noted by GNATS.
From: Sergio Lopez <slp%sinrega.org@localhost>
To: gnats-bugs%NetBSD.org@localhost
Cc: brad.harder%gmail.com@localhost
Subject: Re: kern/48119 (/dev/random kernel crash)
Date: Wed, 28 Aug 2013 07:37:31 +0000
--tKW2IUtsqtDRztdT
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
rnd_read(rndpseudo.c) assumes cprng_strong will only return 0 when
processing a non-blocking request, but as the latter can eventually
sit on cv_wait_sig waiting for entropy, this will also happen when the
request is interrupted, which is what is happening here.
As as PoC, I've modified (see attached file) cprng_strong to return -1
when cv_wait_sig is interrupted, and rnd_read to detect this and bail
out. Probably, it would be better to extend cprng_strong so it returns
the error code in addition to the number of bytes read.
--tKW2IUtsqtDRztdT
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="pr48119.diff"
Index: kern/subr_cprng.c
===================================================================
RCS file: /cvsroot/src/sys/kern/subr_cprng.c,v
retrieving revision 1.22
diff -u -r1.22 subr_cprng.c
--- kern/subr_cprng.c 27 Jul 2013 11:19:09 -0000 1.22
+++ kern/subr_cprng.c 28 Aug 2013 07:36:29 -0000
@@ -180,6 +180,7 @@
size_t
cprng_strong(struct cprng_strong *cprng, void *buffer, size_t bytes, int
flags)
{
+ int error;
size_t result;
/* Caller must loop for more than CPRNG_MAX_LEN bytes. */
@@ -193,11 +194,16 @@
} else {
while (!cprng->cs_ready) {
if (ISSET(flags, FNONBLOCK) ||
- !ISSET(cprng->cs_flags, CPRNG_USE_CV) ||
- cv_wait_sig(&cprng->cs_cv, &cprng->cs_lock)) {
+ !ISSET(cprng->cs_flags, CPRNG_USE_CV)) {
result = 0;
goto out;
}
+
+ error = cv_wait_sig(&cprng->cs_cv, &cprng->cs_lock);
+ if (error) {
+ result = -1;
+ goto out;
+ }
}
}
Index: dev/rndpseudo.c
===================================================================
RCS file: /cvsroot/src/sys/dev/rndpseudo.c,v
retrieving revision 1.16
diff -u -r1.16 rndpseudo.c
--- dev/rndpseudo.c 21 Jul 2013 22:30:19 -0000 1.16
+++ dev/rndpseudo.c 28 Aug 2013 07:36:35 -0000
@@ -375,6 +375,12 @@
((ctx->rc_hard && ISSET(fp->f_flag, FNONBLOCK))?
FNONBLOCK : 0));
+ if (n_read == -1) {
+ printf("rnd EINTR\n");
+ error = EINTR;
+ goto out;
+ }
+
/*
* Equality will hold unless this is /dev/random, in
* which case we get only as many bytes as are left
--tKW2IUtsqtDRztdT--
Home |
Main Index |
Thread Index |
Old Index