This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] Properly check for short writes when sending the response in nscd


I'd prefer to keep the same code structure in all files.  In some of
them the value of total is still needed later, so it cannot be changed.

Andreas.

	* nscd/grpcache.c (cache_addgr): Properly check for short write.
	* nscd/initgrcache.c (addinitgroupsX): Likewise.
	* nscd/pwdcache.c (cache_addpw): Likewise.
	* nscd/servicescache.c (cache_addserv): Likewise.  Don't write
	more than recsize.

diff --git a/nscd/grpcache.c b/nscd/grpcache.c
index d25d8e9..eccb7b1 100644
--- a/nscd/grpcache.c
+++ b/nscd/grpcache.c
@@ -75,6 +75,7 @@ cache_addgr (struct database_dyn *db, int fd, request_header *req,
 	     const void *key, struct group *grp, uid_t owner,
 	     struct hashentry *const he, struct datahead *dh, int errval)
 {
+  bool all_written = true;
   ssize_t total;
   ssize_t written;
   time_t t = time (NULL);
@@ -114,8 +115,12 @@ cache_addgr (struct database_dyn *db, int fd, request_header *req,
 	  total = sizeof (notfound);
 
 	  if (fd != -1)
-	    written = TEMP_FAILURE_RETRY (send (fd, &notfound, total,
-						MSG_NOSIGNAL));
+	    {
+	      written = TEMP_FAILURE_RETRY (send (fd, &notfound, total,
+						  MSG_NOSIGNAL));
+	      if (written != total)
+		all_written = false;
+	    }
 	  else
 	    written = total;
 
@@ -342,6 +347,9 @@ cache_addgr (struct database_dyn *db, int fd, request_header *req,
 # endif
 #endif
 	    written = writeall (fd, &dataset->resp, dataset->head.recsize);
+
+	  if (written != dataset->head.recsize)
+	    all_written = false;
 	}
 
       /* Add the record to the database.  But only if it has not been
@@ -401,7 +409,7 @@ cache_addgr (struct database_dyn *db, int fd, request_header *req,
 	}
     }
 
-  if (__builtin_expect (written != total, 0) && debug_level > 0)
+  if (__builtin_expect (!all_written, 0) && debug_level > 0)
     {
       char buf[256];
       dbg_log (_("short write in %s: %s"),  __FUNCTION__,
diff --git a/nscd/initgrcache.c b/nscd/initgrcache.c
index 196407c8..6b0b26b 100644
--- a/nscd/initgrcache.c
+++ b/nscd/initgrcache.c
@@ -171,10 +171,12 @@ addinitgroupsX (struct database_dyn *db, int fd, request_header *req,
 	nip = nip->next;
     }
 
+  bool all_written;
   ssize_t total;
   ssize_t written;
   time_t timeout;
  out:
+  all_written = true;
   timeout = MAX_TIMEOUT_VALUE;
   if (!any_success)
     {
@@ -198,8 +200,12 @@ addinitgroupsX (struct database_dyn *db, int fd, request_header *req,
 	  /* We have no data.  This means we send the standard reply for this
 	     case.  */
 	  if (fd != -1)
-	    written = TEMP_FAILURE_RETRY (send (fd, &notfound, total,
-						MSG_NOSIGNAL));
+	    {
+	      written = TEMP_FAILURE_RETRY (send (fd, &notfound, total,
+						  MSG_NOSIGNAL));
+	      if (written != total)
+		all_written = false;
+	    }
 
 	  /* If we have a transient error or cannot permanently store
 	     the result, so be it.  */
@@ -379,6 +385,9 @@ addinitgroupsX (struct database_dyn *db, int fd, request_header *req,
 # endif
 #endif
 	    written = writeall (fd, &dataset->resp, dataset->head.recsize);
+
+	  if (written != dataset->head.recsize)
+	    all_written = false;
 	}
 
 
@@ -405,7 +414,7 @@ addinitgroupsX (struct database_dyn *db, int fd, request_header *req,
 
   free (groups);
 
-  if (__builtin_expect (written != total, 0) && debug_level > 0)
+  if (__builtin_expect (!all_written, 0) && debug_level > 0)
     {
       char buf[256];
       dbg_log (_("short write in %s: %s"), __FUNCTION__,
diff --git a/nscd/pwdcache.c b/nscd/pwdcache.c
index ef492b5..aa82ead 100644
--- a/nscd/pwdcache.c
+++ b/nscd/pwdcache.c
@@ -81,6 +81,7 @@ cache_addpw (struct database_dyn *db, int fd, request_header *req,
 	     const void *key, struct passwd *pwd, uid_t owner,
 	     struct hashentry *const he, struct datahead *dh, int errval)
 {
+  bool all_written = true;
   ssize_t total;
   ssize_t written;
   time_t t = time (NULL);
@@ -120,8 +121,12 @@ cache_addpw (struct database_dyn *db, int fd, request_header *req,
 	  written = total = sizeof (notfound);
 
 	  if (fd != -1)
-	    written = TEMP_FAILURE_RETRY (send (fd, &notfound, total,
-						MSG_NOSIGNAL));
+	    {
+	      written = TEMP_FAILURE_RETRY (send (fd, &notfound, total,
+						  MSG_NOSIGNAL));
+	      if (written != total)
+		all_written = false;
+	    }
 
 	  /* If we have a transient error or cannot permanently store
 	     the result, so be it.  */
@@ -306,7 +311,7 @@ cache_addpw (struct database_dyn *db, int fd, request_header *req,
 			  + db->head->data_size));
 	      written = sendfileall (fd, db->wr_fd,
 				     (char *) &dataset->resp
-				     - (char *) db->head, dataset->head.recsize );
+				     - (char *) db->head, dataset->head.recsize);
 # ifndef __ASSUME_SENDFILE
 	      if (written == -1 && errno == ENOSYS)
 		goto use_write;
@@ -318,6 +323,9 @@ cache_addpw (struct database_dyn *db, int fd, request_header *req,
 # endif
 #endif
 	    written = writeall (fd, &dataset->resp, dataset->head.recsize);
+
+	  if (written != dataset->head.recsize)
+	    all_written = false;
 	}
 
 
@@ -377,7 +385,7 @@ cache_addpw (struct database_dyn *db, int fd, request_header *req,
 	}
     }
 
-  if (__builtin_expect (written != total, 0) && debug_level > 0)
+  if (__builtin_expect (!all_written, 0) && debug_level > 0)
     {
       char buf[256];
       dbg_log (_("short write in %s: %s"),  __FUNCTION__,
diff --git a/nscd/servicescache.c b/nscd/servicescache.c
index d29cde7..bdbc495 100644
--- a/nscd/servicescache.c
+++ b/nscd/servicescache.c
@@ -65,6 +65,7 @@ cache_addserv (struct database_dyn *db, int fd, request_header *req,
 	       const void *key, struct servent *serv, uid_t owner,
 	       struct hashentry *const he, struct datahead *dh, int errval)
 {
+  bool all_written = true;
   ssize_t total;
   ssize_t written;
   time_t t = time (NULL);
@@ -104,8 +105,12 @@ cache_addserv (struct database_dyn *db, int fd, request_header *req,
 	  written = total = sizeof (notfound);
 
 	  if (fd != -1)
-	    written = TEMP_FAILURE_RETRY (send (fd, &notfound, total,
-						MSG_NOSIGNAL));
+	    {
+	      written = TEMP_FAILURE_RETRY (send (fd, &notfound, total,
+						  MSG_NOSIGNAL));
+	      if (written != total)
+		all_written = false;
+	    }
 
 	  /* If we have a transient error or cannot permanently store
 	     the result, so be it.  */
@@ -290,14 +295,14 @@ cache_addserv (struct database_dyn *db, int fd, request_header *req,
 	    {
 	      assert (db->wr_fd != -1);
 	      assert ((char *) &dataset->resp > (char *) db->data);
-	      assert ((char *) &dataset->resp - (char *) db->head
+	      assert ((char *) dataset - (char *) db->head
 		      + total
 		      <= (sizeof (struct database_pers_head)
 			  + db->head->module * sizeof (ref_t)
 			  + db->head->data_size));
 	      written = sendfileall (fd, db->wr_fd,
 				     (char *) &dataset->resp
-				     - (char *) db->head, total);
+				     - (char *) db->head, dataset->head.recsize);
 # ifndef __ASSUME_SENDFILE
 	      if (written == -1 && errno == ENOSYS)
 		goto use_write;
@@ -308,7 +313,10 @@ cache_addserv (struct database_dyn *db, int fd, request_header *req,
 	  use_write:
 # endif
 #endif
-	    written = writeall (fd, &dataset->resp, total);
+	    written = writeall (fd, &dataset->resp, dataset->head.recsize);
+
+	  if (written != dataset->head.recsize)
+	    all_written = false;
 	}
 
       /* Add the record to the database.  But only if it has not been
@@ -332,7 +340,7 @@ cache_addserv (struct database_dyn *db, int fd, request_header *req,
 	}
     }
 
-  if (__builtin_expect (written != total, 0) && debug_level > 0)
+  if (__builtin_expect (!all_written, 0) && debug_level > 0)
     {
       char buf[256];
       dbg_log (_("short write in %s: %s"),  __FUNCTION__,
-- 
1.8.1

-- 
Andreas Schwab, SUSE Labs, schwab@suse.de
GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE  1748 E4D4 88E3 0EEA B9D7
"And now for something completely different."


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]