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