[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Commits] r21113 - in /fsf/trunk/libc: ./ crypt/ libio/ nptl/ nptl/sysdeps/unix/sysv/linux/ nptl/sysdeps/unix/sysv/linux/i386/i486/ np...



Author: eglibc
Date: Thu Oct 11 00:01:52 2012
New Revision: 21113

Log:
Import glibc-mainline for 2012-10-11

Added:
    fsf/trunk/libc/crypt/badsalttest.c
    fsf/trunk/libc/nptl/tst-cond25.c
    fsf/trunk/libc/sysdeps/generic/fips-private.h
    fsf/trunk/libc/sysdeps/unix/sysv/linux/fips-private.h
Modified:
    fsf/trunk/libc/ChangeLog
    fsf/trunk/libc/Makeconfig
    fsf/trunk/libc/NEWS
    fsf/trunk/libc/configure
    fsf/trunk/libc/configure.in
    fsf/trunk/libc/crypt/Makefile
    fsf/trunk/libc/crypt/crypt-entry.c
    fsf/trunk/libc/crypt/crypt-private.h
    fsf/trunk/libc/crypt/crypt_util.c
    fsf/trunk/libc/crypt/md5c-test.c
    fsf/trunk/libc/libio/libio.h
    fsf/trunk/libc/nptl/ChangeLog
    fsf/trunk/libc/nptl/Makefile
    fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S
    fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S
    fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/pthread-pi-defines.sym
    fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S
    fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S

Modified: fsf/trunk/libc/ChangeLog
==============================================================================
--- fsf/trunk/libc/ChangeLog (original)
+++ fsf/trunk/libc/ChangeLog Thu Oct 11 00:01:52 2012
@@ -1,3 +1,43 @@
+2012-10-10  Joseph Myers  <joseph@xxxxxxxxxxxxxxxx>
+
+	* configure.in: Run $CXX, not cc1plus, to locate C++ headers.
+	* configure: Regenerated.
+
+	* Makeconfig (+link-static-before-libc): Don't include
+	$(link-static-libc).
+
+	* libio/libio.h (_IO_pos_t): Remove.
+
+2012-10-10  Alexandre Oliva <aoliva@xxxxxxxxxx>
+
+	* NEWS: Add note about FIPS mode.  Wording suggested by Roland
+	McGrath.
+
+2012-10-10  Alexandre Oliva <aoliva@xxxxxxxxxx>
+
+	* crypt/crypt-entry.c: Include fips-private.h.
+	(__crypt_r, __crypt): Disable MD5 and DES if FIPS is enabled.
+	* crypt/md5c-test.c (main): Tolerate disabled MD5.
+	* sysdeps/unix/sysv/linux/fips-private.h: New file.
+	* sysdeps/generic/fips-private.h: New file, dummy fallback.
+
+2012-10-10  Alexandre Oliva <aoliva@xxxxxxxxxx>
+
+	* crypt/crypt-private.h: Include stdbool.h.
+	(_ufc_setup_salt_r): Return bool.
+	* crypt/crypt-entry.c: Include errno.h.
+	(__crypt_r): Return NULL with EINVAL for bad salt.
+	* crypt/crypt_util.c (bad_for_salt): New.
+	(_ufc_setup_salt_r): Check that salt is long enough and within
+	the specified alphabet.
+	* crypt/badsalttest.c: New file.
+	* crypt/Makefile (tests): Add it.
+	($(objpfx)badsalttest): New.
+
+2012-10-09  Maxim Kuvyrkov  <maxim@xxxxxxxxxxxxxxxx>
+
+	* NEWS: Add entry for BZ #14602.
+
 2012-10-09  Joseph Myers  <joseph@xxxxxxxxxxxxxxxx>
 
 	* math/gen-libm-test.pl (parse_args): Handle comparison macros as

Modified: fsf/trunk/libc/Makeconfig
==============================================================================
--- fsf/trunk/libc/Makeconfig (original)
+++ fsf/trunk/libc/Makeconfig Thu Oct 11 00:01:52 2012
@@ -434,7 +434,7 @@
 						     $(start-installed-name))\
 			   $(+preinit) $(link-extra-libs-static) \
 			   $(common-objpfx)libc% $(+postinit),$^) \
-	      $(link-extra-libs-static) $(link-libc-static)
+	      $(link-extra-libs-static)
 +link-static-after-libc = $(+postctorT) $(+postinit)
 +link-static = $(+link-static-before-libc) $(link-libc-static) \
 	       $(+link-static-after-libc)

Modified: fsf/trunk/libc/NEWS
==============================================================================
--- fsf/trunk/libc/NEWS (original)
+++ fsf/trunk/libc/NEWS Thu Oct 11 00:01:52 2012
@@ -15,8 +15,8 @@
   14195, 14237, 14251, 14252, 14283, 14298, 14303, 14307, 14328, 14331,
   14336, 14337, 14347, 14349, 14376, 14417, 14459, 14476, 14477, 14505,
   14510, 14516, 14518, 14519, 14530, 14532, 14538, 14543, 14544, 14545,
-  14557, 14562, 14568, 14576, 14579, 14583, 14587, 14621, 14638, 14645,
-  14648, 14660, 14661.
+  14557, 14562, 14568, 14576, 14579, 14583, 14587, 14602, 14621, 14638,
+  14645, 14648, 14652, 14660, 14661.
 
 * Support for STT_GNU_IFUNC symbols added for s390 and s390x.
   Optimized versions of memcpy, memset, and memcmp added for System z10 and
@@ -47,6 +47,12 @@
 * The ttyname and ttyname_r functions on Linux now fall back to searching for
   the tty file descriptor in /dev/pts or /dev if /proc is not available.  This
   allows creation of chroots without the procfs mounted on /proc.
+
+* The `crypt' function now fails if passed salt bytes that violate the
+  specification for those values.  On Linux, the `crypt' function will
+  consult /proc/sys/crypto/fips_enabled to determine if "FIPS mode" is
+  enabled, and fail on encrypted strings using the MD5 or DES algorithm
+  when the mode is enabled.
 
 
 Version 2.16

Modified: fsf/trunk/libc/configure
==============================================================================
--- fsf/trunk/libc/configure (original)
+++ fsf/trunk/libc/configure Thu Oct 11 00:01:52 2012
@@ -5342,10 +5342,9 @@
 -isystem `echo $sysheaders | sed 's/:/ -isystem /g'`"
   if test -n "$CXX"; then
     CXX_SYSINCLUDES=
-    cxxversion=`$CXX -dumpversion 2>&5` &&
     cxxmachine=`$CXX -dumpmachine 2>&5` &&
-    cxxplus=`$CXX -print-prog-name=cc1plus`
-    cxxheaders=`$cxxplus -v /dev/null 2>&1 | sed -n '/ \//{p;q;}' | sed 's/ //'`
+    cxxheaders=`$CXX -v -S -x c++ /dev/null -o /dev/null 2>&1 \
+	| sed -n -e '1,/#include/d' -e '/^ \//{p;q;}' | sed 's/ //'`
     test "x$cxxheaders" != x && test "x$i" != "x$cxxheaders" &&
     CXX_SYSINCLUDES="$CXX_SYSINCLUDES -isystem $cxxheaders \
 -isystem $cxxheaders/$cxxmachine -isystem $cxxheaders/backward"

Modified: fsf/trunk/libc/configure.in
==============================================================================
--- fsf/trunk/libc/configure.in (original)
+++ fsf/trunk/libc/configure.in Thu Oct 11 00:01:52 2012
@@ -973,10 +973,9 @@
 -isystem `echo $sysheaders | sed 's/:/ -isystem /g'`"
   if test -n "$CXX"; then
     CXX_SYSINCLUDES=
-    cxxversion=`$CXX -dumpversion 2>&AS_MESSAGE_LOG_FD` &&
     cxxmachine=`$CXX -dumpmachine 2>&AS_MESSAGE_LOG_FD` &&
-    cxxplus=`$CXX -print-prog-name=cc1plus`
-    cxxheaders=`$cxxplus -v /dev/null 2>&1 | sed -n '/ \//{p;q;}' | sed 's/ //'`
+    cxxheaders=`$CXX -v -S -x c++ /dev/null -o /dev/null 2>&1 \
+	| sed -n -e '1,/#include/d' -e '/^ \//{p;q;}' | sed 's/ //'`
     test "x$cxxheaders" != x && test "x$i" != "x$cxxheaders" &&
     CXX_SYSINCLUDES="$CXX_SYSINCLUDES -isystem $cxxheaders \
 -isystem $cxxheaders/$cxxmachine -isystem $cxxheaders/backward"

Modified: fsf/trunk/libc/crypt/Makefile
==============================================================================
--- fsf/trunk/libc/crypt/Makefile (original)
+++ fsf/trunk/libc/crypt/Makefile Thu Oct 11 00:01:52 2012
@@ -28,7 +28,7 @@
 libcrypt-routines := crypt-entry md5-crypt sha256-crypt sha512-crypt crypt \
 		     crypt_util
 
-tests := cert md5c-test sha256c-test sha512c-test
+tests := cert md5c-test sha256c-test sha512c-test badsalttest
 
 include ../Makeconfig
 

