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