From seth@psychotic.aberrant.org  Tue Apr 17 07:02:25 2001
Return-Path: <seth@psychotic.aberrant.org>
Received: from psychotic.aberrant.org (psychotic.aberrant.org [64.81.134.141])
	by hub.freebsd.org (Postfix) with ESMTP id 6EBB037B43C
	for <FreeBSD-gnats-submit@freebsd.org>; 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 <seth@psychotic.aberrant.org>
Reply-To: seth@psychotic.aberrant.org
To: FreeBSD-gnats-submit@freebsd.org
Subject: srand() provides only 8-bit table
X-Send-Pr-Version: 3.2

>Number:         26646
>Category:       kern
>Synopsis:       srand() provides only 8-bit table
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    ache
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Tue Apr 17 07:10:01 PDT 2001
>Closed-Date:    Thu May 29 10:11:10 UTC 2008
>Last-Modified:  Thu May 29 10:11:10 UTC 2008
>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:

From: Peter Pentchev <roam@orbitel.bg>
To: Seth <seth@psychotic.aberrant.org>
Cc: FreeBSD-gnats-submit@freebsd.org
Subject: Re: misc/26646: srand() provides only 8-bit table
Date: Tue, 17 Apr 2001 17:15:08 +0300

 On Tue, Apr 17, 2001 at 10:02:23AM -0400, Seth wrote:
 > 
 > >Number:         26646
 > >Category:       misc
 > >Synopsis:       srand() provides only 8-bit table
 > >Originator:     Seth
 > >Release:        FreeBSD 4.0-20000710-STABLE i386
 > >Organization:
 
 [snip]
 
 > >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():
 
 There was a recent discussion on -arch, which seemed to suggest that the first
 workaround would be the better one.  There seem to be people running programs
 that depend on the exact algorithm rand() uses - don't as me why.. and.. hm..
 I don't seem to remember any other reasons for not strengthening s/rand()
 that popped up then..
 
 G'luck,
 Peter
 
 -- 
 I am jealous of the first word in this sentence.
State-Changed-From-To: open->analyzed 
State-Changed-By: ache 
State-Changed-When: Tue Apr 17 07:21:04 PDT 2001 
State-Changed-Why:  
Already fixed in -current 

http://www.freebsd.org/cgi/query-pr.cgi?pr=26646 
State-Changed-From-To: analyzed->patched 
State-Changed-By: ache 
State-Changed-When: Sat Jun 8 13:18:09 PDT 2002 
State-Changed-Why:  
This PR state must be "patched" according to guideline 

http://www.freebsd.org/cgi/query-pr.cgi?pr=26646 
Responsible-Changed-From-To: freebsd-bugs->ache 
Responsible-Changed-By: kris 
Responsible-Changed-When: Sat Jul 12 20:45:33 PDT 2003 
Responsible-Changed-Why:  
Assign to ache as reminder to MFC 

http://www.freebsd.org/cgi/query-pr.cgi?pr=26646 
State-Changed-From-To: patched->closed 
State-Changed-By: gavin 
State-Changed-When: Thu May 29 10:05:19 UTC 2008 
State-Changed-Why:  
Fixed in -HEAD before 5.0 was branched, so fixed in all supported releases 

http://www.freebsd.org/cgi/query-pr.cgi?pr=26646 
>Unformatted:
