about summary refs log tree commit diff
diff options
context:
space:
mode:
authorAlexandre Oliva <aoliva@redhat.com>2014-11-21 03:29:56 -0200
committerAlexandre Oliva <aoliva@redhat.com>2014-11-21 03:29:56 -0200
commit4969890247d7d6a548f17641ed5a18f4b713d211 (patch)
tree26eeb456373435508696552d794f926f02f74701
parent81959214868c9ac9e425fbf0fa3fd9135e207f7e (diff)
downloadglibc-4969890247d7d6a548f17641ed5a18f4b713d211.tar.gz
glibc-4969890247d7d6a548f17641ed5a18f4b713d211.tar.xz
glibc-4969890247d7d6a548f17641ed5a18f4b713d211.zip
BZ#14498: fix infinite loop in nss_db_getservbyname
nss_db uses nss_files code for services, but a continue on protocol
mismatch that doesn't affect nss_files skipped the code that advanced
to the next db entry.  Any one of these changes would suffice to fix
it, but fixing both makes them both safer to reuse elsewhere.

for  ChangeLog

	[BZ #14498]
	* NEWS: Fixed.
	* nss/nss_db/db-XXX.c (_nss_db_get##name##_r): Update hidx
	after parsing line but before break_if_match.
	* nss/nss_files/files-service (DB_LOOKUP): Don't "continue;"
	if there is a protocol mismatch.
-rw-r--r--ChangeLog9
-rw-r--r--NEWS8
-rw-r--r--nss/nss_db/db-XXX.c9
-rw-r--r--nss/nss_files/files-service.c7
4 files changed, 24 insertions, 9 deletions
diff --git a/ChangeLog b/ChangeLog
index 4c9c827252..785189dd8e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2014-11-21  Alexandre Oliva <aoliva@redhat.com>
+
+	[BZ #14498]
+	* NEWS: Fixed.
+	* nss/nss_db/db-XXX.c (_nss_db_get##name##_r): Update hidx
+	after parsing line but before break_if_match.
+	* nss/nss_files/files-service (DB_LOOKUP): Don't "continue;"
+	if there is a protocol mismatch.
+
 2014-11-21  Ma Shimiao <mashimiao.fnst@cn.fujitsu.com>
 
 	* manual/sysinfo.texi (addmntent): It is actually MT-Safe,
diff --git a/NEWS b/NEWS
index 4b7eeb4bc2..5ba3f1bc09 100644
--- a/NEWS
+++ b/NEWS
@@ -9,10 +9,10 @@ Version 2.21
 
 * The following bugs are resolved with this release:
 
-  6652, 12926, 14132, 14138, 14171, 15215, 15884, 17266, 17344, 17363,
-  17370, 17371, 17411, 17460, 17475, 17485, 17501, 17506, 17508, 17522,
-  17555, 17570, 17571, 17572, 17573, 17574, 17582, 17583, 17584, 17585,
-  17589, 17594, 17616, 17625.
+  6652, 12926, 14132, 14138, 14171, 14498, 15215, 15884, 17266, 17344,
+  17363, 17370, 17371, 17411, 17460, 17475, 17485, 17501, 17506, 17508,
+  17522, 17555, 17570, 17571, 17572, 17573, 17574, 17582, 17583, 17584,
+  17585, 17589, 17594, 17616, 17625.
 
 * CVE-2104-7817 The wordexp function could ignore the WRDE_NOCMD flag
   under certain input conditions resulting in the execution of a shell for
diff --git a/nss/nss_db/db-XXX.c b/nss/nss_db/db-XXX.c
index 89b1a126c2..e95088743d 100644
--- a/nss/nss_db/db-XXX.c
+++ b/nss/nss_db/db-XXX.c
@@ -191,6 +191,12 @@ enum nss_status								      \
       char *p = memcpy (buffer, valstr, len);				      \
 									      \
       int err = parse_line (p, result, data, buflen, errnop EXTRA_ARGS);      \
+									      \
+      /* Advance before break_if_match, lest it uses continue to skip
+	 to the next entry.  */						      \
+      if ((hidx += hval2) >= header->dbs[i].hashsize)			      \
+	hidx -= header->dbs[i].hashsize;				      \
+									      \
       if (err > 0)							      \
 	{								      \
 	  status = NSS_STATUS_SUCCESS;					      \
@@ -203,9 +209,6 @@ enum nss_status								      \
 	  status = NSS_STATUS_TRYAGAIN;					      \
 	  break;							      \
 	}								      \
-									      \
-      if ((hidx += hval2) >= header->dbs[i].hashsize)			      \
-	hidx -= header->dbs[i].hashsize;				      \
     }									      \
 									      \
   if (status == NSS_STATUS_NOTFOUND)					      \
diff --git a/nss/nss_files/files-service.c b/nss/nss_files/files-service.c
index 2401cb0852..c28c62f94b 100644
--- a/nss/nss_files/files-service.c
+++ b/nss/nss_files/files-service.c
@@ -44,8 +44,11 @@ DB_LOOKUP (servbyname, ':',
 	   {
 	     /* Must match both protocol (if specified) and name.  */
 	     if (proto != NULL && strcmp (result->s_proto, proto))
-	       continue;
-	     LOOKUP_NAME (s_name, s_aliases)
+	       /* A continue statement here breaks nss_db, because it
+		bypasses advancing to the next db entry, and it
+		doesn't make nss_files any more efficient.  */;
+	     else
+	       LOOKUP_NAME (s_name, s_aliases)
 	   },
 	   const char *name, const char *proto)