On Friday April 13 2007 13:43, Robert Connolly wrote:
> I also put the erandom stuff back in, _dl_sysctl, and an arc4random.c
> update (including better copyright). I just gave up on 0.9.29-pre1 a few
> minutes ago, so I should have a gcc3/4 friendly (no warnings, dual runtime
> compatible) 0.9.28.3-ssp_erandom_arc4random patch this weekend.
>
> Are you guys cool with a "result = arc4random();" "if result != -1 {return
> result;}" option for tempname.c?

I've attached the should_work_but_doesn't/request_for_feedback patch. 
__sysctl_args needs initializers to make gcc happy.

and the Changelog:

* extra/Configs/Config.in

    Moved UCLIBC_BUILD_RELRO, UCLIBC_BUILD_NOW, UCLIBC_BUILD_NOEXECSTACK,
        up in the Security menu list, so the SSP menu is easier to read
        and follow.

    s/smashing stack protector/Stack Smashing Protector/
    s/propolice/ssp/
    s/SSP_COMPAT/SSP_LEGACY/
    s/PROPOLICE_BLOCK_SEGV/SSP_BLOCK_SEGV/

    Various description modifications in the Security menu.

    Added SSP_STATIC_CANARY for low security environments.

    Added UCLIBC_USES_ERND and UCLIBC_USES_SYSCTL_ERND for
        /dev/erandom and sysctl erandom

* ldso/include/dl-syscall.h

    Added UCLIBC_USES_SYSCTL_ERND for _dl__sysctl.

* libc/misc/internals/__uClibc_main.c

    s/SSP_COMPAT/SSP_LEGACY/

* libc/misc/internals/tempname.c

    Implement UCLIBC_USES_ERND and UCLIBC_HAS_ARC4RANDOM.

* libc/sysdeps/linux/common/dl-osinfo.h

    Shorten the 'ifdef __SSP__' error message.
    Implement SSP_STATIC_CANARY.
    Shuffle stuff around, redo indenting, etc.

    s/SSP_COMPAT/SSP_LEGACY/

    Implement UCLIBC_USES_ERND and UCLIBC_USES_SYSCTL_ERND.

    Inadvertently fixed the gcc-4.1 segmentation faults
        with -fstack-protector[-all].

    GCC34 and GCC41 happy with -Wall -Wformat=2 -Wextra -Wshadow.

* libc/sysdeps/linux/common/ssp.c

    Shorten the 'ifdef __SSP__' error message.
    Implement SSP_STATIC_CANARY.
    Shuffle stuff around, redo indenting, etc.

    s/SSP_COMPAT/SSP_LEGACY/
    s/PROPOLICE_BLOCK_SEGV/SSP_BLOCK_SEGV/

    Alias __stack_smash_handler to __stack_chk_fail.

    GCC34 and GCC41 happy with -Wall -Wformat=2 -Wextra -Wshadow.

* libc/stdlib/arc4random.c

    Modifications from upstream, based on OpenBSD arc4random.c
        CVS version 1.16 2007/02/12. Modified how the beginning
        of the stream is discarded, and removed unneeded prototypes.
        Added __arc4_getbyte, commented out, for future use.
        New copyright, with authors blessing, which is slightly
        more liberal and clear, and added a disclaimer.

    Implement UCLIBC_USES_ERND and UCLIBC_USES_SYSCTL_ERND.

    Wrap hidden proto's in IS_IN_libc.

    GCC34 and GCC41 happy with -Wall -Wformat=2 -Wextra -Wshadow.

* libc/sysdeps/linux/common/sysctl.c

        Added hidden proto defintion for UCLIBC_USES_SYSCTL_ERND.

robert
diff -Naur uClibc-0.9.29-pre1.orig/extra/Configs/Config.in uClibc-0.9.29-pre1/extra/Configs/Config.in
--- uClibc-0.9.29-pre1.orig/extra/Configs/Config.in	2007-02-14 08:25:26.000000000 +0000
+++ uClibc-0.9.29-pre1/extra/Configs/Config.in	2007-04-13 15:08:45.000000000 +0000
@@ -1296,19 +1296,72 @@
 	  It requires gcc-3.4 and binutils-2.15 (for arm 2.16) or later.
 	  More about ET_DYN/PIE binaries on <http://pax.grsecurity.net/> .
 	  WARNING: This option also enables FORCE_SHAREABLE_TEXT_SEGMENTS, so all
