From owner-freebsd-bugs@FreeBSD.ORG Wed Jan 27 19:00:02 2010 Return-Path: Delivered-To: freebsd-bugs@hub.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id F07BD106566C for ; Wed, 27 Jan 2010 19:00:01 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (freefall.freebsd.org [IPv6:2001:4f8:fff6::28]) by mx1.freebsd.org (Postfix) with ESMTP id C38A58FC12 for ; Wed, 27 Jan 2010 19:00:01 +0000 (UTC) Received: from freefall.freebsd.org (localhost [127.0.0.1]) by freefall.freebsd.org (8.14.3/8.14.3) with ESMTP id o0RJ01C7029464 for ; Wed, 27 Jan 2010 19:00:01 GMT (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.14.3/8.14.3/Submit) id o0RJ01vl029463; Wed, 27 Jan 2010 19:00:01 GMT (envelope-from gnats) Resent-Date: Wed, 27 Jan 2010 19:00:01 GMT Resent-Message-Id: <201001271900.o0RJ01vl029463@freefall.freebsd.org> Resent-From: FreeBSD-gnats-submit@FreeBSD.org (GNATS Filer) Resent-To: freebsd-bugs@FreeBSD.org Resent-Reply-To: FreeBSD-gnats-submit@FreeBSD.org, James Juran Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 431CC106566C for ; Wed, 27 Jan 2010 18:57:45 +0000 (UTC) (envelope-from nobody@FreeBSD.org) Received: from www.freebsd.org (www.freebsd.org [IPv6:2001:4f8:fff6::21]) by mx1.freebsd.org (Postfix) with ESMTP id 192998FC14 for ; Wed, 27 Jan 2010 18:57:45 +0000 (UTC) Received: from www.freebsd.org (localhost [127.0.0.1]) by www.freebsd.org (8.14.3/8.14.3) with ESMTP id o0RIviiS090817 for ; Wed, 27 Jan 2010 18:57:44 GMT (envelope-from nobody@www.freebsd.org) Received: (from nobody@localhost) by www.freebsd.org (8.14.3/8.14.3/Submit) id o0RIviL6090816; Wed, 27 Jan 2010 18:57:44 GMT (envelope-from nobody) Message-Id: <201001271857.o0RIviL6090816@www.freebsd.org> Date: Wed, 27 Jan 2010 18:57:44 GMT From: James Juran To: freebsd-gnats-submit@FreeBSD.org X-Send-Pr-Version: www-3.1 Cc: Subject: kern/143298: random_yarrow_block() doesn't actually block when not seeded X-BeenThere: freebsd-bugs@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Bug reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 27 Jan 2010 19:00:02 -0000 >Number: 143298 >Category: kern >Synopsis: random_yarrow_block() doesn't actually block when not seeded >Confidential: no >Severity: non-critical >Priority: low >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Wed Jan 27 19:00:01 UTC 2010 >Closed-Date: >Last-Modified: >Originator: James Juran >Release: FreeBSD-8.0 >Organization: BAE Systems >Environment: FreeBSD freebsd8.goldlnk.rootlnka.net 8.0-RELEASE FreeBSD 8.0-RELEASE #0: Sat Nov 21 15:48:17 UTC 2009 root@almeida.cse.buffalo.edu:/usr/obj/usr/src/sys/GENERIC i386 >Description: I believe r153575 introduced a problem with the /dev/random yarrow random number generator's blocking when it is not seeded. This has likely not been noticed until now because yarrow is marked as seeded when it is loaded by default, so someone would have to change the sysctl value from the default. This problem likely only affects users who want to do "better" seeding of /dev/random than is provided by /etc/rc.d/initrandom. In this change the blocking logic was moved from random_read() into a .block method for the particular random number generation method so that the GIANT lock could be removed. In doing this though, the loop guard appears to have been inadvertently changed from while (!random_systat.seeded && !error) to while (random_systat.seeded && !error) >How-To-Repeat: In FreeBSD 8.0, this incorrect behavior can be observed by doing: // By default it is seeded and outputs data; no problem here [root@freebsd8 ~]# sysctl kern.random.sys.seeded kern.random.sys.seeded: 1 [root@freebsd8 ~]# time dd if=/dev/random bs=1 count=1 =1+0 records in 1+0 records out 1 bytes transferred in 0.000006 secs (167772 bytes/sec) real 0m0.005s user 0m0.000s sys 0m0.006s // Now mark it as unseeded. It still produces data and is still marked // as unseeded after the data is produced. It should block until the // seeding is complete. [root@freebsd8 ~]# sysctl kern.random.sys.seeded=0 kern.random.sys.seeded: 1 -> 0 [root@freebsd8 ~]# time dd if=/dev/random bs=1 count=1 ¿1+0 records in 1+0 records out 1 bytes transferred in 0.000006 secs (167772 bytes/sec) real 0m0.006s user 0m0.000s sys 0m0.006s [root@freebsd8 ~]# sysctl kern.random.sys.seeded kern.random.sys.seeded: 0 >Fix: I have not tested this fix and am not able to do so, but I think this will solve the problem and restore the intended behavior. Patch attached with submission follows: Index: sys/dev/random/randomdev_soft.c =================================================================== --- sys/dev/random/randomdev_soft.c (revision 203082) +++ sys/dev/random/randomdev_soft.c (working copy) @@ -391,7 +391,7 @@ random_yarrow_block(int flag) mtx_lock(&random_reseed_mtx); /* Blocking logic */ - while (random_systat.seeded && !error) { + while (!random_systat.seeded && !error) { if (flag & O_NONBLOCK) error = EWOULDBLOCK; else { >Release-Note: >Audit-Trail: >Unformatted: