diff options
author | Mike Frysinger <vapier@gentoo.org> | 2005-04-16 03:59:42 +0000 |
---|---|---|
committer | Mike Frysinger <vapier@gentoo.org> | 2005-04-16 03:59:42 +0000 |
commit | 650870cb833b700fc13a484cbbd9f61ad049b4f3 (patch) | |
tree | ff5e06a5fa43a961e352d5674c7fe154b21ed48b /libc | |
parent | d1abf5ce4c95c2a38f9ac92ae6805a0344de9c7d (diff) |
In Bug 116, dicksnippe writes:
uClibc's mkstemp/mktemp tries to read /dev/urandom (or /dev/random) to
generate random contents for the .XXXXXX part of its argument. In a
chrooted environment /dev/[u]random might not be available. Thus the
mkstemp call fails.
Add back in the braindamaged gettimeofday/getpid code, but only as a
fallback for when reading /dev/[u]random fail for whatever reasons.
Diffstat (limited to 'libc')
-rw-r--r-- | libc/misc/internals/tempname.c | 35 |
1 files changed, 32 insertions, 3 deletions
diff --git a/libc/misc/internals/tempname.c b/libc/misc/internals/tempname.c index c1b211241..cd1f3497b 100644 --- a/libc/misc/internals/tempname.c +++ b/libc/misc/internals/tempname.c @@ -26,6 +26,11 @@ * Don't use brain damaged getpid() based randomness. */ +/* April 15, 2005 Mike Frysinger + * + * Use brain damaged getpid() if real random fails. + */ + #include <stddef.h> #include <stdint.h> #include <stdio.h> @@ -132,6 +137,30 @@ static unsigned int fillrand(unsigned char *buf, unsigned int len) return result; } +static void brain_damaged_fillrand(unsigned char *buf, unsigned int len) +{ + int i, k; + struct timeval tv; + uint32_t high, low, rh; + static uint64_t value; + gettimeofday(&tv, NULL); + value += ((uint64_t) tv.tv_usec << 16) ^ tv.tv_sec ^ getpid(); + low = value & UINT32_MAX; + high = value >> 32; + for (i = 0; i < len; ++i) { + rh = high % 62; + high /= 62; +#define L ((UINT32_MAX % 62 + 1) % 62) + k = (low % 62) + (L * rh); +#undef L +#define H ((UINT32_MAX / 62) + ((UINT32_MAX % 62 + 1) / 62)) + low = (low / 62) + (H * rh) + (k / 62); +#undef H + k %= 62; + buf[i] = letters[k]; + } +} + /* Generate a temporary file name based on TMPL. TMPL must match the rules for mk[s]temp (i.e. end in "XXXXXX"). The name constructed does not exist at the time of the call to __gen_tempname. TMPL is @@ -164,8 +193,9 @@ int __gen_tempname (char *tmpl, int kind) XXXXXX = &tmpl[len - 6]; /* Get some random data. */ - if (fillrand(randomness, sizeof(randomness)) != sizeof(randomness)) { - goto all_done; + if (fillrand(randomness, sizeof(randomness)) != sizeof(randomness)) { + /* if random device nodes failed us, lets use the braindamaged ver */ + brain_damaged_fillrand(randomness, sizeof(randomness)); } for (i = 0 ; i < sizeof(randomness) ; i++) { k = ((randomness[i]) % 62); @@ -219,7 +249,6 @@ int __gen_tempname (char *tmpl, int kind) } /* We got out of the loop because we ran out of combinations to try. */ -all_done: __set_errno (EEXIST); return -1; } |