-		libraries have to be built with -fPIC or -fpic, and all assembler
-		functions must be written as position independent code (PIC).
+	           libraries have to be built with the -fPIC or -fpic compiler
+	           options, and all assembler functions must be written as
+	           Position Independent Code (PIC).
+
+config UCLIBC_BUILD_RELRO
+	bool "Build uClibc with PT_GNU_RELRO segment headers"
+	depends on HAVE_SHARED
+	default y
+	help
+	  Build all libraries and executables with the '-z relro' linker option.
+	  This option tells the dynamic linker to mark the memory region as
+	  read-only after it has completed the relocations.
+
+config UCLIBC_BUILD_NOW
+	bool "Build uClibc to resolve all symbols at run time"
+	depends on HAVE_SHARED
+	default n
+	help
+	  Build all libraries and executables with the '-z now' linker option.
+	  This marking tells the dynamic linker to resolve all symbols when
+	  the program or library is first loaded, instead of when the when
+	  when the function is called. This is more secure but causes a
+	  slight load time performance overhead.
+
+config UCLIBC_BUILD_NOEXECSTACK
+	bool "Build uClibc with noexecstack marking"
+	default y
+	help
+	  Mark all assembler files as noexecstack. This will result in marking
+	  all programs and libraries built against uClibc to not require
+	  an executable stack.
+
+config UCLIBC_USES_ERND
+	bool "Use 'erandom' instead of 'urandom' in uClibc"
+	default n
+	help
+	  Answer Y to use the erandom (economical random) device instead of
+	  urandom. This affects mktemp(3), arc4random(3), and Stack
+	  Smashing Protector. If /dev/erandom is not found at run time then
+	  /dev/urandom will be used. This option requires a modified kernel.
+	  See: http://frandom.sourceforge.net/
+	  Most people will answer N.
+
+config UCLIBC_USES_SYSCTL_ERND
+	bool "Use the sysctl erandom interface in uClibc"
+	depends on UCLIBC_USES_ERND
+	default n
+	help
+	  With this option enabled uClibc will use the erandom sysctl interface.
+	  This has the advantage of working from inside a chroot without /dev.
+	  This option also only uses one system call, while opening, reading,
+	  and closing a device node uses three system calls. This option
+	  requires a modified <linux/sysctl.h> header, in addition to a modified
+	  kernel.
+	  Most people will answer N.
 
 config UCLIBC_HAS_ARC4RANDOM
 	bool "Include the arc4random() function"
 	default n
 	help
-	  Answer Y to support the OpenBSD-like arc4random() function. This
+	  Answer Y to support the OpenBSD-like arc4random(3) 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.
+	  OpenSSL, OpenNTPD, and ICS-Bind currently support this function.
 
 	  Most people will answer N.
 
@@ -1317,46 +1370,76 @@
 	default n
 
 config UCLIBC_HAS_SSP
-	bool "Support for propolice smashing stack protector"
+	bool "Support for Stack Smashing Protector (SSP). a.k.a. ProPolice"
 	depends on !HAVE_NO_SSP
 	default n
 	help
