From ce9d26a8fbad590aa685db707e93ed6aa9278068 Mon Sep 17 00:00:00 2001 From: tg Date: Tue, 27 Apr 2004 19:59:57 +0000 Subject: [PATCH] * mirbsdksh and mirosksh != rksh * use arc4random familiy for randomness, if exists * feed back randomness on reseed and variable assignments --- ksh.1tbl | 9 ++++++++- main.c | 20 ++++++++++++++------ proto.h | 4 +++- var.c | 40 ++++++++++++++++++++++++++++++++++++---- 4 files changed, 61 insertions(+), 12 deletions(-) diff --git a/ksh.1tbl b/ksh.1tbl index f37a037..b25f537 100644 --- a/ksh.1tbl +++ b/ksh.1tbl @@ -1,4 +1,4 @@ -.\" $MirBSD: ksh.1tbl,v 1.21 2004/04/26 18:38:19 tg Exp $ +.\" $MirBSD: ksh.1tbl,v 1.22 2004/04/27 19:59:55 tg Exp $ .\" $OpenBSD: ksh.1tbl,v 1.65 2004/01/23 23:08:45 jmc Exp $ .\" .\" Copyright (c) 1980, 1990, 1993 @@ -1565,6 +1565,13 @@ The point in the series can be set by assigning a number to .Ev RANDOM (see .Xr rand 3 ) . +.Pp +On systems which provide the +.Xr arc4random 3 +function, the random value is seeded on start by the arcfour +random number generator. +If a feedback function is provided, changed values are propagated +back to the arcfour random number generator. .It Ev REPLY Default parameter for the .Ic read diff --git a/main.c b/main.c index b9e6ec4..73c0561 100644 --- a/main.c +++ b/main.c @@ -1,5 +1,5 @@ -/* $MirBSD: main.c,v 1.5 2004/04/26 18:38:20 tg Exp $ */ -/* $OpenBSD: main.c,v 1.26 2004/01/08 05:43:14 jmc Exp $ */ +/* $MirBSD: main.c,v 1.6 2004/04/27 19:59:56 tg Exp $ */ +/* $OpenBSD: main.c,v 1.26 2004/01/08 05:43:14 jmc Exp $ */ /* * startup, main loop, environments and error handling @@ -94,6 +94,9 @@ main(int argc, char *argv[]) char **wp; struct env env; pid_t ppid; +#ifdef KSH + long trnd; +#endif #ifdef MEM_DEBUG chmem_set_defaults("ct", 1); @@ -115,6 +118,9 @@ main(int argc, char *argv[]) argc = 1; } kshname = *argv; +#ifdef KSH + trnd = *((long *)kshname); +#endif ainit(&aperm); /* initialize permanent Area */ @@ -255,9 +261,10 @@ main(int argc, char *argv[]) } ppid = getppid(); setint(global("PPID"), (long) ppid); -#ifdef KSH - setint(global("RANDOM"), (long) (time((time_t *)0) * kshpid * ppid)); -#endif /* KSH */ +#ifdef KSH + trnd ^= ((long) (time((time_t *)0) * kshpid * ppid)); + setint(global("RANDOM"), prng_seed(trnd)); +#endif /* KSH */ /* setstr can't fail here */ setstr(global(version_param), ksh_version, KSH_RETURN_ERROR); @@ -848,7 +855,8 @@ is_restricted(name) if ((p = ksh_strrchr_dirsep(name))) name = p; /* accepts rsh, rksh, rpdksh, pdrksh, etc. */ - return (p = strchr(name, 'r')) && strstr(p, "sh"); + return (p = strchr(name, 'r')) && strstr(p, "sh") + && !strstr(p-2, "mirbsdksh") && !strstr(p-2, "mirosksh"); } void diff --git a/proto.h b/proto.h index d0b7e8a..aa41f3c 100644 --- a/proto.h +++ b/proto.h @@ -1,4 +1,5 @@ -/* $OpenBSD: proto.h,v 1.11 2003/05/16 19:58:57 jsyn Exp $ */ +/* $MirBSD: proto.h,v 1.2 2004/04/27 19:59:57 tg Exp $ */ +/* $OpenBSD: proto.h,v 1.11 2003/05/16 19:58:57 jsyn Exp $ */ /* * prototypes for PD-KSH @@ -275,6 +276,7 @@ void change_random ARGS((void)); int array_ref_len ARGS((const char *cp)); char * arrayname ARGS((const char *str)); void set_array ARGS((const char *var, int reset, char **vals)); +long prng_seed ARGS((long)); /* version.c */ /* vi.c: see edit.h */ diff --git a/var.c b/var.c index dc2577b..7b5d4a4 100644 --- a/var.c +++ b/var.c @@ -1,5 +1,5 @@ -/* $MirBSD: var.c,v 1.2 2004/04/17 00:47:20 tg Exp $ */ -/* $OpenBSD: var.c,v 1.16 2003/08/05 20:52:27 millert Exp $ */ +/* $MirBSD: var.c,v 1.3 2004/04/27 19:59:57 tg Exp $ */ +/* $OpenBSD: var.c,v 1.16 2003/08/05 20:52:27 millert Exp $ */ #include "sh.h" #include "ksh_time.h" @@ -891,7 +891,7 @@ makenv() void change_random() { - rand(); + prng_seed(rand()); } /* @@ -1046,7 +1046,8 @@ setspec(vp) break; case V_RANDOM: vp->flag &= ~SPECIAL; - srand((unsigned int)intval(vp)); + srand(prng_seed(((unsigned int)intval(vp)) + ^ ((unsigned long)rand() << 24))); vp->flag |= SPECIAL; break; case V_SECONDS: @@ -1237,3 +1238,34 @@ set_array(var, reset, vals) setstr(vq, vals[i], KSH_RETURN_ERROR); } } + +/* Return a seed PRNG value, and feed one back to arc4random */ +long +prng_seed(val) + long val; +{ + unsigned long i, j; + +#ifdef HAVE_ARC4RANDOM + i = arc4random(); +#else + i = ((long) (time((time_t *)0) * getpid())); +#endif + j = (rand() << 16) | rand(); + + i ^= val; + j ^= val; + +#if defined(HAVE_ARC4RANDOM_PUSH) + arc4random_push(j); +#elif defined(HAVE_ARC4RANDOM_ADDRANDOM) + arc4random_addrandom(&j, sizeof (j)); +#else + while (j) { + rand(); + j >>= 1; + } +#endif + + return i; +}