Added: fsf/trunk/libc/crypt/badsalttest.c
==============================================================================
--- fsf/trunk/libc/crypt/badsalttest.c (added)
+++ fsf/trunk/libc/crypt/badsalttest.c Thu Oct 11 00:01:52 2012
@@ -1,0 +1,86 @@
+/* Test program for bad DES salt detection in crypt.
+   Copyright (C) 2012 Free Software Foundation, Inc.
+   This file is part of 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 Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/mman.h>
+#include <crypt.h>
+
+static const char *tests[][2] =
+  {
+    { "no salt", "" },
+    { "single char", "/" },
+    { "first char bad", "!x" },
+    { "second char bad", "Z%" },
+    { "both chars bad", ":@" },
+    { "un$upported algorithm", "$2$" },
+    { "unsupported_algorithm", "_1" },
+    { "end of page", NULL }
+  };
+
+static int
+do_test (void)
+{
+  int result = 0;
+  struct crypt_data cd;
+  size_t n = sizeof (tests) / sizeof (*tests);
+  size_t pagesize = (size_t) sysconf (_SC_PAGESIZE);
+  char *page;
+
+  /* Check that crypt won't look at the second character if the first
+     one is invalid.  */
+  page = mmap (NULL, pagesize * 2, PROT_READ | PROT_WRITE,
+	       MAP_PRIVATE | MAP_ANON, -1, 0);
+  if (page == MAP_FAILED)
+    {
+      perror ("mmap");
+      n--;
+    }
+  else
+    {
+      if (mmap (page + pagesize, pagesize, 0,
+		MAP_PRIVATE | MAP_ANON | MAP_FIXED,
+		-1, 0) != page + pagesize)
+	perror ("mmap 2");
+      page[pagesize - 1] = '*';
+      tests[n - 1][1] = &page[pagesize - 1];
+    }
+
+  for (size_t i = 0; i < n; i++)
+    {
+      if (crypt (tests[i][0], tests[i][1]))
+	{
+	  result++;
+	  printf ("%s: crypt returned non-NULL with salt \"%s\"\n",
+		  tests[i][0], tests[i][1]);
+	}
+
+      if (crypt_r (tests[i][0], tests[i][1], &cd))
+	{
+	  result++;
+	  printf ("%s: crypt_r returned non-NULL with salt \"%s\"\n",
+		  tests[i][0], tests[i][1]);
+	}
+    }
+
+  return result;
+}
+
+#define TIMEOUT 5
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"

Modified: fsf/trunk/libc/crypt/crypt-entry.c
==============================================================================
--- fsf/trunk/libc/crypt/crypt-entry.c (original)
+++ fsf/trunk/libc/crypt/crypt-entry.c Thu Oct 11 00:01:52 2012
@@ -27,6 +27,8 @@
 #include <stdio.h>
 #endif
 #include <string.h>
+#include <errno.h>
+#include <fips-private.h>
 
 #ifndef STATIC
 #define STATIC static
@@ -91,8 +93,16 @@
 #ifdef _LIBC
   /* Try to find out whether we have to use MD5 encryption replacement.  */
   if (strncmp (md5_salt_prefix, salt, sizeof (md5_salt_prefix) - 1) == 0)
-    return __md5_crypt_r (key, salt, (char *) data,
-			  sizeof (struct crypt_data));
+    {
+      /* FIPS rules out MD5 password encryption.  */
+      if (fips_enabled_p ())
+	{
+	  __set_errno (EPERM);
+	  return NULL;
+	}
+      return __md5_crypt_r (key, salt, (char *) data,
+			    sizeof (struct crypt_data));
+    }
 
   /* Try to find out whether we have to use SHA256 encryption replacement.  */
   if (strncmp (sha256_salt_prefix, salt, sizeof (sha256_salt_prefix) - 1) == 0)
@@ -108,7 +118,18 @@
   /*
    * Hack DES tables according to salt
    */
-  _ufc_setup_salt_r (salt, data);
+  if (!_ufc_setup_salt_r (salt, data))
+    {
+      __set_errno (EINVAL);
+      return NULL;
+    }
+
+  /* FIPS rules out DES password encryption.  */
+  if (fips_enabled_p ())
+    {
+      __set_errno (EPERM);
+      return NULL;
+    }
 
   /*
    * Setup key schedule
@@ -143,7 +164,9 @@
 {
 #ifdef _LIBC
   /* Try to find out whether we have to use MD5 encryption replacement.  */
-  if (strncmp (md5_salt_prefix, salt, sizeof (md5_salt_prefix) - 1) == 0)
+  if (strncmp (md5_salt_prefix, salt, sizeof (md5_salt_prefix) - 1) == 0
+      /* Let __crypt_r deal with the error code if FIPS is enabled.  */
+      && !fips_enabled_p ())
     return __md5_crypt (key, salt);
 
   /* Try to find out whether we have to use SHA256 encryption replacement.  */

