diff -Naur uClibc-20060603.orig/extra/Configs/Config.in uClibc-20060603/extra/Configs/Config.in --- uClibc-20060603.orig/extra/Configs/Config.in 2006-06-03 07:10:43.000000000 +0000 +++ uClibc-20060603/extra/Configs/Config.in 2006-06-04 02:43:45.000000000 +0000 @@ -1289,16 +1289,70 @@ libraries have to be built with -fPIC or -fpic, and all assembler functions must be written as position independent code (PIC). +config UCLIBC_USES_ERANDOM + bool "Use /dev/erandom" + default n + help + Answer Y to use /dev/erandom by Eli Billauer. Erandom uses no kernel + entropy and performs better than /dev/urandom. If /dev/erandom does + not exist at run time then /dev/urandom will be used. This requires + a modified kernel. A sysctl interface is also available for Erandom. + See + + uClibc can currently use /dev/erandom for mktemp(3), arc4random(3), + and SSP. + + Most people will answer N. + config UCLIBC_HAS_ARC4RANDOM - bool "Include the arc4random() function" + bool "Include the arc4random(3) function" + default n + help + Answer Y to include the arc4random(3) function. arc4random uses the + key stream generator from the ARC4 cipher. ARC4 is an RC4 clone + posted anonymously to USENET. arc4random(3) is intended to be a drop + in replacement for the Unix random(3) function for applications which + require higher quality random numbers. The arc4random function + traditionally uses /dev/urandom to seed it's initial state, but will + always return something even if /dev/urandom fails. gettimeofday(2) + and getpid(2) values are used in the event that /dev/urandom fails. + This function is designed to be more dependable than invoking the + random driver directly. + + OpenSSL, OpenNTPD, BIND, KDE, and others, will use this function if it + is available from libc (OpenSSL currently requires a small patch), + instead of hard coding their own version. + + Most people will answer N. + +config ARC4RANDOM_USES_SYSCTL_ERANDOM + bool "Use sysctl(2) erandom with arc4random(3)" + depends on UCLIBC_USES_ERANDOM && UCLIBC_HAS_ARC4RANDOM + default n + help + Answer Y to use Erandom's sysctl(2) interface within the arc4random(3) + function. This has the advantage of working from withing a chroot. + + This requires patched kernel headers at compile time, and a modified + kernel at run time. + + The vanilla Erandom sysctl provides 16 bytes. arc4random() requires + 128 bytes. This means the sysctl interface must be opened eight times. + A 256 byte Erandom sysctl kernel patch is available so that the + sysctl(2) need only be opened once. This saves several syscalls and + performs better, however uses more system memory. This kernel patch + is available from: + + + Most people will answer N. + +config MKTEMP_USES_ARC4RANDOM + bool "Use arc4randon(3) in mktemp(3)" + depends on UCLIBC_HAS_ARC4RANDOM default n help - Answer Y to support the OpenBSD-like arc4random() function. This - function picks a random number between 0 and N, and will always return - something even if the random driver is dead. If urandom fails then - gettimeofday(2) will be used as the random seed. This function is - designed to be more dependable than invoking /dev/urandom directly. - OpenSSL and OpenNTPD currently support this function. + Answer Y to use arc4random(3) in mktemp(3). If you enabled + UCLIBC_USES_ERANDOM, arc4random(3) will be used instead. Most people will answer N. @@ -1307,22 +1361,22 @@ default n config UCLIBC_HAS_SSP - bool "Support for propolice smashing stack protector" + bool "Support for stack smashing protector" depends on !HAVE_NO_SSP default n help - Add propolice smashing stack protector to the library. + Add stack smashing protector (aka: propolice) to the library. This requires GCC 4.1, supporting the -fstack-protector[-all] options. GCC does not have to provide libssp, the needed functions are added to ldso/libc instead. Most people will answer N. config UCLIBC_HAS_SSP_COMPAT - bool "Support for gcc-3.x propolice smashing stack protector" + bool "Support for gcc-3.x stack smashing protector" depends on UCLIBC_HAS_SSP default n help - Add gcc-3.x propolice smashing stack protector to the library. + Add gcc-3.x propolice stack smashing protector to the library. This requires a patched version of GCC, supporting the -fstack-protector[-all] options, with the __guard and __stack_smash_handler functions removed from libgcc. @@ -1332,21 +1386,21 @@ Most people will answer N. config SSP_QUICK_CANARY - bool "Use simple guard values without accessing /dev/urandom" + bool "Use simple canary values without accessing /dev/urandom" depends on UCLIBC_HAS_SSP default n help Use gettimeofday(2) to define the __guard without accessing /dev/urandom. - WARNING: This makes smashing stack protector vulnerable to timing + WARNING: This makes stack smashing protector vulnerable to timing attacks. Most people will answer N. choice - prompt "Propolice protection blocking signal" + prompt "Stack smashing protector blocking signal" depends on UCLIBC_HAS_SSP - default PROPOLICE_BLOCK_ABRT if ! DODEBUG - default PROPOLICE_BLOCK_SEGV if DODEBUG + default SSP_BLOCK_ABRT if ! DODEBUG + default SSP_BLOCK_SEGV if DODEBUG help "abort" use SIGABRT to block offending programs. This is the default implementation. @@ -1356,20 +1410,21 @@ If unsure, answer "abort". -config PROPOLICE_BLOCK_ABRT +config SSP_BLOCK_ABRT bool "abort" -config PROPOLICE_BLOCK_SEGV +config SSP_BLOCK_SEGV bool "segfault" endchoice config UCLIBC_BUILD_SSP - bool "Build uClibc with propolice protection" + bool "Build uClibc with stack smashing protection" depends on UCLIBC_HAS_SSP default n help - Build all libraries and executables with propolice protection enabled. + Build all libraries and executables with stack smashing protection + enabled. config UCLIBC_BUILD_RELRO bool "Build uClibc with RELRO" diff -Naur uClibc-20060603.orig/libc/misc/internals/tempname.c uClibc-20060603/libc/misc/internals/tempname.c --- uClibc-20060603.orig/libc/misc/internals/tempname.c 2006-06-03 07:12:34.000000000 +0000 +++ uClibc-20060603/libc/misc/internals/tempname.c 2006-06-04 02:50:57.000000000 +0000 @@ -136,14 +136,23 @@ "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; #define NUM_LETTERS (62) +#if !defined(__MKTEMP_USES_ARC4RANDOM__) static unsigned int fillrand(unsigned char *buf, unsigned int len) { int fd; unsigned int result = -1; - fd = open("/dev/urandom", O_RDONLY); +#ifdef UCLIBC_USES_ERANDOM + fd = open("/dev/erandom", O_RDONLY); + if (fd < 0) { +#endif + fd = open("/dev/urandom", O_RDONLY); +#ifdef UCLIBC_USES_ERANDOM + } +#endif if (fd < 0) { fd = open("/dev/random", O_RDONLY | O_NONBLOCK); } + if (fd >= 0) { result = read(fd, buf, len); close(fd); @@ -174,6 +183,7 @@ buf[i] = letters[k]; } } +#endif /* __MKTEMP_USES_ARC4RANDOM__ */ /* 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 @@ -207,10 +217,14 @@ } /* Get some random data. */ +#if defined(__MKTEMP_USES_ARC4RANDOM__) + randomness[i] = (arc4random() % 62); +#else if (fillrand(randomness, sizeof(randomness)) != sizeof(randomness)) { /* if random device nodes failed us, lets use the braindamaged ver */ brain_damaged_fillrand(randomness, sizeof(randomness)); } +#endif /* __MKTEMP_USES_ARC4RANDOM__ */ for (i = 0; i < sizeof(randomness); ++i) XXXXXX[i] = letters[(randomness[i]) % NUM_LETTERS]; diff -Naur uClibc-20060603.orig/libc/stdlib/arc4random.c uClibc-20060603/libc/stdlib/arc4random.c --- uClibc-20060603.orig/libc/stdlib/arc4random.c 2006-06-03 07:11:21.000000000 +0000 +++ uClibc-20060603/libc/stdlib/arc4random.c 2006-06-04 03:12:10.000000000 +0000 @@ -1,17 +1,25 @@ -/* $$$: arc4random.c 2005/02/08 robert */ -/* $NetBSD: arc4random.c,v 1.5.2.1 2004/03/26 22:52:50 jmc Exp $ */ -/* $OpenBSD: arc4random.c,v 1.6 2001/06/05 05:05:38 pvalchev Exp $ */ +/* Modified for Linux - Robert Connolly 2006/06/03 */ +/* $OpenBSD: arc4random.c,v 1.15 2005/11/30 07:51:02 otto Exp $ */ /* - * Arc4 random number generator for OpenBSD. - * Copyright 1996 David Mazieres . + * Copyright (c) 1996, David Mazieres + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. * - * Modification and redistribution in source and binary forms is - * permitted provided that due credit is given to the author and the - * OpenBSD project by leaving this copyright notice intact. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /* + * Arc4 random number generator for OpenBSD. + * * This code is derived from section 17.1 of Applied Cryptography, * second edition, which describes a stream cipher allegedly * compatible with RSA Labs "RC4" cipher (the actual description of @@ -26,41 +34,48 @@ * RC4 is a registered trademark of RSA Laboratories. */ -#include #include #include #include #include #include #include -#ifdef __ARC4RANDOM_USE_ERANDOM__ #include -//libc_hidden_proto(sysctl) -#endif +#ifdef __UCLIBC__ libc_hidden_proto(open) libc_hidden_proto(read) libc_hidden_proto(close) libc_hidden_proto(gettimeofday) +#endif + +#if defined(IS_IN_libc) && !defined(__UCLIBC__) && defined(__GLIBC__) +#define open __open +#define read __read +#define close __close +#endif + +#ifdef __GNUC__ +#define inline __inline +#else /* !__GNUC__ */ +#define inline +#endif /* !__GNUC__ */ struct arc4_stream { - uint8_t i; - uint8_t j; - uint8_t s[256]; + u_int8_t i; + u_int8_t j; + u_int8_t s[256]; }; -static int rs_initialized; +static int rs_initialized; static struct arc4_stream rs; +static pid_t arc4_stir_pid; +static int arc4_count; -static inline void arc4_init(struct arc4_stream *); -static inline void arc4_addrandom(struct arc4_stream *, u_char *, int); -static void arc4_stir(struct arc4_stream *); -static inline uint8_t arc4_getbyte(struct arc4_stream *); -static inline uint32_t arc4_getword(struct arc4_stream *); +static inline u_int8_t arc4_getbyte(struct arc4_stream *); static inline void -arc4_init(as) - struct arc4_stream *as; +arc4_init(struct arc4_stream *as) { int n; @@ -71,13 +86,10 @@ } static inline void -arc4_addrandom(as, dat, datlen) - struct arc4_stream *as; - u_char *dat; - int datlen; +arc4_addrandom(struct arc4_stream *as, u_char *dat, int datlen) { int n; - uint8_t si; + u_int8_t si; as->i--; for (n = 0; n < 256; n++) { @@ -91,44 +103,86 @@ } static void -arc4_stir(as) - struct arc4_stream *as; +arc4_stir(struct arc4_stream *as) { - int fd; - struct { - struct timeval tv; - uint rnd[(128 - sizeof(struct timeval)) / sizeof(uint)]; - } rdat; - int n; - - gettimeofday(&rdat.tv, NULL); - fd = open("/dev/urandom", O_RDONLY); - if (fd != -1) { - read(fd, rdat.rnd, sizeof(rdat.rnd)); - close(fd); - } -#ifdef __ARC4RANDOM_USE_ERANDOM__ - else { - int mib[3]; - uint i; - size_t len; - - /* Device could not be opened, we might be chrooted, take - * randomness from sysctl. */ - - mib[0] = CTL_KERN; - mib[1] = KERN_RANDOM; - mib[2] = RANDOM_ERANDOM; - - for (i = 0; i < sizeof(rdat.rnd) / sizeof(uint); i++) { - len = sizeof(uint); - if (sysctl(mib, 3, &rdat.rnd[i], &len, NULL, 0) == -1) - break; +/* + * Erandom (Frandom's daughter) is a pseudo random number generator which + * uses no kernel entropy during use, but is seeded by Frandom which is + * seeded by kernel entropy. Erandom's initial seed is available only to + * root/the-kernel, making Erandom's output safe for security applications. + * Thanks to Eli Billauer for the Erandom + * kernel driver. Also see + */ + +/* + * Erandom is available as a sysctl value. Sysctl has the advantage of + * working from inside a chroot. Although sysctl is a single-threaded + * interface, the operation of obtaining a value from sysctl is so quick + * that there is little-to-no wait time for processes, and peformance is + * excelent. + * + * SYSCTL_ERANDOM* is defined from . This requires a + * modified kernel. Also see: + * + */ + +/* The vanilla Erandom sysctl provides 16 bytes. */ +/* The modified fat version of Erandom sysctl provides 256 bytes. */ + + int i, fd; + u_char rnd[128]; + +/* If SYSCTL_ERANDOM* is defined, use it first. */ +#if !defined(__UCLIBC__) || defined(ARC4RANDOM_USES_SYSCTL_ERANDOM) +#if defined(SYSCTL_ERANDOM) || defined(SYSCTL_ERANDOM256) + int mib[]={CTL_KERN, KERN_RANDOM, RANDOM_ERANDOM}; + size_t len; + len = sizeof(rnd); +#endif +#ifdef SYSCTL_ERANDOM256 + /* Fill the buffer in one shot. */ + if (sysctl(mib, 3, rnd, &len, NULL, 0) == -1) { +#endif +#ifdef SYSCTL_ERANDOM + /* Fill the buffer in eight shots. */ + for (i = 0; i < sizeof(rnd) / sizeof(u_int); i ++) { + len = sizeof(u_int); + if (sysctl(mib, 3, rnd[i], &len, NULL, 0) == -1) { +#endif +#endif /* !__UCLIBC__ || ARC4RANDOM_USES_SYSCTL_ERANDOM */ +#if !defined(__UCLIBC__) || defined(UCLIBC_USES_ERANDOM) + /* If sysctl erandom did not work, try /dev/erandom. */ + fd = open("/dev/erandom", O_RDONLY); + if (fd != -1) { + read(fd, rnd, sizeof(rnd)); + close(fd); } + else { +#endif + /* If /dev/erandom did not work try /dev/urandom. */ + fd = open("/dev/urandom", O_RDONLY); + if (fd != -1) { + read(fd, rnd, sizeof(rnd)); + close(fd); + } + else { + /* Erandom and Urandom failed? Use the time. */ + struct { + struct timeval tv; + u_int rnd[(128 - sizeof(struct timeval)) + / sizeof(u_int)]; + } rdat; + gettimeofday(&rdat.tv, NULL); + } +#if !defined(__UCLIBC__) || defined(UCLIBC_USES_ERANDOM) + } +#endif +#if defined(SYSCTL_ERANDOM) || defined(SYSCTL_ERANDOM256) } #endif - arc4_addrandom(as, (void *) &rdat, sizeof(rdat)); + arc4_stir_pid = getpid(); + arc4_addrandom(as, rnd, sizeof(rnd)); /* * Throw away the first N words of output, as suggested in the @@ -137,15 +191,16 @@ * http://www.wisdom.weizmann.ac.il/~itsik/RC4/Papers/Rc4_ksa.ps * N = 256 in our case. */ - for (n = 0; n < 256 * 4; n++) - arc4_getbyte(as); + + for (i = 0; i < 256; i++) + (void)arc4_getbyte(as); + arc4_count = 400000; } -static inline uint8_t -arc4_getbyte(as) - struct arc4_stream *as; +static inline u_int8_t +arc4_getbyte(struct arc4_stream *as) { - uint8_t si, sj; + u_int8_t si, sj; as->i = (as->i + 1); si = as->s[as->i]; @@ -156,11 +211,10 @@ return (as->s[(si + sj) & 0xff]); } -static inline uint32_t -arc4_getword(as) - struct arc4_stream *as; +static inline u_int32_t +arc4_getword(struct arc4_stream *as) { - uint32_t val; + u_int32_t val; val = arc4_getbyte(as) << 24; val |= arc4_getbyte(as) << 16; val |= arc4_getbyte(as) << 8; @@ -168,7 +222,9 @@ return val; } +#ifdef __UCLIBC__ libc_hidden_proto(arc4random_stir) +#endif void arc4random_stir(void) { @@ -178,7 +234,9 @@ } arc4_stir(&rs); } +#ifdef __UCLIBC__ libc_hidden_def(arc4random_stir) +#endif void arc4random_addrandom(u_char *dat, int datlen) @@ -188,16 +246,17 @@ arc4_addrandom(&rs, dat, datlen); } -uint32_t +u_int32_t arc4random(void) { - if (!rs_initialized) + if (--arc4_count == 0 || !rs_initialized || arc4_stir_pid != getpid()) arc4random_stir(); return arc4_getword(&rs); } #if 0 /*-------- Test code --------*/ +/* Output a random number */ #include #include diff -Naur uClibc-20060603.orig/libc/sysdeps/linux/common/ssp.c uClibc-20060603/libc/sysdeps/linux/common/ssp.c --- uClibc-20060603.orig/libc/sysdeps/linux/common/ssp.c 2006-06-03 07:12:01.000000000 +0000 +++ uClibc-20060603/libc/sysdeps/linux/common/ssp.c 2006-06-04 01:40:52.000000000 +0000 @@ -20,7 +20,7 @@ #error "file must not be compiled with stack protection enabled on it. Use -fno-stack-protector" #endif -#ifdef __PROPOLICE_BLOCK_SEGV__ +#ifdef __SSP_BLOCK_SEGV__ # define SSP_SIGTYPE SIGSEGV #else # define SSP_SIGTYPE SIGABRT