From owner-freebsd-bugs Tue Apr 17 7:10:10 2001 Delivered-To: freebsd-bugs@hub.freebsd.org Received: from freefall.freebsd.org (freefall.freebsd.org [216.136.204.21]) by hub.freebsd.org (Postfix) with ESMTP id 7990137B424 for ; Tue, 17 Apr 2001 07:10:04 -0700 (PDT) (envelope-from gnats@FreeBSD.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.11.1/8.11.1) id f3HEA4j60558; Tue, 17 Apr 2001 07:10:04 -0700 (PDT) (envelope-from gnats) Received: from psychotic.aberrant.org (psychotic.aberrant.org [64.81.134.141]) by hub.freebsd.org (Postfix) with ESMTP id 6EBB037B43C for ; Tue, 17 Apr 2001 07:02:24 -0700 (PDT) (envelope-from seth@psychotic.aberrant.org) Received: (from seth@localhost) by psychotic.aberrant.org (8.9.3/8.9.3) id KAA11054; Tue, 17 Apr 2001 10:02:23 -0400 (EDT) (envelope-from seth) Message-Id: <200104171402.KAA11054@psychotic.aberrant.org> Date: Tue, 17 Apr 2001 10:02:23 -0400 (EDT) From: Seth Reply-To: seth@psychotic.aberrant.org To: FreeBSD-gnats-submit@freebsd.org X-Send-Pr-Version: 3.2 Subject: misc/26646: srand() provides only 8-bit table Sender: owner-freebsd-bugs@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.org >Number: 26646 >Category: misc >Synopsis: srand() provides only 8-bit table >Confidential: no >Severity: non-critical >Priority: low >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: change-request >Submitter-Id: current-users >Arrival-Date: Tue Apr 17 07:10:01 PDT 2001 >Closed-Date: >Last-Modified: >Originator: Seth >Release: FreeBSD 4.0-20000710-STABLE i386 >Organization: >Environment: Confirmed on above system and on a 4.3-RC system. >Description: This is not a serious problem; in fact, it's well documented in the srand() and rand() manpages. However, the behavior on FreeBSD is not consistent with other operating systems, and ports that fail to take the differences into account will exhibit bad behavior under FreeBSD while appearing fine under other OSes (linux and solaris tested). The issue is that FreeBSD's srand() is acknowleged to be weak, but it's been strengthened in other OSes. (linux and solaris). FreeBSD's srand() provides an 8-bit-wide seed table, where srand(n) produces the same sequence of random numbers (returned by rand()) as srand(n*(256*m)). This affects at least one port -- ident2 -- which uses srand() and rand() with time() to produce a pseudorandom sequence of 6 characters to respond to an ident request. In FreeBSD, the weakness in srand() will cause ident2 to repeat the same 6-character ident string every 256 seconds, and will cause significant overlap in other cases (where the last 3-5 characters are the same as the first 3-5 characters of the last request). The same code on linux and solaris does not repeat with this frequency. Admittedly, this is not a huge problem in itself, but the consequences of having this weakness when other OSes don't may be a bit troubling. If coders code on linux, for example, and don't see that there's a problem with srand() /rand() returning predictable values, then ports (like ident2) will show acceptable behavior on linux but unacceptably bad randomness in FreeBSD. Now, it's entirely possible that some code (probably FreeBSD-specific, since other OSes "fix" srand()) relies on the weakness of srand() to operate correctly. I will leave it up to other, more experienced programmers to determine (a) if this in fact the case, and (b) whether that's a good way of coding. >How-To-Repeat: The weakness of srand() in FreeBSD can be demonstrated by the following code: (Please forgive the code quality; I'm not a programmer.) #define SEED 68 #define STR 6 main() { int i,j; char randstr[STR+1]; for (j = SEED;;j+=256) { printf ("testing seed of %d: ",j); srand(j); for (i = 0; i < STR; i++) { randstr[i] = rand(); while (randstr[i] > 'z') randstr[i] -= 26; while (randstr[i] < 'a') randstr[i] += 26; } randstr[STR] = 0; printf ("%s\n",randstr); } } >Fix: There are two possible workarounds. The first is to identify all third-party code that uses srand() and rand() and apply the necessary patches to make them use srandom() and random(). The second is to "fix" srand() and rand() by redefining them as srandom() and random(): #define rand (int)random #define srand(seed) srandom((int)(seed)) (The above two lines, when applied to the code, seem to "fix" the problem.) >Release-Note: >Audit-Trail: >Unformatted: To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-bugs" in the body of the message