Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 17 Apr 2001 10:02:23 -0400 (EDT)
From:      Seth <seth@psychotic.aberrant.org>
To:        FreeBSD-gnats-submit@freebsd.org
Subject:   misc/26646: srand() provides only 8-bit table
Message-ID:  <200104171402.KAA11054@psychotic.aberrant.org>

next in thread | raw e-mail | index | archive | help

>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




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200104171402.KAA11054>