00db10
commit 4969890247d7d6a548f17641ed5a18f4b713d211
00db10
Author: Alexandre Oliva <aoliva@redhat.com>
00db10
Date:   Fri Nov 21 03:29:56 2014 -0200
00db10
00db10
    BZ#14498: fix infinite loop in nss_db_getservbyname
00db10
    
00db10
    nss_db uses nss_files code for services, but a continue on protocol
00db10
    mismatch that doesn't affect nss_files skipped the code that advanced
00db10
    to the next db entry.  Any one of these changes would suffice to fix
00db10
    it, but fixing both makes them both safer to reuse elsewhere.
00db10
    
00db10
    for  ChangeLog
00db10
    
00db10
    	[BZ #14498]
00db10
    	* NEWS: Fixed.
00db10
    	* nss/nss_db/db-XXX.c (_nss_db_get##name##_r): Update hidx
00db10
    	after parsing line but before break_if_match.
00db10
    	* nss/nss_files/files-service (DB_LOOKUP): Don't "continue;"
00db10
    	if there is a protocol mismatch.
00db10
00db10
Index: b/nss/nss_db/db-XXX.c
00db10
===================================================================
00db10
--- a/nss/nss_db/db-XXX.c
00db10
+++ b/nss/nss_db/db-XXX.c
00db10
@@ -190,6 +190,12 @@ enum nss_status								      \
00db10
       char *p = memcpy (buffer, valstr, len);				      \
00db10
 									      \
00db10
       int err = parse_line (p, result, data, buflen, errnop EXTRA_ARGS);      \
00db10
+									      \
00db10
+      /* Advance before break_if_match, lest it uses continue to skip
00db10
+	 to the next entry.  */						      \
00db10
+      if ((hidx += hval2) >= header->dbs[i].hashsize)			      \
00db10
+	hidx -= header->dbs[i].hashsize;				      \
00db10
+									      \
00db10
       if (err > 0)							      \
00db10
 	{								      \
00db10
 	  status = NSS_STATUS_SUCCESS;					      \
00db10
@@ -202,9 +208,6 @@ enum nss_status								      \
00db10
 	  status = NSS_STATUS_TRYAGAIN;					      \
00db10
 	  break;							      \
00db10
 	}								      \
00db10
-									      \
00db10
-      if ((hidx += hval2) >= header->dbs[i].hashsize)			      \
00db10
-	hidx -= header->dbs[i].hashsize;				      \
00db10
     }									      \
00db10
 									      \
00db10
   if (status == NSS_STATUS_NOTFOUND)					      \
00db10
Index: b/nss/nss_files/files-service.c
00db10
===================================================================
00db10
--- a/nss/nss_files/files-service.c
00db10
+++ b/nss/nss_files/files-service.c
00db10
@@ -44,8 +44,11 @@ DB_LOOKUP (servbyname, ':',
00db10
 	   {
00db10
 	     /* Must match both protocol (if specified) and name.  */
00db10
 	     if (proto != NULL && strcmp (result->s_proto, proto))
00db10
-	       continue;
00db10
-	     LOOKUP_NAME (s_name, s_aliases)
00db10
+	       /* A continue statement here breaks nss_db, because it
00db10
+		bypasses advancing to the next db entry, and it
00db10
+		doesn't make nss_files any more efficient.  */;
00db10
+	     else
00db10
+	       LOOKUP_NAME (s_name, s_aliases)
00db10
 	   },
00db10
 	   const char *name, const char *proto)
00db10