From owner-svn-src-stable@FreeBSD.ORG Wed Jul 24 10:12:51 2013 Return-Path: Delivered-To: svn-src-stable@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) by hub.freebsd.org (Postfix) with ESMTP id 43F2578E; Wed, 24 Jul 2013 10:12:51 +0000 (UTC) (envelope-from ache@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.freebsd.org (Postfix) with ESMTPS id 267442787; Wed, 24 Jul 2013 10:12:51 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.7/8.14.7) with ESMTP id r6OACpsD011296; Wed, 24 Jul 2013 10:12:51 GMT (envelope-from ache@svn.freebsd.org) Received: (from ache@localhost) by svn.freebsd.org (8.14.7/8.14.5/Submit) id r6OACoqb011294; Wed, 24 Jul 2013 10:12:50 GMT (envelope-from ache@svn.freebsd.org) Message-Id: <201307241012.r6OACoqb011294@svn.freebsd.org> From: "Andrey A. Chernov" Date: Wed, 24 Jul 2013 10:12:50 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-9@freebsd.org Subject: svn commit: r253607 - in stable/9: include lib/libc/stdlib X-SVN-Group: stable-9 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: SVN commit messages for all the -stable branches of the src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 24 Jul 2013 10:12:51 -0000 Author: ache Date: Wed Jul 24 10:12:50 2013 New Revision: 253607 URL: http://svnweb.freebsd.org/changeset/base/253607 Log: 1) POSIX requires rand(3) return values to be in the [0, RAND_MAX] range, but ACM formula we use have internal state (and return value) in the [1, 0x7ffffffe] range, so our RAND_MAX (0x7fffffff) is never reached because it is off by one, zero is not reached too. Correct both RAND_MAX and rand(3) return value, shifting last one to the 0 by 1 subtracted, resulting POSIXed [0, 0x7ffffffd(=new RAND_MAX)] range. 2) Add a checks for not overflowing on too big seeds. It may happens on the machines, where sizeof(unsigned int) > 32 bits. This change is binary compatible because range is reduced, not expanded, so no bump is needed. Reviewed by: bde Approved by: re (glebius) Modified: stable/9/include/stdlib.h stable/9/lib/libc/stdlib/rand.c Directory Properties: stable/9/include/ (props changed) stable/9/lib/libc/ (props changed) Modified: stable/9/include/stdlib.h ============================================================================== --- stable/9/include/stdlib.h Wed Jul 24 09:59:16 2013 (r253606) +++ stable/9/include/stdlib.h Wed Jul 24 10:12:50 2013 (r253607) @@ -69,7 +69,7 @@ typedef struct { #define EXIT_FAILURE 1 #define EXIT_SUCCESS 0 -#define RAND_MAX 0x7fffffff +#define RAND_MAX 0x7ffffffd __BEGIN_DECLS #ifdef _XLOCALE_H_ Modified: stable/9/lib/libc/stdlib/rand.c ============================================================================== --- stable/9/lib/libc/stdlib/rand.c Wed Jul 24 09:59:16 2013 (r253606) +++ stable/9/lib/libc/stdlib/rand.c Wed Jul 24 10:12:50 2013 (r253607) @@ -67,15 +67,15 @@ do_rand(unsigned long *ctx) */ long hi, lo, x; - /* Can't be initialized with 0, so use another value. */ - if (*ctx == 0) - *ctx = 123459876; + /* Must be in [1, 0x7ffffffe] range at this point. */ hi = *ctx / 127773; lo = *ctx % 127773; x = 16807 * lo - 2836 * hi; if (x < 0) x += 0x7fffffff; - return ((*ctx = x) % ((u_long)RAND_MAX + 1)); + *ctx = x; + /* Transform to [0, 0x7ffffffd] range. */ + return (x - 1); #endif /* !USE_WEAK_SEEDING */ } @@ -83,15 +83,32 @@ do_rand(unsigned long *ctx) int rand_r(unsigned int *ctx) { - u_long val = (u_long) *ctx; - int r = do_rand(&val); + u_long val; + int r; - *ctx = (unsigned int) val; +#ifdef USE_WEAK_SEEDING + val = *ctx; +#else + /* Transform to [1, 0x7ffffffe] range. */ + val = (*ctx % 0x7ffffffe) + 1; +#endif + r = do_rand(&val); + +#ifdef USE_WEAK_SEEDING + *ctx = (unsigned int)val; +#else + *ctx = (unsigned int)(val - 1); +#endif return (r); } -static u_long next = 1; +static u_long next = +#ifdef USE_WEAK_SEEDING + 1; +#else + 2; +#endif int rand() @@ -104,6 +121,10 @@ srand(seed) u_int seed; { next = seed; +#ifndef USE_WEAK_SEEDING + /* Transform to [1, 0x7ffffffe] range. */ + next = (next % 0x7ffffffe) + 1; +#endif } @@ -125,6 +146,10 @@ sranddev() mib[0] = CTL_KERN; mib[1] = KERN_ARND; sysctl(mib, 2, (void *)&next, &len, NULL, 0); +#ifndef USE_WEAK_SEEDING + /* Transform to [1, 0x7ffffffe] range. */ + next = (next % 0x7ffffffe) + 1; +#endif }