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