Index | Thread | Search

From:
Biarder <mss091204.1@gmail.com>
Subject:
ksh(1), use arc4random_uniform(3) to calculate $RANDOM
To:
tech@openbsd.org
Date:
Fri, 22 May 2026 16:53:41 +0700

Download raw body.

Thread
Currently, ksh(1) uses rand(3) and modular arithmetic to calculate
$RANDOM.  However, OpenBSD recommend using arc4random_uniform(3)
to calculate a uniform random integer because rand function is
predictable and also has modular bias when modulo operation is
performed.

I passed all regress tests on OpenBSD 7.9 GENERIC.MP#495 amd64. 

Index: jobs.c
===================================================================
RCS file: /cvs/src/bin/ksh/jobs.c,v
diff -u -p -r1.62 jobs.c
--- jobs.c	7 Jul 2020 10:33:58 -0000	1.62
+++ jobs.c	22 May 2026 09:50:35 -0000
@@ -528,8 +528,6 @@ exchild(struct op *t, int flags, volatil
 	}
 
 	/* shell (parent) stuff */
-	/* Ensure next child gets a (slightly) different $RANDOM sequence */
-	change_random();
 	if (!(flags & XPIPEO)) {	/* last process in a job */
 		/* YYY: Is this needed? (see also YYY above)
 		   if (Flag(FMONITOR) && !(flags&(XXCOM|XBGND)))
Index: sh.h
===================================================================
RCS file: /cvs/src/bin/ksh/sh.h,v
diff -u -p -r1.78 sh.h
--- sh.h	5 Mar 2026 05:38:58 -0000	1.78
+++ sh.h	22 May 2026 09:50:35 -0000
@@ -598,7 +598,6 @@ char	*skip_wdvarname(const char *, int);
 int	is_wdvarname(const char *, int);
 int	is_wdvarassign(const char *);
 char **	makenv(void);
-void	change_random(void);
 int	array_ref_len(const char *);
 char *	arrayname(const char *);
 void    set_array(const char *, int, char **);
Index: var.c
===================================================================
RCS file: /cvs/src/bin/ksh/var.c,v
diff -u -p -r1.76 var.c
--- var.c	5 Mar 2026 05:40:37 -0000	1.76
+++ var.c	22 May 2026 09:50:35 -0000
@@ -880,17 +880,6 @@ makenv(void)
 }
 
 /*
- * Called after a fork in parent to bump the random number generator.
- * Done to ensure children will not get the same random number sequence
- * if the parent doesn't use $RANDOM.
- */
-void
-change_random(void)
-{
-	rand();
-}
-
-/*
  * handle special variables with side effects - PATH, SECONDS.
  */
 
@@ -939,7 +928,7 @@ getspec(struct tbl *vp)
 		break;
 	case V_RANDOM:
 		vp->flag &= ~SPECIAL;
-		setint(vp, (int64_t) (rand() & 0x7fff));
+		setint(vp, (int64_t) arc4random_uniform(0x8000));
 		vp->flag |= SPECIAL;
 		break;
 	case V_HISTSIZE: