[PATCH] Fix nss_db crash when db contains exactly one entry

Siddhesh Poyarekar siddhesh@redhat.com
Tue Nov 27 15:43:00 GMT 2012


Hi,

It looks like the hashtable size calculation in nssdb is buggy, since
it returns a hashtable of size 1 when a database has just one entry.
This is easy to reproduce with the following:

* Have exactly one user associated with another group, i.e. exactly
  one line of the type:

mail:x:12:postfix

* Ensure that db is queried first for groups:

cat /etc/nsswitch.conf:

...
passwd:     files
shadow:     files
group:      db files
...

* Make the nssdb:

cd /var/db && make

* Start nscd -d and watch it crash

The crash is inside nssdb and hence with the above configuration,
programs throughout the system will eventually start crashing (sshd,
systemd/init, etc.).  Attached patch ensures that makedb sets the
hashtable size to a prime greater than 3, which is sufficient for the
way the hashtable is populated.

I've verified that this fixes the crash on an F18 test system
(2.16.x).  OK to check-in?

Siddhesh

ChangeLog:

	* nss/makedb.c (is_prime): Ensure that CANDIDATE is greater
        than 3.
-------------- next part --------------
diff --git a/nss/makedb.c b/nss/makedb.c
index 8d7d027..fdcf4c6 100644
--- a/nss/makedb.c
+++ b/nss/makedb.c
@@ -591,10 +591,12 @@ copy_valstr (const void *nodep, const VISIT which, const int depth)
 }
 
 
+/* Check if a number is prime.  We check only odd numbers greater than 10.
+   Enter even numbers and watch the function fail in mysterious ways.  Odd
+   numbers less than 10 return false even if they are prime.  */
 static int
 is_prime (size_t candidate)
 {
-  /* No even number and none less than 10 will be passed here.  */
   size_t divn = 3;
   size_t sq = divn * divn;
 
@@ -605,7 +607,7 @@ is_prime (size_t candidate)
       ++divn;
     }
 
-  return candidate % divn != 0;
+  return (candidate >= divn && candidate % divn != 0);
 }
 
 


More information about the Libc-alpha mailing list