Author: robert
Date: 2007-06-08 03:24:35 -0600 (Fri, 08 Jun 2007)
New Revision: 1828

Added:
   trunk/glibc/glibc-2.5-arc4_prng-2.patch
Log:
Added new arc4_prng patch, adding mkstemps(), and support for strfry()

Added: trunk/glibc/glibc-2.5-arc4_prng-2.patch
===================================================================
--- trunk/glibc/glibc-2.5-arc4_prng-2.patch                             (rev 0)
+++ trunk/glibc/glibc-2.5-arc4_prng-2.patch     2007-06-08 09:24:35 UTC (rev 
1828)
@@ -0,0 +1,1064 @@
+Submitted By: Robert Connolly <robert at linuxfromscratch dot org> (ashes)
+Date: 2007-06-06
+Initial Package Version: 2.5
+Upstream Status: Rejected
+                 http://sources.redhat.com/bugzilla/show_bug.cgi?id=4417
+Origin: OpenBSD src/lib/libc/crypt/arc4random.c v1.16, Alt/Owl Linux's
+        glibc-2.5-owl-alt-res_randomid.patch, and gcc-4.1.2's
+        libiberty/mkstemps.c.
+Description: This patch adds arc4random(3) to the Glibc library, to tempname.c
+for mktemp and friends, to res_init.c and res_mkquery.c to improve the
+resolver, to bindrsvprt.c to randomize the port numbers, and to strfry(3).
+This patch also adds  the mkstemps(3) function.
+
+Both arc4random(3) and mkstemps(3) are non-standard BSD functions. They will
+be used by many packages if they're found, such as openntpd, bind9, perl, kde,
+poppler, binutils, gcc.
+
+Manual pages for arc4random() and mkstemps() are in the manual/ directory.
+
+This patch also adds the --with-prng-device configure option to let you
+specify /dev/urandom, /dev/erandom, or whatever. This device does not need to
+exist at build time. This device will be used arc4random and stack smashing
+protector.
+
+This patch also uses ./configure to check for RANDOM_ERANDOM in
+<linux/sysctl.h>, and will use it with arc4random() if it is found.
+/dev/?random will be used otherwise, and none need to exist in the host kernel
+at build time.
+Note: It looks like the Linux kernel will eventually stop supplying the
+__sysctl syscall, so this option may be removed one day.
+
+After 'make install' you will probably want to install the manual pages by 
hand.
+
+diff -Naur glibc-2.5.orig/config.h.in glibc-2.5/config.h.in
+--- glibc-2.5.orig/config.h.in 2006-03-02 15:54:43.000000000 +0000
++++ glibc-2.5/config.h.in      2007-06-08 08:08:21.000000000 +0000
+@@ -206,6 +206,12 @@
+ /* Define if __stack_chk_guard canary should be randomized at program 
startup.  */
+ #undef ENABLE_STACKGUARD_RANDOMIZE
+ 
++/* Define this to the system's pseudo-random device (/dev/urandom).  */
++#undef PRNG_DEV
++
++/* Define if your <linux/sysctl.h> has RANDOM_ERANDOM.  */
++#undef HAVE_RANDOM_ERANDOM
++
+ /*
+  */
+ 
+diff -Naur glibc-2.5.orig/configure glibc-2.5/configure
+--- glibc-2.5.orig/configure   2006-09-29 20:18:33.000000000 +0000
++++ glibc-2.5/configure        2007-06-08 08:08:21.000000000 +0000
+@@ -313,7 +313,7 @@
+ # include <unistd.h>
+ #endif"
+ 
+-ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME 
PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix 
program_transform_name bindir sbindir libexecdir datadir sysconfdir 
sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir 
build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS with_fp 
with_cvs enable_check_abi oldest_abi bindnow force_install all_warnings build 
build_cpu build_vendor build_os host host_cpu host_vendor host_os subdirs 
add_ons add_on_subdirs base_machine submachine sysnames sysdeps_add_ons 
INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA LN_S CC CFLAGS LDFLAGS CPPFLAGS 
ac_ct_CC OBJEXT BUILD_CC cross_compiling CPP CXX CXXFLAGS ac_ct_CXX AR OBJDUMP 
RANLIB ac_ct_RANLIB MIG AS LD PWD_P MAKE MSGFMT MAKEINFO SED AUTOCONF 
SYSINCLUDES CXX_SYSINCLUDES libc_cv_gcc_static_libgcc BASH libc_cv_have_bash2 
KSH libc_cv_have_ksh AWK PERL INSTALL_INFO BISON VERSIONING 
libc_cv_asm_protected_directive libc_cv_cc_with_l
 ibunwind libc_cv_z_nodelete libc_cv_z_nodlopen libc_cv_z_initfirst 