-	  Add propolice smashing stack protector 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.
+	  This option requires the GCC -fstack-protector[-all] feature to
+	  utilize. This option replaces "libssp", from GCC 4.1+, and is ideal
+	  if you build all or most of your system with -fstack-protector[-all].
+	  If you only build a small number of applications with this protection
+	  then linking to "libssp" may be more appropriate. Build GCC 4.1+ with
+	  'make gcc_cv_libc_provides_ssp=yes' to force GCC 4.1+ to use SSP from
+	  ldso/libc.
+	  Third-party patches for older GCC versions are available, and will
+	  require you to enable the UCLIBC_HAS_SSP_LEGACY option to use.
+	  For more information see:
+	  <http://www.research.ibm.com/trl/projects/security/ssp/>
+	  Note about entropy:
+	  By default Stack Smashing Protector uses /dev/urandom as a source of
+	  entropy each time a protected program is run. This can lead to the
+	  /dev/random device running out of entropy, causing cryptographic
+	  software to block and wait for more entropy. There are alternatives
+	  for SSP. The /dev/erandom device is ideal for non-cryptographic
+	  applications like SSP. It is also possible to use High Precision
+	  Timing (hp-timing), kernel stack, and memory-map (mmap) XOR values,
+	  and finally gettimeofday(2) XOR values. Each in turn is higher
+	  performance and less secure. The sysctl interface for erandom,
+	  hp-timing, and gettimeofday(2) have the advantage of working
+	  from inside a chroot without /dev/*random devices.
 	  Most people will answer N.
 
-config UCLIBC_HAS_SSP_COMPAT
-	bool "Support for gcc-3.x propolice smashing stack protector"
+config UCLIBC_HAS_SSP_LEGACY
+	bool "Support for legacy Stack Smashing Protector"
 	depends on UCLIBC_HAS_SSP
 	default n
 	help
-	  Add gcc-3.x propolice smashing stack 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.
-	  These functions are added to ldso/libc instead.
-	  More information at:
-	  <http://www.research.ibm.com/trl/projects/security/ssp/>
+	  This option enables support for GCC 2.95.3 and 3.x Stack
+	  Smashing Protector to the library. This requires a modified
+	  GCC supporting the -fstack-protector[-all] options, with
+	  the __guard and __stack_smash_handler functions removed from
+	  libgcc.
 	  Most people will answer N.
 
-config SSP_QUICK_CANARY
-	bool "Use simple guard values without accessing /dev/urandom"
+config SSP_STATIC_CANARY
+	bool "Only use the 'terminator canary' for the SSP guard value"
 	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
-	  	attacks.
+	  Use a static (never changing) value for the SSP guard value.
+	  This option has the least security and highest performance.
+	  This option should only be used for debugging, or very low security
+	  environments.
+	  WARNING: This makes Stack Smashing Protector vulnerable to attack.
+	  Most people will answer N.
+
+config SSP_QUICK_CANARY
+	bool "Use simple SSP guard values without accessing a random device"
+	depends on UCLIBC_HAS_SSP && !SSP_STATIC_CANARY
+	default n
+	help
+	  Use gettimeofday(2) to define the SSP guard value without accessing
+	  /dev/urandom. If gettimeofday(2) fails then a static canary will be
+	  used.
+	  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 kill 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.
@@ -1366,42 +1449,22 @@
 
 	  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 protection"
 	depends on UCLIBC_HAS_SSP
 	default n
 	help
-	  Build all libraries and executables with propolice protection enabled.
-
-config UCLIBC_BUILD_RELRO
-	bool "Build uClibc with RELRO"
-	depends on HAVE_SHARED
-	default y
-	help
-	  Build all libraries and executables with -z relro.
-
-config UCLIBC_BUILD_NOW
-	bool "Build uClibc with NOW"
-	depends on HAVE_SHARED
-	default n
-	help
-	  Build all libraries and executables with -z now.
-
-config UCLIBC_BUILD_NOEXECSTACK
-	bool "Build uClibc with noexecstack marking"
-	default y
-	help
-	  Mark all assembler files as noexecstack. This will result in marking
-	  all libraries and executables built against uClibc not requiring
-	  executable stack.
+	  Build all programs and libraries with -fstack-protector[-all].
+	  This adds approximately 4-8% performance overhead, and increases
+	  the size of the uClibc library by about 1.5%.
 
 endmenu
 
diff -Naur uClibc-0.9.29-pre1.orig/ldso/include/dl-syscall.h uClibc-0.9.29-pre1/ldso/include/dl-syscall.h
--- uClibc-0.9.29-pre1.orig/ldso/include/dl-syscall.h	2006-12-06 20:22:42.000000000 +0000
+++ uClibc-0.9.29-pre1/ldso/include/dl-syscall.h	2007-04-13 15:08:45.000000000 +0000
@@ -131,6 +131,18 @@
 # endif
 #endif
 
+#ifdef __UCLIBC_USES_SYSCTL_ERND__
+#  include <sys/sysctl.h>
+#  define __NR__dl__sysctl __NR__sysctl
+
+       _syscall1(int, _dl__sysctl, struct __sysctl_args *, args);
+       int _dl_sysctl(int *name, int nlen, void *oldval, size_t *oldlenp,
+                  void *newval, size_t newlen)
+       {
+               struct __sysctl_args args={name,nlen,oldval,oldlenp,newval,newlen};
+               return _dl__sysctl(&args);
+       }
+#endif
 
 /* handle all the fun mmap intricacies */
 #if (defined(__UCLIBC_MMAP_HAS_6_ARGS__) && defined(__NR_mmap)) || !defined(__NR_mmap2)
diff -Naur uClibc-0.9.29-pre1.orig/ldso/ldso/ldso.c uClibc-0.9.29-pre1/ldso/ldso/ldso.c
--- uClibc-0.9.29-pre1.orig/ldso/ldso/ldso.c	2007-03-31 13:42:48.000000000 +0000
+++ uClibc-0.9.29-pre1/ldso/ldso/ldso.c	2007-04-13 15:08:45.000000000 +0000
@@ -100,10 +100,10 @@
 /* Only exported for architectures that don't store the stack guard canary
  * in local thread area.  */
 uintptr_t __stack_chk_guard attribute_relro;
-#  ifdef __UCLIBC_HAS_SSP_COMPAT__
+#  ifdef __UCLIBC_HAS_SSP_LEGACY__
 strong_alias(__stack_chk_guard,__guard)
 #  endif
-# elif __UCLIBC_HAS_SSP_COMPAT__
+# elif __UCLIBC_HAS_SSP_LEGACY__
 uintptr_t __guard attribute_relro;
 # endif
 #endif
@@ -229,7 +229,7 @@
 	stack_chk_guard = _dl_setup_stack_chk_guard ();
 # ifdef THREAD_SET_STACK_GUARD
 	THREAD_SET_STACK_GUARD (stack_chk_guard);
-#  ifdef __UCLIBC_HAS_SSP_COMPAT__
+#  ifdef __UCLIBC_HAS_SSP_LEGACY__
 	__guard = stack_chk_guard;
 #  endif
 # else
diff -Naur uClibc-0.9.29-pre1.orig/libc/misc/internals/__uClibc_main.c uClibc-0.9.29-pre1/libc/misc/internals/__uClibc_main.c
--- uClibc-0.9.29-pre1.orig/libc/misc/internals/__uClibc_main.c	2007-01-11 22:39:13.000000000 +0000
+++ uClibc-0.9.29-pre1/libc/misc/internals/__uClibc_main.c	2007-04-13 15:08:45.000000000 +0000
@@ -61,14 +61,14 @@
 /* for gcc-4.1 non-TLS */
 uintptr_t __stack_chk_guard attribute_relro;
 /* for gcc-3.x + Etoh ssp */
-#   ifdef __UCLIBC_HAS_SSP_COMPAT__
+#   ifdef __UCLIBC_HAS_SSP_LEGACY__
 #    ifdef __HAVE_SHARED__
 strong_alias(__stack_chk_guard,__guard)
 #    else
 uintptr_t __guard attribute_relro;
 #    endif
 #   endif
-#  elif defined __UCLIBC_HAS_SSP_COMPAT__
+#  elif defined __UCLIBC_HAS_SSP_LEGACY__
 uintptr_t __guard attribute_relro;
 #  endif
 # endif
@@ -208,12 +208,12 @@
     stack_chk_guard = _dl_setup_stack_chk_guard();
 #  ifdef THREAD_SET_STACK_GUARD
     THREAD_SET_STACK_GUARD (stack_chk_guard);
-#   ifdef __UCLIBC_HAS_SSP_COMPAT__
+#   ifdef __UCLIBC_HAS_SSP_LEGACY__
     __guard = stack_chk_guard;
 #   endif
 #  else
     __stack_chk_guard = stack_chk_guard;
-#   if !defined __HAVE_SHARED__ && defined __UCLIBC_HAS_SSP_COMPAT__
+#   if !defined __HAVE_SHARED__ && defined __UCLIBC_HAS_SSP_LEGACY__
      __guard = stack_chk_guard;
 #   endif
 #  endif
