diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2009-10-12 15:25:01 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2009-10-12 15:25:01 +0200 |
commit | 76ace254e171ee9ca7a13f36335ccad9cc6ae6e1 (patch) | |
tree | 47b017524b61e217e1dce1a82f3111b97a49425f | |
parent | 3c39e702d02600e9023f2f87f6e7c2c62aa27587 (diff) | |
download | busybox-w32-76ace254e171ee9ca7a13f36335ccad9cc6ae6e1.tar.gz busybox-w32-76ace254e171ee9ca7a13f36335ccad9cc6ae6e1.tar.bz2 busybox-w32-76ace254e171ee9ca7a13f36335ccad9cc6ae6e1.zip |
ash,hush: fix $RANDOM in children being repeated
function old new delta
next_random 46 68 +22
forkshell 248 263 +15
expand_vars_to_list 2118 2131 +13
run_pipe 1775 1782 +7
popstring 134 140 +6
builtin_umask 123 121 -2
ash_main 1356 1336 -20
get_local_var_value 125 104 -21
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 5/3 up/down: 63/-43) Total: 20 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | shell/ash.c | 17 | ||||
-rw-r--r-- | shell/hush.c | 6 | ||||
-rw-r--r-- | shell/math.c | 2 | ||||
-rw-r--r-- | shell/random.c | 7 | ||||
-rw-r--r-- | shell/random.h | 6 |
5 files changed, 22 insertions, 16 deletions
diff --git a/shell/ash.c b/shell/ash.c index cc2677126..d81dbd3f5 100644 --- a/shell/ash.c +++ b/shell/ash.c | |||
@@ -4725,10 +4725,12 @@ forkshell(struct job *jp, union node *n, int mode) | |||
4725 | freejob(jp); | 4725 | freejob(jp); |
4726 | ash_msg_and_raise_error("can't fork"); | 4726 | ash_msg_and_raise_error("can't fork"); |
4727 | } | 4727 | } |
4728 | if (pid == 0) | 4728 | if (pid == 0) { |
4729 | CLEAR_RANDOM_T(&random_gen); /* or else $RANDOM repeats in child */ | ||
4729 | forkchild(jp, n, mode); | 4730 | forkchild(jp, n, mode); |
4730 | else | 4731 | } else { |
4731 | forkparent(jp, n, mode, pid); | 4732 | forkparent(jp, n, mode, pid); |
4733 | } | ||
4732 | return pid; | 4734 | return pid; |
4733 | } | 4735 | } |
4734 | 4736 | ||
@@ -10079,12 +10081,6 @@ setcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) | |||
10079 | static void FAST_FUNC | 10081 | static void FAST_FUNC |
10080 | change_random(const char *value) | 10082 | change_random(const char *value) |
10081 | { | 10083 | { |
10082 | /* Galois LFSR parameter */ | ||
10083 | /* Taps at 32 31 29 1: */ | ||
10084 | enum { MASK = 0x8000000b }; | ||
10085 | /* Another example - taps at 32 31 30 10: */ | ||
10086 | /* MASK = 0x00400007 */ | ||
10087 | |||
10088 | uint32_t t; | 10084 | uint32_t t; |
10089 | 10085 | ||
10090 | if (value == NULL) { | 10086 | if (value == NULL) { |
@@ -13268,11 +13264,6 @@ int ash_main(int argc UNUSED_PARAM, char **argv) | |||
13268 | #endif | 13264 | #endif |
13269 | rootpid = getpid(); | 13265 | rootpid = getpid(); |
13270 | 13266 | ||
13271 | #if ENABLE_ASH_RANDOM_SUPPORT | ||
13272 | /* Can use monotonic_ns() for better randomness but for now it is | ||
13273 | * not used anywhere else in busybox... so avoid bloat */ | ||
13274 | INIT_RANDOM_T(&random_gen, rootpid, monotonic_us()); | ||
13275 | #endif | ||
13276 | init(); | 13267 | init(); |
13277 | setstackmark(&smark); | 13268 | setstackmark(&smark); |
13278 | procargs(argv); | 13269 | procargs(argv); |
diff --git a/shell/hush.c b/shell/hush.c index d105029ff..21f3edcac 100644 --- a/shell/hush.c +++ b/shell/hush.c | |||
@@ -88,6 +88,8 @@ | |||
88 | #include "match.h" | 88 | #include "match.h" |
89 | #if ENABLE_HUSH_RANDOM_SUPPORT | 89 | #if ENABLE_HUSH_RANDOM_SUPPORT |
90 | # include "random.h" | 90 | # include "random.h" |
91 | #else | ||
92 | # define CLEAR_RANDOM_T(rnd) ((void)0) | ||
91 | #endif | 93 | #endif |
92 | #ifndef PIPE_BUF | 94 | #ifndef PIPE_BUF |
93 | # define PIPE_BUF 4096 /* amount of buffering in a pipe */ | 95 | # define PIPE_BUF 4096 /* amount of buffering in a pipe */ |
@@ -1319,8 +1321,6 @@ static const char *get_local_var_value(const char *name) | |||
1319 | // bash compat: UID? EUID? | 1321 | // bash compat: UID? EUID? |
1320 | #if ENABLE_HUSH_RANDOM_SUPPORT | 1322 | #if ENABLE_HUSH_RANDOM_SUPPORT |
1321 | if (strcmp(name, "RANDOM") == 0) { | 1323 | if (strcmp(name, "RANDOM") == 0) { |
1322 | if (G.random_gen.galois_LFSR == 0) | ||
1323 | INIT_RANDOM_T(&G.random_gen, G.root_pid, monotonic_us()); | ||
1324 | return utoa(next_random(&G.random_gen)); | 1324 | return utoa(next_random(&G.random_gen)); |
1325 | } | 1325 | } |
1326 | #endif | 1326 | #endif |
@@ -4000,6 +4000,7 @@ static NOINLINE int run_pipe(struct pipe *pi) | |||
4000 | if (!command->pid) { /* child */ | 4000 | if (!command->pid) { /* child */ |
4001 | #if ENABLE_HUSH_JOB | 4001 | #if ENABLE_HUSH_JOB |
4002 | disable_restore_tty_pgrp_on_exit(); | 4002 | disable_restore_tty_pgrp_on_exit(); |
4003 | CLEAR_RANDOM_T(&G.random_gen); /* or else $RANDOM repeats in child */ | ||
4003 | 4004 | ||
4004 | /* Every child adds itself to new process group | 4005 | /* Every child adds itself to new process group |
4005 | * with pgid == pid_of_first_child_in_pipe */ | 4006 | * with pgid == pid_of_first_child_in_pipe */ |
@@ -5207,6 +5208,7 @@ static FILE *generate_stream_from_string(const char *s) | |||
5207 | + (1 << SIGTTIN) | 5208 | + (1 << SIGTTIN) |
5208 | + (1 << SIGTTOU) | 5209 | + (1 << SIGTTOU) |
5209 | , SIG_IGN); | 5210 | , SIG_IGN); |
5211 | CLEAR_RANDOM_T(&G.random_gen); /* or else $RANDOM repeats in child */ | ||
5210 | close(channel[0]); /* NB: close _first_, then move fd! */ | 5212 | close(channel[0]); /* NB: close _first_, then move fd! */ |
5211 | xmove_fd(channel[1], 1); | 5213 | xmove_fd(channel[1], 1); |
5212 | /* Prevent it from trying to handle ctrl-z etc */ | 5214 | /* Prevent it from trying to handle ctrl-z etc */ |
diff --git a/shell/math.c b/shell/math.c index 3791b84bc..fc20def62 100644 --- a/shell/math.c +++ b/shell/math.c | |||
@@ -258,7 +258,7 @@ static int | |||
258 | arith_lookup_val(v_n_t *t, a_e_h_t *math_hooks) | 258 | arith_lookup_val(v_n_t *t, a_e_h_t *math_hooks) |
259 | { | 259 | { |
260 | if (t->var) { | 260 | if (t->var) { |
261 | const char * p = lookupvar(t->var); | 261 | const char *p = lookupvar(t->var); |
262 | 262 | ||
263 | if (p) { | 263 | if (p) { |
264 | int errcode; | 264 | int errcode; |
diff --git a/shell/random.c b/shell/random.c index cca9d120d..7f5821cbc 100644 --- a/shell/random.c +++ b/shell/random.c | |||
@@ -20,6 +20,13 @@ next_random(random_t *rnd) | |||
20 | 20 | ||
21 | uint32_t t; | 21 | uint32_t t; |
22 | 22 | ||
23 | if (UNINITED_RANDOM_T(rnd)) { | ||
24 | /* Can use monotonic_ns() for better randomness but for now | ||
25 | * it is not used anywhere else in busybox... so avoid bloat | ||
26 | */ | ||
27 | INIT_RANDOM_T(rnd, getpid(), monotonic_us()); | ||
28 | } | ||
29 | |||
23 | /* LCG has period of 2^32 and alternating lowest bit */ | 30 | /* LCG has period of 2^32 and alternating lowest bit */ |
24 | rnd->LCG = 1664525 * rnd->LCG + 1013904223; | 31 | rnd->LCG = 1664525 * rnd->LCG + 1013904223; |
25 | /* Galois LFSR has period of 2^32-1 = 3 * 5 * 17 * 257 * 65537 */ | 32 | /* Galois LFSR has period of 2^32-1 = 3 * 5 * 17 * 257 * 65537 */ |
diff --git a/shell/random.h b/shell/random.h index 8667e1c99..e22a2e88b 100644 --- a/shell/random.h +++ b/shell/random.h | |||
@@ -13,7 +13,13 @@ typedef struct random_t { | |||
13 | uint32_t LCG; /* LCG (fast but weak) */ | 13 | uint32_t LCG; /* LCG (fast but weak) */ |
14 | } random_t; | 14 | } random_t; |
15 | 15 | ||
16 | #define UNINITED_RANDOM_T(rnd) \ | ||
17 | ((rnd)->galois_LFSR == 0) | ||
18 | |||
16 | #define INIT_RANDOM_T(rnd, nonzero, v) \ | 19 | #define INIT_RANDOM_T(rnd, nonzero, v) \ |
17 | ((rnd)->galois_LFSR = (nonzero), (rnd)->LCG = (v)) | 20 | ((rnd)->galois_LFSR = (nonzero), (rnd)->LCG = (v)) |
18 | 21 | ||
22 | #define CLEAR_RANDOM_T(rnd) \ | ||
23 | ((rnd)->galois_LFSR = 0) | ||
24 | |||
19 | uint32_t next_random(random_t *rnd) FAST_FUNC; | 25 | uint32_t next_random(random_t *rnd) FAST_FUNC; |