libc_cv_z_relro libc_cv_Bgroup libc_cv_libgcc_s_suffix libc_cv_as_needed 
ASFLAGS_config libc_cv_z_combreloc libc_cv_z_execstack libc_cv_fpie 
libc_cv_hashstyle fno_unit_at_a_time libc_cv_ssp libc_cv_have_initfini 
no_whole_archive exceptions LIBGD have_libaudit have_libcap have_selinux EGREP 
sizeof_long_double libc_cv_gcc_unwind_find_fde uname_sysname uname_release 
uname_version old_glibc_headers libc_cv_slibdir libc_cv_localedir 
libc_cv_sysconfdir libc_cv_rootsbindir libc_cv_forced_unwind use_ldconfig 
ldd_rewrite_script elf xcoff static shared pic_default profile omitfp bounded 
static_nss nopic_initfini DEFINES mach_interface_list VERSION RELEASE LIBOBJS 
LTLIBOBJS'
++ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME 
PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix 
program_transform_name bindir sbindir libexecdir datadir sysconfdir 
sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir 
build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS with_fp 
with_cvs enable_check_abi oldest_abi bindnow force_install all_warnings build 
build_cpu build_vendor build_os host host_cpu host_vendor host_os subdirs 
add_ons add_on_subdirs base_machine submachine sysnames sysdeps_add_ons 
INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA LN_S CC CFLAGS LDFLAGS CPPFLAGS 
ac_ct_CC OBJEXT BUILD_CC cross_compiling CPP CXX CXXFLAGS ac_ct_CXX AR OBJDUMP 
RANLIB ac_ct_RANLIB MIG AS LD PWD_P MAKE MSGFMT MAKEINFO SED AUTOCONF 
SYSINCLUDES CXX_SYSINCLUDES libc_cv_gcc_static_libgcc BASH libc_cv_have_bash2 
KSH libc_cv_have_ksh AWK PERL INSTALL_INFO BISON VERSIONING 
libc_cv_asm_protected_directive libc_cv_cc_with_l
 ibunwind libc_cv_z_nodelete libc_cv_z_nodlopen libc_cv_z_initfirst 