diff -Naur uClibc-0.9.29-pre1.orig/libc/misc/internals/tempname.c uClibc-0.9.29-pre1/libc/misc/internals/tempname.c
--- uClibc-0.9.29-pre1.orig/libc/misc/internals/tempname.c	2006-01-27 21:26:40.000000000 +0000
+++ uClibc-0.9.29-pre1/libc/misc/internals/tempname.c	2007-04-13 15:08:45.000000000 +0000
@@ -138,8 +138,17 @@
 
 static unsigned int fillrand(unsigned char *buf, unsigned int len)
 {
-    int fd;
     unsigned int result = -1;
+
+#ifdef __UCLIBC_HAS_ARC4RANDOM__
+    result = arc4random();
+    return result;
+#endif
+    int fd=0;
+
+#ifdef __UCLIBC_USES_ERND__
+    if ((fd = open("/dev/erandom", O_RDONLY)) == (-1))
+#endif
     fd = open("/dev/urandom", O_RDONLY);
     if (fd < 0) {
 	fd = open("/dev/random", O_RDONLY | O_NONBLOCK);
diff -Naur uClibc-0.9.29-pre1.orig/libc/stdlib/arc4random.c uClibc-0.9.29-pre1/libc/stdlib/arc4random.c
--- uClibc-0.9.29-pre1.orig/libc/stdlib/arc4random.c	2006-02-13 07:42:06.000000000 +0000
+++ uClibc-0.9.29-pre1/libc/stdlib/arc4random.c	2007-04-13 15:15:27.000000000 +0000
@@ -1,17 +1,22 @@
-/*	$$$: 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 $	*/
-
 /*
- * Arc4 random number generator for OpenBSD.
- * Copyright 1996 David Mazieres <[EMAIL PROTECTED]>.
+ * Copyright (c) 1996, David Mazieres <[EMAIL PROTECTED]>
  *
- * 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.
+ * 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.
+ *
+ * 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,22 +31,38 @@
  * RC4 is a registered trademark of RSA Laboratories.
  */
 
+/* Modified for Linux uClibc by Robert Connolly */
+
 #include <features.h>
+
 #include <fcntl.h>
 #include <stdlib.h>
 #include <unistd.h>
 #include <sys/types.h>
 #include <sys/param.h>
 #include <sys/time.h>
-#ifdef __ARC4RANDOM_USE_ERANDOM__
+
+#include <stdint.h>
+
+#ifdef __UCLIBC_USES_SYSCTL_ERND__
 #include <sys/sysctl.h>
-//libc_hidden_proto(sysctl)
+# ifdef IS_IN_libc
+libc_hidden_proto(sysctl)
+# endif
 #endif
 
+#ifdef IS_IN_libc
 libc_hidden_proto(open)
 libc_hidden_proto(read)
 libc_hidden_proto(close)
 libc_hidden_proto(gettimeofday)
+#endif
+
+#ifdef __GNUC__
+#define inline __inline
+#else
+#define inline
+#endif
 
 struct arc4_stream {
 	uint8_t i;
@@ -49,18 +70,15 @@
 	uint8_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 void
-arc4_init(as)
-	struct arc4_stream *as;
+arc4_init(struct arc4_stream *as)
 {
 	int     n;
 
@@ -71,10 +89,7 @@
 }
 
 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;
@@ -91,59 +106,52 @@
 }
 
 static void
-arc4_stir(as)
-	struct arc4_stream *as;
+arc4_stir(struct arc4_stream *as)
 {
-	int     fd;
+	int	i=0, fd=0;
+	size_t	len;
 	struct {
 		struct timeval tv;
-		uint rnd[(128 - sizeof(struct timeval)) / sizeof(uint)];
-	}       rdat;
-	int	n;
+		u_int rnd[(128 - sizeof(struct timeval)) / sizeof(u_int)];
+	}	rdat;
+
+        gettimeofday(&rdat.tv, NULL);
+
+#ifdef __UCLIBC_USES_SYSCTL_ERND__
+	int	mib[3];
+
+	mib[0] = CTL_KERN;
+	mib[1] = KERN_RANDOM;
+	mib[2] = RANDOM_ERANDOM;
+
+	len = sizeof(rnd);
+	if (sysctl(mib, 3, &rnd, &len, NULL, 0) == (-1))
+#endif
+#ifdef __UCLIBC_USES_ERND__
+	if (fd = open("/dev/erandom", O_RDONLY, 0) == (-1))
+#endif
+	fd = open("/dev/urandom", O_RDONLY, 0);
 
-	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;
-		}
-	}
-#endif
 
-	arc4_addrandom(as, (void *) &rdat, sizeof(rdat));
+	arc4_stir_pid = getpid();
+	arc4_addrandom(as, &rdat, sizeof(rdat));
 
 	/*
-	 * Throw away the first N words of output, as suggested in the
-	 * paper "Weaknesses in the Key Scheduling Algorithm of RC4"
-	 * by Fluher, Mantin, and Shamir.
+	 * Discard early keystream, as per recommendations in:
 	 * 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 = 1600000;
 }
 
 static inline uint8_t
-arc4_getbyte(as)
-	struct arc4_stream *as;
+arc4_getbyte(struct arc4_stream *as)
 {
 	uint8_t si, sj;
 
@@ -156,9 +164,21 @@
 	return (as->s[(si + sj) & 0xff]);
 }
 
+#if 0
+/* This is intended as a libc private function, so other parts of libc
+   can get entropy without calling getpid(2). This is not yet implemented
+   for uClibc. */
+uint8_t
+__arc4_getbyte(void)
+{
+	if (--arc4_count == 0 || !rs_initialized)
+		arc4random_stir();
+	return arc4_getbyte(&rs);
+}
+#endif
+
 static inline uint32_t
-arc4_getword(as)
-	struct arc4_stream *as;
+arc4_getword(struct arc4_stream *as)
 {
 	uint32_t val;
 	val = arc4_getbyte(as) << 24;
@@ -168,7 +188,9 @@
 	return val;
 }
 
