summaryrefslogtreecommitdiff
path: root/src/lib/libc/stdlib/random.c
diff options
context:
space:
mode:
authorderaadt <>2014-12-08 21:45:20 +0000
committerderaadt <>2014-12-08 21:45:20 +0000
commit1e2b0be5bee045db1b0abb1f87801004db563bb8 (patch)
treebf17a76201de02c2ce50358a383001a6b6c5cc64 /src/lib/libc/stdlib/random.c
parent4b0b4fc5d98edef87738071b3784e13573327bab (diff)
downloadopenbsd-1e2b0be5bee045db1b0abb1f87801004db563bb8.tar.gz
openbsd-1e2b0be5bee045db1b0abb1f87801004db563bb8.tar.bz2
openbsd-1e2b0be5bee045db1b0abb1f87801004db563bb8.zip
Change rand(), random(), drand48(), lrand48(), mrand48(), and srand48()
to returning strong random by default, source from arc4random(3). Parameters to the seeding functions are ignored, and the subsystems remain in strong random mode. If you wish the standardized deterministic mode, call srand_deterministic(), srandom_determistic(), srand48_deterministic(), seed48_deterministic() or lcong48_deterministic() instead. The re-entrant functions rand_r(), erand48(), nrand48(), jrand48() are unaffected by this change and remain in deterministic mode (for now). Verified as a good roadmap forward by auditing 8800 pieces of software. Roughly 60 pieces of software will need adaptation to request the deterministic mode. Violates POSIX and C89, which violate best practice in this century. ok guenther tedu millert
Diffstat (limited to 'src/lib/libc/stdlib/random.c')
-rw-r--r--src/lib/libc/stdlib/random.c49
1 files changed, 14 insertions, 35 deletions
diff --git a/src/lib/libc/stdlib/random.c b/src/lib/libc/stdlib/random.c
index e4ff07ea0c..cba088c751 100644
--- a/src/lib/libc/stdlib/random.c
+++ b/src/lib/libc/stdlib/random.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: random.c,v 1.24 2014/10/13 20:54:13 chl Exp $ */ 1/* $OpenBSD: random.c,v 1.25 2014/12/08 21:45:20 deraadt Exp $ */
2/* 2/*
3 * Copyright (c) 1983 Regents of the University of California. 3 * Copyright (c) 1983 Regents of the University of California.
4 * All rights reserved. 4 * All rights reserved.
@@ -176,7 +176,7 @@ static int rand_type = TYPE_3;
176static int rand_deg = DEG_3; 176static int rand_deg = DEG_3;
177static int rand_sep = SEP_3; 177static int rand_sep = SEP_3;
178 178
179static int use_arc4random; 179static int random_deterministic;
180 180
181_THREAD_PRIVATE_MUTEX(random); 181_THREAD_PRIVATE_MUTEX(random);
182static long random_l(void); 182static long random_l(void);
@@ -203,7 +203,7 @@ srandom_l(unsigned int x)
203 int32_t test; 203 int32_t test;
204 div_t val; 204 div_t val;
205 205
206 use_arc4random = 0; 206 random_deterministic = 1;
207 if (rand_type == TYPE_0) 207 if (rand_type == TYPE_0)
208 state[0] = x; 208 state[0] = x;
209 else { 209 else {
@@ -231,39 +231,23 @@ srandom_l(unsigned int x)
231void 231void
232srandom(unsigned int x) 232srandom(unsigned int x)
233{ 233{
234 LOCK(); 234 random_deterministic = 0;
235 srandom_l(x);
236 UNLOCK();
237} 235}
238 236
239#if defined(APIWARN)
240__warn_references(srandom,
241 "warning: srandom() seed choices are invariably poor");
242#endif
243
244/*
245 * srandomdev:
246 *
247 * Many programs choose the seed value in a totally predictable manner.
248 * This often causes problems. We seed the generator using random data.
249 * Note that this particular seeding procedure can generate states
250 * which are impossible to reproduce by calling srandom() with any
251 * value, since the succeeding terms in the state buffer are no longer
252 * derived from the LC algorithm applied to a fixed seed.
253 */
254void 237void
255srandomdev(void) 238srandomdev(void)
256{ 239{
240 random_deterministic = 0; /* back to the default */
241}
242
243void
244srandom_deterministic(unsigned int x)
245{
257 LOCK(); 246 LOCK();
258 use_arc4random = 1; 247 srandom_l(x);
259 UNLOCK(); 248 UNLOCK();
260} 249}
261 250
262#if defined(APIWARN)
263__warn_references(srandomdev,
264 "warning: srandomdev() usage; consider switching to arc4random()");
265#endif
266
267/* 251/*
268 * initstate: 252 * initstate:
269 * 253 *
@@ -289,7 +273,7 @@ initstate(u_int seed, char *arg_state, size_t n)
289 char *ostate = (char *)(&state[-1]); 273 char *ostate = (char *)(&state[-1]);
290 274
291 LOCK(); 275 LOCK();
292 use_arc4random = 0; 276 random_deterministic = 1;
293 if (rand_type == TYPE_0) 277 if (rand_type == TYPE_0)
294 state[-1] = rand_type; 278 state[-1] = rand_type;
295 else 279 else
@@ -354,7 +338,7 @@ setstate(char *arg_state)
354 char *ostate = (char *)(&state[-1]); 338 char *ostate = (char *)(&state[-1]);
355 339
356 LOCK(); 340 LOCK();
357 use_arc4random = 0; 341 random_deterministic = 1;
358 if (rand_type == TYPE_0) 342 if (rand_type == TYPE_0)
359 state[-1] = rand_type; 343 state[-1] = rand_type;
360 else 344 else
@@ -405,7 +389,7 @@ random_l(void)
405{ 389{
406 int32_t i; 390 int32_t i;
407 391
408 if (use_arc4random) 392 if (random_deterministic == 0)
409 return arc4random() & 0x7fffffff; 393 return arc4random() & 0x7fffffff;
410 394
411 if (rand_type == TYPE_0) 395 if (rand_type == TYPE_0)
@@ -431,8 +415,3 @@ random(void)
431 UNLOCK(); 415 UNLOCK();
432 return r; 416 return r;
433} 417}
434
435#if defined(APIWARN)
436__warn_references(random,
437 "warning: random() isn't random; consider using arc4random()");
438#endif