libc_cv_z_relro libc_cv_Bgroup libc_cv_libgcc_s_suffix libc_cv_as_needed 
ASFLAGS_config libc_cv_z_combreloc libc_cv_z_execstack libc_cv_fpie 
libc_cv_hashstyle fno_unit_at_a_time libc_cv_ssp libc_cv_have_initfini 
no_whole_archive exceptions LIBGD have_libaudit have_libcap have_selinux EGREP 
sizeof_long_double libc_cv_gcc_unwind_find_fde uname_sysname uname_release 
uname_version old_glibc_headers libc_cv_slibdir libc_cv_localedir 
libc_cv_sysconfdir libc_cv_rootsbindir libc_cv_forced_unwind use_ldconfig 
ldd_rewrite_script elf xcoff static shared pic_default have_random_erandom 
profile omitfp bounded static_nss nopic_initfini DEFINES mach_interface_list 
VERSION RELEASE LIBOBJS LTLIBOBJS'
+ ac_subst_files=''
+ 
+ # Initialize some variables set by options.
+@@ -903,6 +903,9 @@
+   --with-headers=PATH     location of system headers to use (for example
+                           /usr/src/linux/include) [default=compiler
+                           default]
++  --with-prng-device=/path/to/prng
++                          specify the path to the system's pseudo-random
++                          device. [default=/dev/urandom]
+   --with-tls              enable support for TLS
+   --without-__thread      do not use TLS features even when supporting them
+   --with-cpu=CPU          select code for CPU variant
+@@ -1513,6 +1516,19 @@
+   sysheaders=''
+ fi;
+ 
++
++# Check whether --with-prng-device or --without-prng-device was given.
++if test "${with_prng_device+set}" = set; then
++  withval="$with_prng_device"
++  prng_device=$withval
++else
++  prng_device=/dev/urandom
++fi;
++cat >>confdefs.h <<_ACEOF
++#define PRNG_DEV "$prng_device"
++_ACEOF
++
++
+ # Check whether --enable-sanity-checks or --disable-sanity-checks was given.
+ if test "${enable_sanity_checks+set}" = set; then
+   enableval="$enable_sanity_checks"
+@@ -7797,6 +7813,31 @@
+ echo "${ECHO_T}$pic_default" >&6
+ 
+ 
++echo "$as_me:$LINENO: checking whether you have sysctl RANDOM_ERANDOM" >&5
++echo $ECHO_N "checking whether you have sysctl RANDOM_ERANDOM... $ECHO_C" >&6
++if test "${have_random_erandom+set}" = set; then
++  echo $ECHO_N "(cached) $ECHO_C" >&6
++else
++  have_random_erandom=no
++cat > conftest.c <<EOF
++#include <sys/sysctl.h>
++int main(void) { return RANDOM_ERANDOM; }
++EOF
++if eval "${CC-cc} -S conftest.c 2>&5 1>&5"; then
++  have_random_erandom=yes
++fi
++rm -f conftest.*
++fi
++echo "$as_me:$LINENO: result: $have_random_erandom" >&5
++echo "${ECHO_T}$have_random_erandom" >&6
++
++if test $have_random_erandom = yes; then
++  cat >>confdefs.h <<\_ACEOF
++#define HAVE_RANDOM_ERANDOM 1
++_ACEOF
++
++fi
++
+ 
+ 
+ 
+@@ -8552,6 +8593,7 @@
+ s,@static@,$static,;t t
+ s,@shared@,$shared,;t t
+ s,@pic_default@,$pic_default,;t t
++s,@have_random_erandom@,$have_random_erandom,;t t
+ s,@profile@,$profile,;t t
+ s,@omitfp@,$omitfp,;t t
+ s,@bounded@,$bounded,;t t
+diff -Naur glibc-2.5.orig/configure.in glibc-2.5/configure.in
+--- glibc-2.5.orig/configure.in        2006-07-10 21:45:29.000000000 +0000
++++ glibc-2.5/configure.in     2007-06-08 08:08:21.000000000 +0000
+@@ -100,6 +100,15 @@
+           [sysheaders=$withval],
+           [sysheaders=''])
+ 
++AC_ARG_WITH([prng-device],
++          AC_HELP_STRING([--with-prng-device=/path/to/prng],
++                         [specify the path to the system's
++                          pseudo-random device.
++                          @<:@default=/dev/urandom@:>@]),
++          [prng_device=$withval],
++          [prng_device=/dev/urandom])
++AC_DEFINE_UNQUOTED(PRNG_DEV, "$prng_device")
++
+ AC_ARG_ENABLE([sanity-checks],
+               AC_HELP_STRING([--disable-sanity-checks],
+                              [really do not use threads (should not be used 
except in special situations) @<:@default=yes@:>@]),
+@@ -2165,6 +2174,21 @@
+ rm -f conftest.*])
+ AC_SUBST(pic_default)
+ 
++AC_CACHE_CHECK([whether you have sysctl RANDOM_ERANDOM], have_random_erandom,
++[have_random_erandom=no
++cat > conftest.c <<EOF
++#include <sys/sysctl.h>
++int main(void) { return RANDOM_ERANDOM; }
++EOF
++if eval "${CC-cc} -S conftest.c 2>&AS_MESSAGE_LOG_FD 1>&AS_MESSAGE_LOG_FD"; 
then
++  have_random_erandom=yes
++fi
++rm -f conftest.*])
++AC_SUBST(have_random_erandom)
++if test $have_random_erandom = yes; then
++  AC_DEFINE(HAVE_RANDOM_ERANDOM)
++fi
++
+ AC_SUBST(profile)
+ AC_SUBST(omitfp)
+ AC_SUBST(bounded)
+diff -Naur glibc-2.5.orig/manual/arc4random.3 glibc-2.5/manual/arc4random.3
+--- glibc-2.5.orig/manual/arc4random.3 1970-01-01 00:00:00.000000000 +0000
++++ glibc-2.5/manual/arc4random.3      2007-06-08 08:08:21.000000000 +0000
+@@ -0,0 +1,110 @@
++.\" $OpenBSD: arc4random.3,v 1.19 2005/07/17 08:50:55 jaredy Exp $
++.\"
++.\" Copyright 1997 Niels Provos <[EMAIL PROTECTED]>
++.\" All rights reserved.
++.\"
++.\" Redistribution and use in source and binary forms, with or without
++.\" modification, are permitted provided that the following conditions
++.\" are met:
++.\" 1. Redistributions of source code must retain the above copyright
++.\"    notice, this list of conditions and the following disclaimer.
++.\" 2. Redistributions in binary form must reproduce the above copyright
++.\"    notice, this list of conditions and the following disclaimer in the
++.\"    documentation and/or other materials provided with the distribution.
++.\" 3. All advertising materials mentioning features or use of this software
++.\"    must display the following acknowledgement:
++.\"      This product includes software developed by Niels Provos.
++.\" 4. The name of the author may not be used to endorse or promote products
++.\"    derived from this software without specific prior written permission.
++.\"
++.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
++.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
++.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
++.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
++.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
++.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
++.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
++.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
++.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
++.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++.\"
++.\" Manual page, using -mandoc macros
++.\"
++.Dd April 15, 1997
++.Dt ARC4RANDOM 3
++.Os
++.Sh NAME
++.Nm arc4random ,
++.Nm arc4random_stir ,
++.Nm arc4random_addrandom
++.Nd arc4 random number generator
++.Sh SYNOPSIS
++.Fd #include <stdlib.h>
++.Ft u_int32_t
++.Fn arc4random "void"
++.Ft void
++.Fn arc4random_stir "void"
++.Ft void
++.Fn arc4random_addrandom "u_char *dat" "int datlen"
++.Sh DESCRIPTION
++The
++.Fn arc4random
++function provides a high quality 32-bit pseudo-random
++number very quickly.
++.Fn arc4random
++seeds itself on a regular basis from the kernel strong random number
++subsystem described in
++.Xr random 4 .
++On each call, an ARC4 generator is used to generate a new result.
++The
++.Fn arc4random
++function uses the ARC4 cipher key stream generator,
++which uses 8*8 8-bit S-Boxes.
++The S-Boxes can be in about (2**1700) states.
++.Pp
++.Fn arc4random
++fits into a middle ground not covered by other subsystems such as
++the strong, slow, and resource expensive random
++devices described in
++.Xr random 4
++versus the fast but poor quality interfaces described in
++.Xr rand 3 ,
++.Xr random 3 ,
++and
++.Xr drand48 3 .
++.Pp
++The
++.Fn arc4random_stir
++function reads data from a pseudo-random device, usually
++.Pa /dev/urandom,
++and uses it to permute the S-Boxes via
++.Fn arc4random_addrandom .
++.Pp
++There is no need to call
++.Fn arc4random_stir
++before using
++.Fn arc4random ,
++since
++.Fn arc4random
++automatically initializes itself.
++.Sh SEE ALSO
++.Xr rand 3 ,
++.Xr rand48 3 ,
++.Xr random 3
++.Sh HISTORY
++An algorithm called
++.Pa RC4
++was designed by RSA Data Security, Inc.
++It was considered a trade secret.
++Because it was a trade secret, it obviously could not be patented.
++A clone of this was posted anonymously to USENET and confirmed to
++be equivalent by several sources who had access to the original cipher.
++Because of the trade secret situation, RSA Data Security, Inc. can do
++nothing about the release of the ARC4 algorithm.
++Since
++.Pa RC4
++used to be a trade secret, the cipher is now referred to as
++.Pa ARC4 .
++.Pp
++These functions first appeared in
++.Ox 2.1 .
+diff -Naur glibc-2.5.orig/manual/mkstemps.3 glibc-2.5/manual/mkstemps.3
+--- glibc-2.5.orig/manual/mkstemps.3   1970-01-01 00:00:00.000000000 +0000
++++ glibc-2.5/manual/mkstemps.3        2007-06-08 08:08:21.000000000 +0000
+@@ -0,0 +1,86 @@
++.\"   $OpenBSD: mktemp.3,v 1.40 2007/05/10 22:46:36 espie Exp $
++.\"
++.\" Copyright (c) 1989, 1991, 1993
++.\"   The Regents of the University of California.  All rights reserved.
++.\"
++.\" Redistribution and use in source and binary forms, with or without
++.\" modification, are permitted provided that the following conditions
++.\" are met:
++.\" 1. Redistributions of source code must retain the above copyright
++.\"    notice, this list of conditions and the following disclaimer.
++.\" 2. Redistributions in binary form must reproduce the above copyright
++.\"    notice, this list of conditions and the following disclaimer in the
++.\"    documentation and/or other materials provided with the distribution.
++.\" 3. Neither the name of the University nor the names of its contributors
++.\"    may be used to endorse or promote products derived from this software
++.\"    without specific prior written permission.
++.\"
++.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
++.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
++.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
++.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
++.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
++.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
++.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
++.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
++.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
++.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
++.\" SUCH DAMAGE.
++.\"
++.Dd June 4, 1993
++.Dt MKTEMP 3
++.Os
++.Sh NAME
++.Nm mkstemps
++.Nd make temporary file name (unique)
++.Sh SYNOPSIS
++.Fd #include <stdlib.h>
++.Ft int
++.Fn mkstemps "char *template" "int suffixlen"
++.Sh DESCRIPTION
++.Pp
++The
++.Fn mkstemps
++function acts the same as
++.Fn mkstemp ,
++except it permits a suffix to exist in the template.
++The template should be of the form
++.Pa /tmp/tmpXXXXXXXXXXsuffix .
++.Fn mkstemps
++is told the length of the suffix string, i.e.,
++.Li strlen("suffix") .
++.Pp
++The
++.Fn mkstemps
++function return \-1 if no suitable file could be created.
++If any call fails, an error code is placed in the global variable
++.Va errno .
++The
++.Fn mkstemps
++function may also set
++.Va errno
++to any value specified by the
++.Xr open 2
++function or,
++.Bl -tag -width Er
++.It Bq Er EINVAL
++The suffix length is longer than the template length.
++.El
++.Sh SEE ALSO
++.Xr chmod 2 ,
++.Xr getpid 2 ,
++.Xr mkdir 2 ,
++.Xr open 2 ,
++.Xr stat 2 ,
++.Xr tempnam 3 ,
++.Xr tmpfile 3 ,
++.Xr tmpnam 3
++.Sh HISTORY
++The
++.Fn mkstemps
++function appeared in
++.Ox 2.3 .
++.Sh BUGS
++The
++.Fn mkstemps
++function are non-standard and should not be used if portability is required.
+diff -Naur glibc-2.5.orig/misc/Makefile glibc-2.5/misc/Makefile
+--- glibc-2.5.orig/misc/Makefile       2006-06-17 17:00:58.000000000 +0000
++++ glibc-2.5/misc/Makefile    2007-06-08 08:08:21.000000000 +0000
+@@ -44,7 +44,7 @@
+           acct chroot fsync sync fdatasync reboot \
+           gethostid sethostid \
+           revoke vhangup \
+-          swapon swapoff mktemp mkstemp mkstemp64 mkdtemp \
++          swapon swapoff mktemp mkstemp mkstemps mkstemp64 mkdtemp \
+           ualarm usleep \
+           gtty stty \
+           ptrace \
+diff -Naur glibc-2.5.orig/misc/Versions glibc-2.5/misc/Versions
+--- glibc-2.5.orig/misc/Versions       2005-11-11 18:58:19.000000000 +0000
++++ glibc-2.5/misc/Versions    2007-06-08 08:08:21.000000000 +0000
+@@ -54,7 +54,7 @@
+ 
+     # m*
+     madvise; mkstemp; mktemp; mlock; mlockall; mmap; mount; mprotect; msync;
+-    munlock; munlockall; munmap;
++    munlock; munlockall; munmap; mkstemps;
+ 
+     # o*
+     openlog;
+diff -Naur glibc-2.5.orig/misc/mkstemps.c glibc-2.5/misc/mkstemps.c
+--- glibc-2.5.orig/misc/mkstemps.c     1970-01-01 00:00:00.000000000 +0000
++++ glibc-2.5/misc/mkstemps.c  2007-06-08 08:08:21.000000000 +0000
+@@ -0,0 +1,116 @@
++/* Copyright (C) 1991, 1992, 1996, 1998, 2004 Free Software Foundation, Inc.
++   This file is derived from mkstemp.c from the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Library General Public License as
++   published by the Free Software Foundation; either version 2 of the
++   License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Library General Public License for more details.
++
++   You should have received a copy of the GNU Library General Public
++   License along with the GNU C Library; see the file COPYING.LIB.  If not,
++   write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth 
Floor,
++   Boston, MA 02110-1301, USA.  */
++
++/* From gcc-4.1.2 libiberty. This version uses arc4random(). - ashes */
++
++#include <sys/types.h>
++#include <stdlib.h>
++#include <string.h>
++#include <errno.h>
++#include <stdio.h>
++#include <fcntl.h>
++#include <unistd.h>
++#include <sys/time.h>
++
++/* We need to provide a type for gcc_uint64_t.  */
++#ifdef __GNUC__
++__extension__ typedef unsigned long long gcc_uint64_t;
++#else
++typedef unsigned long gcc_uint64_t;
++#endif
++
++#ifndef TMP_MAX
++#define TMP_MAX 16384
++#endif
++
++/*
++
[EMAIL PROTECTED] Replacement int mkstemps (char [EMAIL PROTECTED], int 
@var{suffix_len})
++
++Generate a unique temporary file name from @var{pattern}.
[EMAIL PROTECTED] has the form:
++
[EMAIL PROTECTED]
++   @var{path}/[EMAIL PROTECTED]
[EMAIL PROTECTED] example
++
[EMAIL PROTECTED] tells us how long @var{suffix} is (it can be zero
++length).  The last six characters of @var{pattern} before @var{suffix}
++must be @samp{XXXXXX}; they are replaced with a string that makes the
++filename unique.  Returns a file descriptor open on the file for
++reading and writing.
++
[EMAIL PROTECTED] deftypefn
++
++*/
++
++int
++mkstemps (char *pattern, int suffix_len)
++{
++  static const char letters[]
++    = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
++  static gcc_uint64_t value;
++  char *XXXXXX;
++  size_t len;
++  int count;
++
++  len = strlen (pattern);
++
++  if ((int) len < 6 + suffix_len
++      || strncmp (&pattern[len - 6 - suffix_len], "XXXXXX", 6))
++    {
++      return -1;
++    }
++
++  XXXXXX = &pattern[len - 6 - suffix_len];
++
++  value = arc4random();
++
++  for (count = 0; count < TMP_MAX; ++count)
++    {
++      gcc_uint64_t v = value;
++      int fd;
++
++      /* Fill in the random bits.  */
++      XXXXXX[0] = letters[v % 62];
++      v /= 62;
++      XXXXXX[1] = letters[v % 62];
++      v /= 62;
++      XXXXXX[2] = letters[v % 62];
++      v /= 62;
++      XXXXXX[3] = letters[v % 62];
++      v /= 62;
++      XXXXXX[4] = letters[v % 62];
++      v /= 62;
++      XXXXXX[5] = letters[v % 62];
++
++      fd = open (pattern, O_RDWR|O_CREAT|O_EXCL, 0600);
++      if (fd >= 0)
++      /* The file does not exist.  */
++      return fd;
++
++      /* This is a random value.  It is only necessary that the next
++       TMP_MAX values generated by adding 7777 to VALUE are different
++       with (module 2^32).  */
++      value += 7777;
++    }
++
++  /* We return the null string if we can't find a unique file name.  */
++  pattern[0] = '\0';
++  return -1;
++}
+diff -Naur glibc-2.5.orig/resolv/res_init.c glibc-2.5/resolv/res_init.c
+--- glibc-2.5.orig/resolv/res_init.c   2006-09-04 17:59:54.000000000 +0000
++++ glibc-2.5/resolv/res_init.c        2007-06-08 08:08:21.000000000 +0000
+@@ -537,7 +537,7 @@
+ 
+ u_int
+ res_randomid(void) {
+-      return 0xffff & __getpid();
++      return arc4random() & 0xffff;
+ }
+ #ifdef _LIBC
+ libc_hidden_def (__res_randomid)
+diff -Naur glibc-2.5.orig/resolv/res_mkquery.c glibc-2.5/resolv/res_mkquery.c
+--- glibc-2.5.orig/resolv/res_mkquery.c        2006-09-04 17:57:02.000000000 
+0000
++++ glibc-2.5/resolv/res_mkquery.c     2007-06-08 08:08:21.000000000 +0000
+@@ -120,23 +120,7 @@
+               return (-1);
+       memset(buf, 0, HFIXEDSZ);
+       hp = (HEADER *) buf;
+-      /* We randomize the IDs every time.  The old code just
+-         incremented by one after the initial randomization which
+-         still predictable if the application does multiple
+-         requests.  */
+-      int randombits;
+-      do
+-        {
+-#ifdef RANDOM_BITS
+-          RANDOM_BITS (randombits);
+-#else
+-          struct timeval tv;
+-          __gettimeofday (&tv, NULL);
+-          randombits = (tv.tv_sec << 8) ^ tv.tv_usec;
+-#endif
+-        }
+-      while ((randombits & 0xffff) == 0);
+-      statp->id = (statp->id + randombits) & 0xffff;
++      statp->id = arc4random() & 0xffff;
+       hp->id = statp->id;
+       hp->opcode = op;
+       hp->rd = (statp->options & RES_RECURSE) != 0;
+diff -Naur glibc-2.5.orig/scripts/data/localplt-i386-linux-gnu.data 
glibc-2.5/scripts/data/localplt-i386-linux-gnu.data
+--- glibc-2.5.orig/scripts/data/localplt-i386-linux-gnu.data   2006-01-11 
21:06:19.000000000 +0000
++++ glibc-2.5/scripts/data/localplt-i386-linux-gnu.data        2007-06-08 
08:08:21.000000000 +0000
+@@ -1,4 +1,6 @@
+ libc.so: _Unwind_Find_FDE
++libc.so: arc4random
++libc.so: arc4random_stir
+ libc.so: calloc
+ libc.so: free
+ libc.so: malloc
+diff -Naur glibc-2.5.orig/stdlib/Makefile glibc-2.5/stdlib/Makefile
+--- glibc-2.5.orig/stdlib/Makefile     2006-08-21 21:02:11.000000000 +0000
++++ glibc-2.5/stdlib/Makefile  2007-06-08 08:08:21.000000000 +0000
+@@ -30,7 +30,7 @@
+ 
+ routines      :=                                                            \
+       atof atoi atol atoll                                                  \
+-      abort                                                                 \
++      abort arc4random                                                      \
+       bsearch qsort msort                                                   \
+       getenv putenv setenv secure-getenv                                    \
+       exit on_exit atexit cxa_atexit cxa_finalize old_atexit                \
+diff -Naur glibc-2.5.orig/stdlib/Versions glibc-2.5/stdlib/Versions
+--- glibc-2.5.orig/stdlib/Versions     2004-05-03 21:25:53.000000000 +0000
++++ glibc-2.5/stdlib/Versions  2007-06-08 08:08:21.000000000 +0000
+@@ -11,6 +11,7 @@
+ 
+     # a*
+     a64l; abort; abs; atexit; atof; atoi; atol; atoll;
++    arc4random_stir; arc4random_addrandom; arc4random;
+ 
+     # b*
+     bsearch;
+diff -Naur glibc-2.5.orig/stdlib/arc4random.c glibc-2.5/stdlib/arc4random.c
+--- glibc-2.5.orig/stdlib/arc4random.c 1970-01-01 00:00:00.000000000 +0000
++++ glibc-2.5/stdlib/arc4random.c      2007-06-08 08:08:21.000000000 +0000
+@@ -0,0 +1,262 @@
++/*
++ * Copyright (c) 1996, David Mazieres <[EMAIL PROTECTED]>
++ *
++ * 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
++ * which is a trade secret).  The same algorithm is used as a stream
++ * cipher called "arcfour" in Tatu Ylonen's ssh package.
++ *
++ * Here the stream cipher has been modified always to include entropy
++ * when initializing the state.  That makes it impossible to
++ * regenerate the same random sequence twice, so this can't be used
++ * for encryption, but will generate good random numbers.
++ *
++ * RC4 is a registered trademark of RSA Laboratories.
++ */
++
++/* Modified by Robert Connolly for Glibc. April 23, 2007 */
++
++#include <fcntl.h>
++#include <stdlib.h>
++#include <unistd.h>
++#include <sys/types.h>
++#include <sys/time.h>
++
++#if defined(HAVE_RANDOM_ERANDOM)
++#include <sys/sysctl.h>
++#endif
++
++#ifndef PRNG_DEV
++#error "PRNG_DEV is not defined"
++#endif
++
++#ifdef __GNUC__
++#define inline __inline
++#else
++#define inline
++#endif
++
++struct arc4_stream {
++      u_int8_t i;
++      u_int8_t j;
++      u_int8_t s[256];
++};
++
++static int rs_initialized;
++static struct arc4_stream rs;
++static pid_t arc4_stir_pid;
++static int arc4_count;
++
++static inline u_int8_t arc4_getbyte(struct arc4_stream *);
++
++#if defined(TEST)
++u_int32_t arc4random(void);
++void arc4random_stir(void);
++void arc4random_addrandom(unsigned char *, int);
++#endif
++
++#if !defined(_LIBC)
++#define __getpid getpid
++#define __gettimeofday gettimeofday
++#define __open open
++#define __read read
++#define __close close
++#endif
++
++static inline void
++arc4_init(struct arc4_stream *as)
++{
++      int     n;
++
++      for (n = 0; n < 256; n++)
++              as->s[n] = n;
++      as->i = 0;
++      as->j = 0;
++}
++
++static inline void
++arc4_addrandom(struct arc4_stream *as, u_char *dat, int datlen)
++{
++      int     n;
++      u_int8_t si;
++
++      as->i--;
++      for (n = 0; n < 256; n++) {
++              as->i = (as->i + 1);
++              si = as->s[as->i];
++              as->j = (as->j + si + dat[n % datlen]);
++              as->s[as->i] = as->s[as->j];
++              as->s[as->j] = si;
++      }
++      as->j = as->i;
++}
++
++static void
++arc4_stir(struct arc4_stream *as)
++{
++      int     n, fd;
++      u_char  rnd[128];
++      struct timeval tv;
++
++#if defined(HAVE_RANDOM_ERANDOM)
++      /* This is the most efficient method (1 syscall). */
++      int     mib[3];
++      size_t  len;
++
++      mib[0] = CTL_KERN;
++      mib[1] = KERN_RANDOM;
++      mib[2] = RANDOM_ERANDOM;
++
++      len = sizeof(rnd);
++      if (__sysctl(mib, 3, rnd, &len, NULL, 0) == -1)
++      /* Sysctl failed? Try /dev/urandom (3 syscalls). */
++#endif
++        fd = __open(PRNG_DEV, O_RDONLY, 0);
++        if (fd != -1) {
++              __read(fd, rnd, sizeof(rnd));
++              __close(fd);
++        }
++        /* Did the pseudo-random device fail? Use gettimeofday(). */
++        else if (__gettimeofday(&tv, NULL) != (-1)) {
++
++              /* Initialize the first element so it's hopefully not '0',
++               * to help out the next loop. Tossing in some prime numbers
++               * probably can't hurt. */
++              rnd[0] = (tv.tv_sec % 10000) * 3 + tv.tv_usec * 7 + \
++                      (__getpid() % 1000) * 13;
++
++              for (n = 1; n < 127 ; n++) {
++
++              /* Take advantage of the stack space. Only initialize
++               * elements equal to '0'. This will make the rnd[]
++               * array much less vulnerable to timing attacks. Here
++               * we'll stir getpid() into the value of the previous
++               * elememnt. Approximately 1 in 128 elements will still
++               * become '0', so it will be a nightmare to try to
++               * predict this array. */
++
++                      if (rnd[n] == 0) {
++                              rnd[n] = ((rnd[n - 1] + n) ^ \
++                                      ((__getpid() % 1000) * 17));
++                      }
++              }
++        }
++        else {
++        /* gettimeofday() failed? Do the same thing as above, but only
++         * with getpid(). This is very bad, but arc4random() should never
++         * fail, so never give up. */
++
++              rnd[0] = (__getpid() % 1000) * 19;
++              for (n = 1; n < 127 ; n++) {
++                      if (rnd[n] == 0) {
++                              rnd[n] = ((rnd[n - 1] + n) ^ \
++                                      ((__getpid() % 1000) * 23));
++                      }
++              }
++        }
++        /* else??? Print warning here. */
++
++      arc4_stir_pid = __getpid();
++      arc4_addrandom(as, rnd, sizeof(rnd));
++
++      /*
++       * Discard early keystream, as per recommendations in:
++       * http://www.wisdom.weizmann.ac.il/~itsik/RC4/Papers/Rc4_ksa.ps
++       */
++      for (n = 0; n < 256; n++)
++              (void)arc4_getbyte(as);
++      arc4_count = 1600000;
++}
++
++static inline u_int8_t
++arc4_getbyte(struct arc4_stream *as)
++{
++      u_int8_t si, sj;
++
++      as->i = (as->i + 1);
++      si = as->s[as->i];
++      as->j = (as->j + si);
++      sj = as->s[as->j];
++      as->s[as->i] = sj;
++      as->s[as->j] = si;
++      return (as->s[(si + sj) & 0xff]);
++}
++
++/*
++ * __arc4_getbyte() is a libc private function intended for use
++ * with malloc(3) without calling getpid(2). It's good for
++ * fetching a specific amount of bytes.
++ */
++u_int8_t
++__arc4_getbyte(void)
++{
++      if (--arc4_count == 0 || !rs_initialized)
++              arc4random_stir();
++      return arc4_getbyte(&rs);
++}
++
++static inline u_int32_t
++arc4_getword(struct arc4_stream *as)
++{
++      u_int32_t val;
++      val = arc4_getbyte(as) << 24;
++      val |= arc4_getbyte(as) << 16;
++      val |= arc4_getbyte(as) << 8;
++      val |= arc4_getbyte(as);
++      return val;
++}
++
++void
++arc4random_stir(void)
++{
++      if (!rs_initialized) {
++              arc4_init(&rs);
++              rs_initialized = 1;
++      }
++      arc4_stir(&rs);
++}
++
++void
++arc4random_addrandom(u_char *dat, int datlen)
++{
++      if (!rs_initialized)
++              arc4random_stir();
++      arc4_addrandom(&rs, dat, datlen);
++}
++
++u_int32_t
++arc4random(void)
++{
++      arc4_count -= 4;
++      if (arc4_count <= 0 || !rs_initialized || arc4_stir_pid != __getpid())
++              arc4random_stir();
++      return arc4_getword(&rs);
++}
++
++#if defined(TEST)
++#include <stdio.h>
++int main(void)
++{
++      int random_number;
++      random_number = arc4random() % 65536;
++      printf("%d\n", random_number);
++      return 0;
++}
++#endif
+diff -Naur glibc-2.5.orig/stdlib/stdlib.h glibc-2.5/stdlib/stdlib.h
+--- glibc-2.5.orig/stdlib/stdlib.h     2006-01-14 12:08:29.000000000 +0000
++++ glibc-2.5/stdlib/stdlib.h  2007-06-08 08:08:21.000000000 +0000
+@@ -577,6 +577,12 @@
+ extern int lcong48_r (unsigned short int __param[7],
+                     struct drand48_data *__buffer)
+      __THROW __nonnull ((1, 2));
++
++/* Arcfour random number generator. */
++extern u_int32_t arc4random(void);
++extern void arc4random_stir(void);
++extern void arc4random_addrandom(unsigned char *, int);
++
+ # endif       /* Use misc.  */
+ #endif        /* Use SVID or X/Open.  */
+ 
+@@ -727,6 +733,7 @@
+    Returns TEMPLATE, or a null pointer if it cannot get a unique name.
+    The directory is created mode 700.  */
+ extern char *mkdtemp (char *__template) __THROW __nonnull ((1)) __wur;
++extern int mkstemps(char *, int) __THROW __wur;
+ #endif
+ 
+ 
+diff -Naur glibc-2.5.orig/string/strfry.c glibc-2.5/string/strfry.c
+--- glibc-2.5.orig/string/strfry.c     2002-03-11 23:47:45.000000000 +0000
++++ glibc-2.5/string/strfry.c  2007-06-08 08:28:04.000000000 +0000
+@@ -18,38 +18,9 @@
+ 
+ #include <string.h>
+ #include <stdlib.h>
+-#include <time.h>
+-#include <unistd.h>
+ 
+ char *
+ strfry (char *string)
+ {
+-  static int init;
+-  static struct random_data rdata;
+-  size_t len, i;
+-
+-  if (!init)
+-    {
+-      static char state[32];
+-      rdata.state = NULL;
+-      __initstate_r (time ((time_t *) NULL) ^ getpid (),
+-                   state, sizeof (state), &rdata);
+-      init = 1;
+-    }
+-
+-  len = strlen (string);
+-  for (i = 0; i < len; ++i)
+-    {
+-      int32_t j;
+-      char c;
+-
+-      __random_r (&rdata, &j);
+-      j %= len;
+-
+-      c = string[i];
+-      string[i] = string[j];
+-      string[j] = c;
+-    }
+-
+-  return string;
++  return (char)arc4random();
+ }
+diff -Naur glibc-2.5.orig/sunrpc/bindrsvprt.c glibc-2.5/sunrpc/bindrsvprt.c
+--- glibc-2.5.orig/sunrpc/bindrsvprt.c 2005-11-22 04:39:05.000000000 +0000
++++ glibc-2.5/sunrpc/bindrsvprt.c      2007-06-08 08:08:21.000000000 +0000
+@@ -67,7 +67,7 @@
+ 
+   if (port == 0)
+     {
+-      port = (__getpid () % NPORTS) + STARTPORT;
++      port = (arc4random() % NPORTS) + STARTPORT;
+     }
+ 
+   /* Initialize to make gcc happy.  */
+diff -Naur glibc-2.5.orig/sysdeps/posix/tempname.c 
glibc-2.5/sysdeps/posix/tempname.c
+--- glibc-2.5.orig/sysdeps/posix/tempname.c    2006-04-07 19:29:07.000000000 
+0000
++++ glibc-2.5/sysdeps/posix/tempname.c 2007-06-08 08:08:21.000000000 +0000
+@@ -52,10 +52,6 @@
+ # include <fcntl.h>
+ #endif
+ 
+-#if HAVE_SYS_TIME_H || _LIBC
+-# include <sys/time.h>
+-#endif
+-
+ #if HAVE_STDINT_H || _LIBC
+ # include <stdint.h>
+ #endif
+@@ -94,8 +90,6 @@
+ # define struct_stat64 struct stat64
+ #else
+ # define struct_stat64 struct stat
+-# define __getpid getpid
+-# define __gettimeofday gettimeofday
+ # define __mkdir mkdir
+ # define __open open
+ # define __open64 open
+@@ -107,25 +101,6 @@
+ # define __secure_getenv getenv
+ #endif
+ 
+-#ifdef _LIBC
+-# include <hp-timing.h>
+-# if HP_TIMING_AVAIL
+-#  define RANDOM_BITS(Var) \
+-  if (__builtin_expect (value == UINT64_C (0), 0))                          \
+-    {                                                                       \
+-      /* If this is the first time this function is used initialize         \
+-       the variable we accumulate the value in to some somewhat             \
+-       random value.  If we'd not do this programs at startup time          \
+-       might have a reduced set of possible names, at least on slow         \
+-       machines.  */                                                        \
+-      struct timeval tv;                                                    \
+-      __gettimeofday (&tv, NULL);                                           \
+-      value = ((uint64_t) tv.tv_usec << 16) ^ tv.tv_sec;                    \
+-    }                                                                       \
+-  HP_TIMING_NOW (Var)
+-# endif
+-#endif
+-
+ /* Use the widest available unsigned type if uint64_t is not
+    available.  The algorithm below extracts a number less than 62**6
+    (approximately 2**35.725) from uint64_t, so ancient hosts where
+@@ -229,10 +204,8 @@
+ {
+   int len;
+   char *XXXXXX;
+-  static uint64_t value;
+-  uint64_t random_time_bits;
+-  unsigned int count;
+   int fd = -1;
++  unsigned int i;
+   int save_errno = errno;
+   struct_stat64 st;
+ 
+@@ -262,39 +235,13 @@
+   /* This is where the Xs start.  */
+   XXXXXX = &tmpl[len - 6];
+ 
+-  /* Get some more or less random data.  */
+-#ifdef RANDOM_BITS
+-  RANDOM_BITS (random_time_bits);
+-#else
+-# if HAVE_GETTIMEOFDAY || _LIBC
+-  {
+-    struct timeval tv;
+-    __gettimeofday (&tv, NULL);
+-    random_time_bits = ((uint64_t) tv.tv_usec << 16) ^ tv.tv_sec;
+-  }
+-# else
+-  random_time_bits = time (NULL);
+-# endif
+-#endif
+-  value += random_time_bits ^ __getpid ();
+-
+-  for (count = 0; count < attempts; value += 7777, ++count)
++  for (i = 0; i < 6 ; ++i)
+     {
+-      uint64_t v = value;
+-
+-      /* Fill in the random bits.  */
+-      XXXXXX[0] = letters[v % 62];
+-      v /= 62;
+-      XXXXXX[1] = letters[v % 62];
+-      v /= 62;
+-      XXXXXX[2] = letters[v % 62];
+-      v /= 62;
+-      XXXXXX[3] = letters[v % 62];
+-      v /= 62;
+-      XXXXXX[4] = letters[v % 62];
+-      v /= 62;
+-      XXXXXX[5] = letters[v % 62];
++      XXXXXX[i] = letters[(arc4random() % 62)];
++    }
+ 
++  for (i = 0; i < attempts; ++i)
++    {
+       switch (kind)
+       {
+       case __GT_FILE:
+diff -Naur glibc-2.5.orig/sysdeps/unix/sysv/linux/dl-osinfo.h 
glibc-2.5/sysdeps/unix/sysv/linux/dl-osinfo.h
+--- glibc-2.5.orig/sysdeps/unix/sysv/linux/dl-osinfo.h 2006-08-01 
06:55:27.000000000 +0000
++++ glibc-2.5/sysdeps/unix/sysv/linux/dl-osinfo.h      2007-06-08 
08:08:21.000000000 +0000
+@@ -158,12 +158,15 @@
+       FATAL ("FATAL: cannot determine kernel version\n");                   \
+   } while (0)
+ 
++#ifndef PRNG_DEV
++#error "PRNG_DEV is not defined"
++#endif
+ static inline uintptr_t __attribute__ ((always_inline))
+ _dl_setup_stack_chk_guard (void)
+ {
+   uintptr_t ret;
+ #ifdef ENABLE_STACKGUARD_RANDOMIZE
+-  int fd = __open ("/dev/urandom", O_RDONLY);
++  int fd = __open (PRNG_DEV, O_RDONLY);
+   if (fd >= 0)
+     {
+       ssize_t reslen = __read (fd, &ret, sizeof (ret));

-- 
http://linuxfromscratch.org/mailman/listinfo/patches
FAQ: http://www.linuxfromscratch.org/faq/
Unsubscribe: See the above information page

Reply via email to