+#ifdef IS_IN_libc
 libc_hidden_proto(arc4random_stir)
+#endif
 void
 arc4random_stir(void)
 {
@@ -178,8 +200,11 @@
 	}
 	arc4_stir(&rs);
 }
+#ifdef IS_IN_libc
 libc_hidden_def(arc4random_stir)
+#endif
 
+/* arc4random_addrandom() is used by third parties, like ICS-BIND. */
 void
 arc4random_addrandom(u_char *dat, int datlen)
 {
@@ -191,20 +216,24 @@
 uint32_t
 arc4random(void)
 {
-	if (!rs_initialized)
+	arc4_count -= 4;
+	if (arc4_count <= 0 || !rs_initialized || arc4_stir_pid != getpid())
 		arc4random_stir();
 	return arc4_getword(&rs);
 }
 
 #if 0
 /*-------- Test code --------*/
-#include <stdlib.h>
-#include <stdio.h>
+/* Copyright 2003, Han Boetes <[EMAIL PROTECTED]>
+ * This is released in public domain. */
+
+# include <stdlib.h>
+# include <stdio.h>
 
 int main(void) {
     int random_number;
-    random_number = arc4random() % 65536;
-    printf("%d\n", random_number);
+    random_number = arc4random(); /* "arc4random() % 65536;" would also work. */
+    printf("arc4random number is %d\n", random_number);
     return 0;
 }
 #endif
diff -Naur uClibc-0.9.29-pre1.orig/libc/sysdeps/linux/common/dl-osinfo.h uClibc-0.9.29-pre1/libc/sysdeps/linux/common/dl-osinfo.h
--- uClibc-0.9.29-pre1.orig/libc/sysdeps/linux/common/dl-osinfo.h	2006-01-14 00:58:03.000000000 +0000
+++ uClibc-0.9.29-pre1/libc/sysdeps/linux/common/dl-osinfo.h	2007-04-13 15:14:59.000000000 +0000
@@ -13,56 +13,97 @@
 # if defined IS_IN_libc || defined IS_IN_rtld
 
 #  if defined __SSP__ || defined __SSP_ALL__
-#   error "file must not be compiled with stack protection enabled on it. Use -fno-stack-protector"
+#   error "This file must not be compiled with stack protection. Use -fno-stack-protector"
 #  endif
 
 #  include <stdint.h>
-#  include <sys/time.h>
 
-#  ifdef IS_IN_libc
-#include <fcntl.h>
+#  ifndef __SSP_STATIC_CANARY__
+#   include <sys/time.h>
+#   ifdef IS_IN_libc
+libc_hidden_proto(gettimeofday)
+#    define GETTIMEOFDAY gettimeofday
+#   else /* This is IS_IN_rtld */
+#    define GETTIMEOFDAY _dl_gettimeofday
+#   endif /* IS_IN_libc */
+
+#   if !defined(__SSP_QUICK_CANARY__)
+#    ifdef IS_IN_libc
+#      include <fcntl.h>
 libc_hidden_proto(open)
 libc_hidden_proto(read)
 libc_hidden_proto(close)
-libc_hidden_proto(gettimeofday)
-#   define OPEN open
-#   define READ read
-#   define CLOSE close
-#   define GETTIMEOFDAY gettimeofday
-#  else
-#   define OPEN _dl_open
-#   define READ _dl_read
-#   define CLOSE _dl_close
-#   define GETTIMEOFDAY _dl_gettimeofday
-#  endif
+#      define OPEN open
+#      define READ read
+#      define CLOSE close
+#    else /* This is IS_IN_rtld */
+#     define OPEN _dl_open
+#     define READ _dl_read
+#     define CLOSE _dl_close
+#    endif /* IS_IN_libc */
+
+#    ifdef __UCLIBC_USES_SYSCTL_ERND__
+#     include <sys/sysctl.h>
+#      ifdef IS_IN_libc
+libc_hidden_proto(sysctl)
+#       define SYSCTL sysctl
+#      else /* This is IS_IN_rtld */
+#       define SYSCTL _dl_sysctl
+#      endif /* IS_IN_libc */
+#    endif /* __UCLIBC_USES_SYSCTL_ERND__ */
+#   endif /* !__SSP_QUICK_CANARY__ */
+#  endif /* !__SSP_STATIC_CANARY__ */
 
 static __always_inline uintptr_t _dl_setup_stack_chk_guard(void)
 {
 	uintptr_t ret;
-#  ifndef __SSP_QUICK_CANARY__
-	{
-		int fd = OPEN("/dev/urandom", O_RDONLY, 0);
-		if (fd >= 0) {
-			size_t size = READ(fd, &ret, sizeof(ret));
-			CLOSE(fd);
-			if (size == (size_t) sizeof(ret))
-				return ret;
-		}
-	}
-#  endif /* !__SSP_QUICK_CANARY__ */
 
-	/* Start with the "terminator canary". */
-	ret = 0xFF0A0D00UL;
+#  if !defined(__SSP_QUICK_CANARY__) && !defined(__SSP_STATIC_CANARY__)
+#   ifdef __UCLIBC_USES_SYSCTL_ERND__
+	int	mib[3];
+	size_t	len;
+
+	mib[0] = CTL_KERN;
+	mib[1] = KERN_RANDOM;
+	mib[2] = RANDOM_ERANDOM;
+
+	len = sizeof(ret);
+	if (SYSCTL(mib, 3, &ret, &len, NULL, 0) != (-1) &&
+	    len == sizeof(ret))
+	      {
+		return ret;
+	      }
+#   endif
+
+	int fd=0;
+
+#   ifdef __UCLIBC_USES_ERND__
+	if ((fd = OPEN("/dev/erandom", O_RDONLY, 0)) == (-1))
+#   endif
+	fd = OPEN ("/dev/urandom", O_RDONLY, 0);
+	if (fd >= 0)
+	  {
+		ssize_t reslen = READ (fd, &ret, sizeof (ret));
+		CLOSE (fd);
+		if (reslen == (ssize_t) sizeof(ret))
+		  return ret;
+	  }
+#  endif /* !__SSP_QUICK_CANARY__ && !__SSP_STATIC_CANARY__ */
+
+#  ifndef __SSP_STATIC_CANARY__
+	struct timeval tv;
+	if (GETTIMEOFDAY(&tv, NULL) != (-1))
+	  {
+		ret ^= tv.tv_usec ^ tv.tv_sec;
+		  return ret;
+	  }
+#  endif
 
-	/* Everything failed? Or we are using a weakened model of the 
-	 * terminator canary */
-	{
-		struct timeval tv;
-		if (GETTIMEOFDAY(&tv, NULL) != (-1))
-			ret ^= tv.tv_usec ^ tv.tv_sec;
-	}
+	/* __SSP_STATIC_CANARY__ */
+	ret = 0xFF0A0D00UL;
 	return ret;
 }
+
 # endif /* libc || rtld */
 #endif /* __UCLIBC_HAS_SSP__ */
 
diff -Naur uClibc-0.9.29-pre1.orig/libc/sysdeps/linux/common/ssp.c uClibc-0.9.29-pre1/libc/sysdeps/linux/common/ssp.c
--- uClibc-0.9.29-pre1.orig/libc/sysdeps/linux/common/ssp.c	2006-01-26 22:04:19.000000000 +0000
+++ uClibc-0.9.29-pre1/libc/sysdeps/linux/common/ssp.c	2007-04-13 15:08:45.000000000 +0000
@@ -3,7 +3,7 @@
  * $Header: $
  *
  * This is a modified version of Hiroaki Etoh's stack smashing routines
- * implemented for glibc.
+ * implemented for uClibc.
  *
  * The following people have contributed input to this code.
  * Ned Ludd - <[EMAIL PROTECTED]>
@@ -17,10 +17,10 @@
  */
 
 #if defined __SSP__ || defined __SSP_ALL__
-#error "file must not be compiled with stack protection enabled on it. Use -fno-stack-protector"
+#error "This file must not be compiled with stack protection. Use -fno-stack-protector"
 #endif
 
-#ifdef __PROPOLICE_BLOCK_SEGV__
+#ifdef __SSP_BLOCK_SEGV__
 # define SSP_SIGTYPE SIGSEGV
 #else
 # define SSP_SIGTYPE SIGABRT
@@ -50,52 +50,31 @@
 	struct sigaction sa;
 	sigset_t mask;
 
-	sigfillset(&mask);
+	(void)sigfillset(&mask);
+	(void)sigdelset(&mask, SSP_SIGTYPE); /* Block signals. */
+	(void)sigprocmask(SIG_BLOCK, &mask, NULL); /* except SIGABRT */
 
-	sigdelset(&mask, SSP_SIGTYPE);	/* Block all signal handlers */
-	sigprocmask(SIG_BLOCK, &mask, NULL);	/* except SSP_SIGTYPE */
-
-	/* Make the default handler associated with the signal handler */
-	memset(&sa, 0, sizeof(struct sigaction));
-	sigfillset(&sa.sa_mask);	/* Block all signals */
+	(void)memset(&sa, 0, sizeof(sa));
 	sa.sa_flags = 0;
 	sa.sa_handler = SIG_DFL;
-	sigaction(SSP_SIGTYPE, &sa, NULL);
+	(void)sigaction(SSP_SIGTYPE, &sa, NULL);
 }
 