Modified: fsf/trunk/libc/crypt/crypt-private.h
==============================================================================
--- fsf/trunk/libc/crypt/crypt-private.h (original)
+++ fsf/trunk/libc/crypt/crypt-private.h Thu Oct 11 00:01:52 2012
@@ -26,6 +26,7 @@
 #define CRYPT_PRIVATE_H	1
 
 #include <features.h>
+#include <stdbool.h>
 
 /* crypt.c */
 extern void _ufc_doit_r (ufc_long itr, struct crypt_data * __restrict __data,
@@ -36,7 +37,7 @@
 extern void __init_des_r (struct crypt_data * __restrict __data);
 extern void __init_des (void);
 
-extern void _ufc_setup_salt_r (const char *s,
+extern bool _ufc_setup_salt_r (const char *s,
 			       struct crypt_data * __restrict __data);
 extern void _ufc_mk_keytab_r (const char *key,
 			      struct crypt_data * __restrict __data);

Modified: fsf/trunk/libc/crypt/crypt_util.c
==============================================================================
--- fsf/trunk/libc/crypt/crypt_util.c (original)
+++ fsf/trunk/libc/crypt/crypt_util.c Thu Oct 11 00:01:52 2012
@@ -596,23 +596,55 @@
 #endif
 
 /*
+ * Return false iff C is in the specified alphabet for crypt salt.
+ */
+
+static bool
+bad_for_salt (char c)
+{
+  switch (c)
+    {
+    case '0' ... '9':
+    case 'A' ... 'Z':
+    case 'a' ... 'z':
+    case '.': case '/':
+      return false;
+
+    default:
+      return true;
+    }
+}
+
+/*
  * Setup the unit for a new salt
  * Hopefully we'll not see a new salt in each crypt call.
- */
-
-void
+ * Return false if an unexpected character was found in s[0] or s[1].
+ */
+
+bool
 _ufc_setup_salt_r(s, __data)
      const char *s;
      struct crypt_data * __restrict __data;
 {
   ufc_long i, j, saltbits;
+  char s0, s1;
 
   if(__data->initialized == 0)
     __init_des_r(__data);
 
-  if(s[0] == __data->current_salt[0] && s[1] == __data->current_salt[1])
-    return;
-  __data->current_salt[0] = s[0]; __data->current_salt[1] = s[1];
+  s0 = s[0];
+  if(bad_for_salt (s0))
+    return false;
+
+  s1 = s[1];
+  if(bad_for_salt (s1))
+    return false;
+
+  if(s0 == __data->current_salt[0] && s1 == __data->current_salt[1])
+    return true;
+
+  __data->current_salt[0] = s0;
+  __data->current_salt[1] = s1;
 
   /*
    * This is the only crypt change to DES:
@@ -646,6 +678,8 @@
   shuffle_sb((LONGG)__data->sb3, __data->current_saltbits ^ saltbits);
 
   __data->current_saltbits = saltbits;
+
+  return true;
 }
 
 void

Modified: fsf/trunk/libc/crypt/md5c-test.c
==============================================================================
--- fsf/trunk/libc/crypt/md5c-test.c (original)
+++ fsf/trunk/libc/crypt/md5c-test.c Thu Oct 11 00:01:52 2012
@@ -9,7 +9,10 @@
   int result = 0;
 
   cp = crypt ("Hello world!", salt);
-  result |= strcmp ("$1$saltstri$YMyguxXMBpd2TEZ.vS/3q1", cp);
+
+  /* MD5 is disabled in FIPS mode.  */
+  if (cp)
+    result |= strcmp ("$1$saltstri$YMyguxXMBpd2TEZ.vS/3q1", cp);
 
   return result;
 }

Modified: fsf/trunk/libc/libio/libio.h
==============================================================================
--- fsf/trunk/libc/libio/libio.h (original)
+++ fsf/trunk/libc/libio/libio.h Thu Oct 11 00:01:52 2012
@@ -31,7 +31,6 @@
 
 #include <_G_config.h>
 /* ALL of these should be defined in _G_config.h */
-#define _IO_pos_t _G_fpos_t /* obsolete */
 #define _IO_fpos_t _G_fpos_t
 #define _IO_fpos64_t _G_fpos64_t
 #define _IO_size_t size_t

Modified: fsf/trunk/libc/nptl/ChangeLog
==============================================================================
--- fsf/trunk/libc/nptl/ChangeLog (original)
+++ fsf/trunk/libc/nptl/ChangeLog Thu Oct 11 00:01:52 2012
@@ -1,3 +1,21 @@
+2012-10-10  Siddhesh Poyarekar  <siddhesh@xxxxxxxxxx>
+
+	[BZ #14652]
+	* Makefile (tests): New test case tst-cond25.
+	(LDFLAGS-tst-cond25): Link tst-cond25 against librt.
+	* sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S
+	(__condvar_tw_cleanup): Lock mutex only if we don't already
+	own it.
+	* sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S
+	(__condvar_w_cleanup): Likewise.
+	* sysdeps/unix/sysv/linux/pthread-pi-defines.sym: Add TID_MASK.
+	* sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S
+	(__condvar_cleanup2): Lock mutex only if we don't already
+	own it.
+	* sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S
+	(__condvar_cleanup1): Likewise.
+	* tst-cond25.c: New test case.
+
 2012-10-09  Roland McGrath  <roland@xxxxxxxxxxxxx>
 
 	* sysdeps/pthread/configure: Regenerated.

Modified: fsf/trunk/libc/nptl/Makefile
==============================================================================
--- fsf/trunk/libc/nptl/Makefile (original)
+++ fsf/trunk/libc/nptl/Makefile Thu Oct 11 00:01:52 2012
@@ -206,7 +206,7 @@
 	tst-cond1 tst-cond2 tst-cond3 tst-cond4 tst-cond5 tst-cond6 tst-cond7 \
 	tst-cond8 tst-cond9 tst-cond10 tst-cond11 tst-cond12 tst-cond13 \
 	tst-cond14 tst-cond15 tst-cond16 tst-cond17 tst-cond18 tst-cond19 \
-	tst-cond20 tst-cond21 tst-cond22 tst-cond23 tst-cond24 \
+	tst-cond20 tst-cond21 tst-cond22 tst-cond23 tst-cond24 tst-cond25 \
 	tst-cond-except \
 	tst-robust1 tst-robust2 tst-robust3 tst-robust4 tst-robust5 \
 	tst-robust6 tst-robust7 tst-robust8 tst-robust9 \
@@ -276,6 +276,7 @@
 LDFLAGS-pthread.so = -Wl,--enable-new-dtags,-z,nodelete,-z,initfirst
 
 LDFLAGS-tst-cond24 = -lrt
+LDFLAGS-tst-cond25 = -lrt
 
 include ../Makeconfig
 

Modified: fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S
==============================================================================
--- fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S (original)
+++ fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S Thu Oct 11 00:01:52 2012
@@ -649,10 +649,24 @@
 	movl	$0x7fffffff, %edx
 	ENTER_KERNEL
 
+	/* Lock the mutex only if we don't own it already.  This only happens
+	   in case of PI mutexes, if we got cancelled after a successful
+	   return of the futex syscall and before disabling async
+	   cancellation.  */
 5:	movl	24+FRAME_SIZE(%esp), %eax
-	call	__pthread_mutex_cond_lock
-
-	movl	%esi, (%esp)
+	movl	MUTEX_KIND(%eax), %ebx
+	andl	$(ROBUST_BIT|PI_BIT), %ebx
+	cmpl	$PI_BIT, %ebx
+	jne	8f
+
+	movl	(%eax), %ebx
+	andl	$TID_MASK, %ebx
+	cmpl	%ebx, %gs:TID
+	je	9f
+
+8:	call	__pthread_mutex_cond_lock
+
+9:	movl	%esi, (%esp)
 .LcallUR:
 	call	_Unwind_Resume
 	hlt

Modified: fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S
==============================================================================
--- fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S (original)
+++ fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S Thu Oct 11 00:01:52 2012
@@ -566,10 +566,24 @@
 	movl	$0x7fffffff, %edx
 	ENTER_KERNEL
 
+	/* Lock the mutex only if we don't own it already.  This only happens
+	   in case of PI mutexes, if we got cancelled after a successful
+	   return of the futex syscall and before disabling async
+	   cancellation.  */
 5:	movl	24+FRAME_SIZE(%esp), %eax
-	call	__pthread_mutex_cond_lock
-
-	movl	%esi, (%esp)
+	movl	MUTEX_KIND(%eax), %ebx
+	andl	$(ROBUST_BIT|PI_BIT), %ebx
+	cmpl	$PI_BIT, %ebx
+	jne	8f
+
+	movl	(%eax), %ebx
+	andl	$TID_MASK, %ebx
+	cmpl	%ebx, %gs:TID
+	je	9f
+
+8:	call	__pthread_mutex_cond_lock
+
+9:	movl	%esi, (%esp)
 .LcallUR:
 	call	_Unwind_Resume
 	hlt

Modified: fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/pthread-pi-defines.sym
==============================================================================
--- fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/pthread-pi-defines.sym (original)
+++ fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/pthread-pi-defines.sym Thu Oct 11 00:01:52 2012
@@ -6,3 +6,4 @@
 ROBUST_BIT	PTHREAD_MUTEX_ROBUST_NORMAL_NP
 PI_BIT		PTHREAD_MUTEX_PRIO_INHERIT_NP
 PS_BIT		PTHREAD_MUTEX_PSHARED_BIT
+TID_MASK	FUTEX_TID_MASK

Modified: fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S
==============================================================================
--- fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S (original)
+++ fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S Thu Oct 11 00:01:52 2012
@@ -771,10 +771,24 @@
 	movl	$SYS_futex, %eax
 	syscall
 
+	/* Lock the mutex only if we don't own it already.  This only happens
+	   in case of PI mutexes, if we got cancelled after a successful
+	   return of the futex syscall and before disabling async
+	   cancellation.  */
 5:	movq	16(%rsp), %rdi
-	callq	__pthread_mutex_cond_lock
-
-	movq	24(%rsp), %rdi
+	movl	MUTEX_KIND(%rdi), %eax
+	andl	$(ROBUST_BIT|PI_BIT), %eax
+	cmpl	$PI_BIT, %eax
+	jne	7f
+
+	movl	(%rdi), %eax
+	andl	$TID_MASK, %eax
+	cmpl	%eax, %fs:TID
+	je	8f
+
+7:	callq	__pthread_mutex_cond_lock
+
+8:	movq	24(%rsp), %rdi
 	movq	FRAME_SIZE(%rsp), %r15
 	movq	FRAME_SIZE+8(%rsp), %r14
 	movq	FRAME_SIZE+16(%rsp), %r13

Modified: fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S
==============================================================================
--- fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S (original)
+++ fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S Thu Oct 11 00:01:52 2012
@@ -495,10 +495,24 @@
 	movl	$SYS_futex, %eax
 	syscall
 
+	/* Lock the mutex only if we don't own it already.  This only happens
+	   in case of PI mutexes, if we got cancelled after a successful
+	   return of the futex syscall and before disabling async
+	   cancellation.  */
 5:	movq	16(%rsp), %rdi
-	callq	__pthread_mutex_cond_lock
-
-	movq	24(%rsp), %rdi
+	movl	MUTEX_KIND(%rdi), %eax
+	andl	$(ROBUST_BIT|PI_BIT), %eax
+	cmpl	$PI_BIT, %eax
+	jne	7f
+
+	movl	(%rdi), %eax
+	andl	$TID_MASK, %eax
+	cmpl	%eax, %fs:TID
+	je	8f
+
+7:	callq	__pthread_mutex_cond_lock
+
+8:	movq	24(%rsp), %rdi
 .LcallUR:
 	call	_Unwind_Resume@PLT
 	hlt

Added: fsf/trunk/libc/nptl/tst-cond25.c
==============================================================================
--- fsf/trunk/libc/nptl/tst-cond25.c (added)
+++ fsf/trunk/libc/nptl/tst-cond25.c Thu Oct 11 00:01:52 2012
@@ -1,0 +1,282 @@
+/* Verify that condition variables synchronized by PI mutexes don't hang on
+   on cancellation.
+   Copyright (C) 2012 Free Software Foundation, Inc.
+   This file is part of 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 Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <pthread.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/syscall.h>
+#include <unistd.h>
+#include <sys/time.h>
+#include <time.h>
+
+#define NUM 5
+#define ITERS 10000
+#define COUNT 100
+
+typedef void *(*thr_func) (void *);
+
+pthread_mutex_t mutex;
+pthread_cond_t cond;
+
+void cleanup (void *u)
+{
+  /* pthread_cond_wait should always return with the mutex locked.  */
+  if (pthread_mutex_unlock (&mutex))
+    abort ();
+}
+
+void *
+signaller (void *u)
+{
+  int i, ret = 0;
+  void *tret = NULL;
+
+  for (i = 0; i < ITERS; i++)
+    {
+      if ((ret = pthread_mutex_lock (&mutex)) != 0)
+        {
+	  tret = (void *)1;
+	  printf ("signaller:mutex_lock failed: %s\n", strerror (ret));
+	  goto out;
+	}
+      if ((ret = pthread_cond_signal (&cond)) != 0)
+        {
+	  tret = (void *)1;
+	  printf ("signaller:signal failed: %s\n", strerror (ret));
+	  goto unlock_out;
+	}
+      if ((ret = pthread_mutex_unlock (&mutex)) != 0)
+        {
+	  tret = (void *)1;
+	  printf ("signaller:mutex_unlock failed: %s\n", strerror (ret));
+	  goto out;
+	}
+      pthread_testcancel ();
+    }
+
+out:
+  return tret;
+
+unlock_out:
+  if ((ret = pthread_mutex_unlock (&mutex)) != 0)
+    printf ("signaller:mutex_unlock[2] failed: %s\n", strerror (ret));
+  goto out;
+}
+
+void *
+waiter (void *u)
+{
+  int i, ret = 0;
+  void *tret = NULL;
+  int seq = (int)u;
+
+  for (i = 0; i < ITERS / NUM; i++)
+    {
+      if ((ret = pthread_mutex_lock (&mutex)) != 0)
+        {
+	  tret = (void *)1;
+	  printf ("waiter[%u]:mutex_lock failed: %s\n", seq, strerror (ret));
+	  goto out;
+	}
+      pthread_cleanup_push (cleanup, NULL);
+
+      if ((ret = pthread_cond_wait (&cond, &mutex)) != 0)
+        {
+	  tret = (void *)1;
+	  printf ("waiter[%u]:wait failed: %s\n", seq, strerror (ret));
+	  goto unlock_out;
+	}
+
+      if ((ret = pthread_mutex_unlock (&mutex)) != 0)
+        {
+	  tret = (void *)1;
+	  printf ("waiter[%u]:mutex_unlock failed: %s\n", seq, strerror (ret));
+	  goto out;
+	}
+      pthread_cleanup_pop (0);
+    }
+
+out:
+  puts ("waiter tests done");
+  return tret;
+
+unlock_out:
+  if ((ret = pthread_mutex_unlock (&mutex)) != 0)
+    printf ("waiter:mutex_unlock[2] failed: %s\n", strerror (ret));
+  goto out;
+}
+
+void *
+timed_waiter (void *u)
+{
+  int i, ret;
+  void *tret = NULL;
+  int seq = (int)u;
+
+  for (i = 0; i < ITERS / NUM; i++)
+    {
+      struct timespec ts;
+
+      if ((ret = clock_gettime(CLOCK_REALTIME, &ts)) != 0)
+        {
+	  tret = (void *)1;
+	  printf ("%u:clock_gettime failed: %s\n", seq, strerror (errno));
+	  goto out;
+	}
+      ts.tv_sec += 20;
+
+      if ((ret = pthread_mutex_lock (&mutex)) != 0)
+        {
+	  tret = (void *)1;
+	  printf ("waiter[%u]:mutex_lock failed: %s\n", seq, strerror (ret));
+	  goto out;
+	}
+      pthread_cleanup_push (cleanup, NULL);
+
+      /* We should not time out either.  */
+      if ((ret = pthread_cond_timedwait (&cond, &mutex, &ts)) != 0)
+        {
+	  tret = (void *)1;
+	  printf ("waiter[%u]:timedwait failed: %s\n", seq, strerror (ret));
+	  goto unlock_out;
+	}
+      if ((ret = pthread_mutex_unlock (&mutex)) != 0)
+        {
+	  tret = (void *)1;
+	  printf ("waiter[%u]:mutex_unlock failed: %s\n", seq, strerror (ret));
+	  goto out;
+	}
+      pthread_cleanup_pop (0);
+    }
+
+out:
+  puts ("timed_waiter tests done");
+  return tret;
+
+unlock_out:
+  if ((ret = pthread_mutex_unlock (&mutex)) != 0)
+    printf ("waiter[%u]:mutex_unlock[2] failed: %s\n", seq, strerror (ret));
+  goto out;
+}
+
+int
+do_test_wait (thr_func f)
+{
+  pthread_t w[NUM];
+  pthread_t s;
+  pthread_mutexattr_t attr;
+  int i, j, ret = 0;
+  void *thr_ret;
+
+  for (i = 0; i < COUNT; i++)
+    {
+      if ((ret = pthread_mutexattr_init (&attr)) != 0)
+        {
+	  printf ("mutexattr_init failed: %s\n", strerror (ret));
+	  goto out;
+	}
+
+      if ((ret = pthread_mutexattr_setprotocol (&attr, PTHREAD_PRIO_INHERIT)) != 0)
+        {
+	  printf ("mutexattr_setprotocol failed: %s\n", strerror (ret));
+	  goto out;
+	}
+
+      if ((ret = pthread_cond_init (&cond, NULL)) != 0)
+        {
+	  printf ("cond_init failed: %s\n", strerror (ret));
+	  goto out;
+	}
+
+      if ((ret = pthread_mutex_init (&mutex, &attr)) != 0)
+        {
+	  printf ("mutex_init failed: %s\n", strerror (ret));
+	  goto out;
+	}
+
+      for (j = 0; j < NUM; j++)
+        if ((ret = pthread_create (&w[j], NULL, f, (void *)j)) != 0)
+	  {
+	    printf ("waiter[%d]: create failed: %s\n", j, strerror (ret));
+	    goto out;
+	  }
+
+      if ((ret = pthread_create (&s, NULL, signaller, NULL)) != 0)
+        {
+	  printf ("signaller: create failed: %s\n", strerror (ret));
+	  goto out;
+	}
+
+      for (j = 0; j < NUM; j++)
+        {
+          if ((ret = pthread_cancel (w[j])) != 0)
+	    {
+	      printf ("waiter[%d]: cancel failed: %s\n", j, strerror (ret));
+	      goto out;
+	    }
+
+          if ((ret = pthread_join (w[j], &thr_ret)) != 0)
+	    {
+	      printf ("waiter[%d]: join failed: %s\n", j, strerror (ret));
+	      goto out;
+	    }
+
+          if (thr_ret != NULL && thr_ret != PTHREAD_CANCELED)
+	    {
+	      ret = 1;
+	      goto out;
+	    }
+        }
+
+      /* The signalling thread could have ended before it was cancelled.  */
+      pthread_cancel (s);
+
+      if ((ret = pthread_join (s, &thr_ret)) != 0)
+        {
+	  printf ("signaller: join failed: %s\n", strerror (ret));
+	  goto out;
+	}
+
+      if (thr_ret != NULL && thr_ret != PTHREAD_CANCELED)
+        {
+          ret = 1;
+          goto out;
+        }
+    }
+
+out:
+  return ret;
+}
+
+int
+do_test (int argc, char **argv)
+{
+  int ret = do_test_wait (waiter);
+
+  if (ret)
+    return ret;
+
+  return do_test_wait (timed_waiter);
+}
+
+#define TIMEOUT 5
+#include "../test-skeleton.c"

Added: fsf/trunk/libc/sysdeps/generic/fips-private.h
==============================================================================
--- fsf/trunk/libc/sysdeps/generic/fips-private.h (added)
+++ fsf/trunk/libc/sysdeps/generic/fips-private.h Thu Oct 11 00:01:52 2012
@@ -1,0 +1,36 @@
+/* Dummy implementation of FIPS compliance status test.
+   Copyright (C) 2012 Free Software Foundation, Inc.
+   This file is part of 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 Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _FIPS_PRIVATE_H
+#define _FIPS_PRIVATE_H
+
+#include <stdbool.h>
+
+/* Return true if compliance with the FIPS security standards is
+   enabled.
+
+   This is only relevant within crypt, to tell whether MD5 and DES
+   algorithms should be rejected.  */
+
+static inline bool
+fips_enabled_p (void)
+{
+  return false;
+}
+
+#endif /* _FIPS_PRIVATE_H */

Added: fsf/trunk/libc/sysdeps/unix/sysv/linux/fips-private.h
==============================================================================
--- fsf/trunk/libc/sysdeps/unix/sysv/linux/fips-private.h (added)
+++ fsf/trunk/libc/sysdeps/unix/sysv/linux/fips-private.h Thu Oct 11 00:01:52 2012
@@ -1,0 +1,74 @@
+/* FIPS compliance status test for GNU/Linux systems.
+   Copyright (C) 2012 Free Software Foundation, Inc.
+   This file is part of 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 Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _FIPS_PRIVATE_H
+#define _FIPS_PRIVATE_H
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <not-cancel.h>
+#include <stdbool.h>
+
+/* Return true if FIPS mode is enabled.  See
+   sysdeps/generic/fips-private.h for more information.  */
+
+static inline bool
+fips_enabled_p (void)
+{
+  static enum
+  {
+    FIPS_UNTESTED = 0,
+    FIPS_ENABLED = 1,
+    FIPS_DISABLED = -1,
+    FIPS_TEST_FAILED = -2
+  } checked;
+
+  if (checked == FIPS_UNTESTED)
+    {
+      int fd = open_not_cancel_2 ("/proc/sys/crypto/fips_enabled", O_RDONLY);
+
+      if (fd != -1)
+	{
+	  /* This is more than enough, the file contains a single integer.  */
+	  char buf[32];
+	  ssize_t n;
+	  n = TEMP_FAILURE_RETRY (read_not_cancel (fd, buf, sizeof (buf) - 1));
+	  close_not_cancel_no_status (fd);
+
+	  if (n > 0)
+	    {
+	      /* Terminate the string.  */
+	      buf[n] = '\0';
+
+	      char *endp;
+	      long int res = strtol (buf, &endp, 10);
+	      if (endp != buf && (*endp == '\0' || *endp == '\n'))
+		checked = (res > 0) ? FIPS_ENABLED : FIPS_DISABLED;
+	    }
+	}
+
+      if (checked == FIPS_UNTESTED)
+	checked = FIPS_TEST_FAILED;
+    }
+
+  return checked == FIPS_ENABLED;
+}
+
+#endif /* _FIPS_PRIVATE_H */

_______________________________________________
Commits mailing list
Commits@xxxxxxxxxx
http://eglibc.org/cgi-bin/mailman/listinfo/commits