Avoid race in nscd
authorAndreas Jaeger <aj@suse.de>
Tue, 15 May 2012 18:35:53 +0000 (20:35 +0200)
committerAndreas Jaeger <aj@suse.de>
Tue, 15 May 2012 18:37:05 +0000 (20:37 +0200)
2012-05-15  Jeff Law  <law@redhat.com>
            Andreas Jaeger  <aj@suse.de>

        [BZ #13594]
        * nscd/nscd-client.h (__nscd_acquire_maplock): New function, split
        out from...
        * nscd/nscd_helper.c (__nscd_get_map_ref): ... here.
        * nscd/nscd-client.h: Add __nscd_acquire_maplock.
        * nscd/nscd_gethst_r.c (__nscd_get_nl_timestamp): Add locking to
        code changing __hst_map_handle.map.

ChangeLog
NEWS
nscd/nscd-client.h
nscd/nscd_gethst_r.c
nscd/nscd_helper.c

index 7576361c77ad3f8fcc32df2713e5872d8b06f3a6..b635a1905867fe40d99300ea649cf003dca2bd2a 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2012-05-15  Jeff Law  <law@redhat.com>
+           Andreas Jaeger  <aj@suse.de>
+
+       [BZ #13594]
+       * nscd/nscd-client.h (__nscd_acquire_maplock): New function, split
+       out from...
+       * nscd/nscd_helper.c (__nscd_get_map_ref): ... here.
+       * nscd/nscd-client.h: Add __nscd_acquire_maplock.
+       * nscd/nscd_gethst_r.c (__nscd_get_nl_timestamp): Add locking to
+       code changing __hst_map_handle.map.
+
 2012-05-15  Roland McGrath  <roland@hack.frob.com>
 
        * configure.in (sysnames): Look for Implies-before and Implies-after
diff --git a/NEWS b/NEWS
index 39def0430ee011b73d853464d1d6a82db75a9349..e8694718843777bee1f805220056f968ad8ad07a 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -18,16 +18,16 @@ Version 2.16
   11494, 11521, 11677, 11837, 11959, 12047, 12097, 12193, 12297, 12298,
   12301, 12340, 12354, 13058, 13361, 13525, 13526, 13527, 13528, 13529,
   13530, 13531, 13532, 13533, 13547, 13551, 13552, 13553, 13555, 13556,
-  13559, 13563, 13566, 13583, 13592, 13613, 13618, 13637, 13656, 13658,
-  13673, 13691, 13695, 13704, 13705, 13706, 13726, 13738, 13739, 13750,
-  13758, 13760, 13761, 13775, 13786, 13787, 13792, 13806, 13824, 13840,
-  13841, 13844, 13846, 13851, 13852, 13854, 13871, 13872, 13873, 13879,
-  13883, 13884, 13885, 13886, 13892, 13895, 13908, 13910, 13911, 13912,
-  13913, 13914, 13915, 13916, 13917, 13918, 13919, 13920, 13921, 13922,
-  13923, 13924, 13926, 13927, 13928, 13938, 13941, 13942, 13954, 13955,
-  13956, 13963, 13967, 13970, 13973, 13979, 13983, 13986, 14012, 14027,
-  14033, 14034, 14040, 14043, 14044, 14049, 14053, 14055, 14064, 14080,
-  14083, 14103, 14104
+  13559, 13563, 13566, 13583, 13592, 13594, 13613, 13618, 13637, 13656,
+  13658, 13673, 13691, 13695, 13704, 13705, 13706, 13726, 13738, 13739,
+  13750, 13758, 13760, 13761, 13775, 13786, 13787, 13792, 13806, 13824,
+  13840, 13841, 13844, 13846, 13851, 13852, 13854, 13871, 13872, 13873,
+  13879, 13883, 13884, 13885, 13886, 13892, 13895, 13908, 13910, 13911,
+  13912, 13913, 13914, 13915, 13916, 13917, 13918, 13919, 13920, 13921,
+  13922, 13923, 13924, 13926, 13927, 13928, 13938, 13941, 13942, 13954,
+  13955, 13956, 13963, 13967, 13970, 13973, 13979, 13983, 13986, 14012,
+  14027, 14033, 14034, 14040, 14043, 14044, 14049, 14053, 14055, 14064,
+  14080, 14083, 14103, 14104
 
 * ISO C11 support:
 
index e57a23c057f07bf46868a57478f03b33ced45dab..325368e73b317f6fafcd0576c7002d44a2dc6992 100644 (file)
@@ -1,5 +1,4 @@
-/* Copyright (c) 1998, 1999, 2000, 2003, 2004, 2005, 2006, 2007, 2009, 2011
-   Free Software Foundation, Inc.
+/* Copyright (c) 1998-2012 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Thorsten Kukuk <kukuk@suse.de>, 1998.
 
@@ -322,6 +321,24 @@ struct locked_map_ptr
 };
 #define libc_locked_map_ptr(class, name) class struct locked_map_ptr name
 
+/* Try acquiring lock for mapptr, returns true if it succeeds, false
+   if not.  */
+static inline bool __nscd_acquire_maplock (volatile struct locked_map_ptr *mapptr)
+{
+  int cnt = 0;
+  while (__builtin_expect (atomic_compare_and_exchange_val_acq (&mapptr->lock,
+                                                               1, 0) != 0, 0))
+    {
+      // XXX Best number of rounds?
+      if (__builtin_expect (++cnt > 5, 0))
+       return false;
+
+      atomic_delay ();
+    }
+
+  return true;
+}
+
 
 /* Open socket connection to nscd server.  */
 extern int __nscd_open_socket (const char *key, size_t keylen,
index c1661f86d4ce301cb95cb6333e17ebd780876d0b..d64ad2e7b6c9e58bddad2c4d86da5ab2d6055fef 100644 (file)
@@ -1,5 +1,4 @@
-/* Copyright (C) 1998-2005, 2006, 2007, 2008, 2009, 2011
-   Free Software Foundation, Inc.
+/* Copyright (C) 1998-2012 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
 
@@ -100,9 +99,18 @@ libc_freeres_fn (hst_map_free)
 uint32_t
 __nscd_get_nl_timestamp (void)
 {
+  uint32_t retval;
   if (__nss_not_use_nscd_hosts != 0)
     return 0;
 
+  /* __nscd_get_mapping can change hst_map_handle.mapped to NO_MAPPING.
+   However, __nscd_get_mapping assumes the prior value was not NO_MAPPING.
+   Thus we have to acquire the lock to prevent this thread from changing
+   hst_map_handle.mapped to NO_MAPPING while another thread is inside
+    __nscd_get_mapping.  */
+  if (!__nscd_acquire_maplock (&__hst_map_handle))
+    return 0;
+
   struct mapped_database *map = __hst_map_handle.mapped;
 
   if (map == NULL
@@ -112,9 +120,14 @@ __nscd_get_nl_timestamp (void)
     map = __nscd_get_mapping (GETFDHST, "hosts", &__hst_map_handle.mapped);
 
   if (map == NO_MAPPING)
-    return 0;
+    retval = 0;
+  else
+    retval = map->head->extra_data[NSCD_HST_IDX_CONF_TIMESTAMP];
+
+  /* Release the lock.  */
+  __hst_map_handle.lock = 0;
 
-  return map->head->extra_data[NSCD_HST_IDX_CONF_TIMESTAMP];
+  return retval;
 }
 
 
index 92558b6a51b583dbf650ae842ca85bff5acae1a3..96fb93db768703ccb51db20efde0c6e7c309dda9 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 1998-2007, 2008, 2009 Free Software Foundation, Inc.
+/* Copyright (C) 1998-2012 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
 
@@ -419,7 +419,6 @@ __nscd_get_mapping (request_type type, const char *key,
   return result;
 }
 
-
 struct mapped_database *
 __nscd_get_map_ref (request_type type, const char *name,
                    volatile struct locked_map_ptr *mapptr, int *gc_cyclep)
@@ -428,16 +427,8 @@ __nscd_get_map_ref (request_type type, const char *name,
   if (cur == NO_MAPPING)
     return cur;
 
-  int cnt = 0;
-  while (__builtin_expect (atomic_compare_and_exchange_val_acq (&mapptr->lock,
-                                                               1, 0) != 0, 0))
-    {
-      // XXX Best number of rounds?
-      if (__builtin_expect (++cnt > 5, 0))
-       return NO_MAPPING;
-
-      atomic_delay ();
-    }
+  if (!__nscd_acquire_maplock (mapptr))
+    return NO_MAPPING;
 
   cur = mapptr->mapped;