-static void ssp_write(int fd, const char *msg1, const char *msg2, const char *msg3)
+static void ssp_write(int fd, const char *msg1,
+		       const char *msg2, const char *msg3)
 {
 	write(fd, msg1, strlen(msg1));
 	write(fd, msg2, strlen(msg2));
 	write(fd, msg3, strlen(msg3));
 	write(fd, "()\n", 3);
 	openlog("ssp", LOG_CONS | LOG_PID, LOG_USER);
-	syslog(LOG_INFO, "%s%s%s()", msg1, msg2, msg3);
+	syslog(LOG_INFO, "%s%s%s", msg1, msg2, msg3);
 	closelog();
 }
 
-static attribute_noreturn void terminate(void)
-{
-	(void) kill(getpid(), SSP_SIGTYPE);
-	_exit(127);
-}
-
-void __stack_smash_handler(char func[], int damaged __attribute__ ((unused))) attribute_noreturn;
-void __stack_smash_handler(char func[], int damaged)
-{
-	static const char message[] = ": stack smashing attack in function ";
-
-	block_signals();
-
-	ssp_write(STDERR_FILENO, __uclibc_progname, message, func);
-
-	/* The loop is added only to keep gcc happy. */
-	while(1)
-		terminate();
-}
-
-void __stack_chk_fail(void) attribute_noreturn;
-void __stack_chk_fail(void)
+void __stack_chk_fail(void) __attribute__((__noreturn__));
+void
+__stack_chk_fail(void)
 {
 	static const char msg1[] = "stack smashing detected: ";
 	static const char msg3[] = " terminated";
@@ -104,24 +83,14 @@
 
 	ssp_write(STDERR_FILENO, msg1, __uclibc_progname, msg3);
 
-	/* The loop is added only to keep gcc happy. */
-	while(1)
-		terminate();
+	while(1) /* Make GCC happy with __attribute__((__noreturn__)). */
+	  {
+		(void)kill(getpid(), SSP_SIGTYPE);
+		_exit(127);
+	  }
 }
 
