Index | Thread | Search

From:
Stuart Henderson <stu@spacehopper.org>
Subject:
Re: ksh(1), use arc4random_uniform(3) to calculate $RANDOM
To:
Biarder <mss091204.1@gmail.com>, <tech@openbsd.org>
Date:
Fri, 22 May 2026 12:44:30 +0100

Download raw body.

Thread
  • Stuart Henderson:

    ksh(1), use arc4random_uniform(3) to calculate $RANDOM

  • Theo de Raadt:

    ksh(1), use arc4random_uniform(3) to calculate $RANDOM

  • read about RANDOM in ksh(1), it is required that this give deterministic 
    output in some cases
    
    -- 
      Sent from a phone, apologies for poor formatting.
    
    On 22 May 2026 10:54:11 Biarder <mss091204.1@gmail.com> wrote:
    
    > 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:
    
    
  • Stuart Henderson:

    ksh(1), use arc4random_uniform(3) to calculate $RANDOM

  • Theo de Raadt:

    ksh(1), use arc4random_uniform(3) to calculate $RANDOM