-#if 0
-void __chk_fail(void) attribute_noreturn;
-void __chk_fail(void)
-{
-	static const char msg1[] = "buffer overflow detected: ";
-	static const char msg3[] = " terminated";
-
-	block_signals();
-
-	ssp_write(STDERR_FILENO, msg1, __uclibc_progname, msg3);
-
-	/* The loop is added only to keep gcc happy. */
-	while(1)
-		terminate();
-}
+#ifdef __UCLIBC_HAS_SSP_LEGACY__
+void
+__stack_smash_handler(void) __attribute__((alias("__stack_chk_fail"),__noreturn__));
 #endif
diff -Naur uClibc-0.9.29-pre1.orig/libc/sysdeps/linux/common/sysctl.c uClibc-0.9.29-pre1/libc/sysdeps/linux/common/sysctl.c
--- uClibc-0.9.29-pre1.orig/libc/sysdeps/linux/common/sysctl.c	2006-12-08 21:05:37.000000000 +0000
+++ uClibc-0.9.29-pre1/libc/sysdeps/linux/common/sysctl.c	2007-04-13 15:08:45.000000000 +0000
@@ -12,6 +12,10 @@
 extern int sysctl (int *__name, int __nlen, void *__oldval,
 		   size_t *__oldlenp, void *__newval, size_t __newlen) __THROW;
 
+#ifdef __UCLIBC_USES_SYSCTL_ERND__
+libc_hidden_proto(sysctl)
+#endif
+
 struct __sysctl_args {
 	int *name;
 	int nlen;
@@ -39,3 +43,6 @@
 
 	return _sysctl(&args);
 }
+#ifdef __UCLIBC_USES_SYSCTL_ERND__
+libc_hidden_def(sysctl)
+#endif

Attachment: pgpW3GotdspvO.pgp
Description: PGP signature

_______________________________________________
uClibc mailing list
[EMAIL PROTECTED]
http://busybox.net/cgi-bin/mailman/listinfo/uclibc

Reply via email to