Browse Source

Merge remote-tracking branch 'dgoulet/bug14554_026_v1'

Nick Mathewson 9 years ago
parent
commit
aba90b2125
2 changed files with 14 additions and 6 deletions
  1. 4 0
      changes/bug14554
  2. 10 6
      src/common/compat_threads.c

+ 4 - 0
changes/bug14554

@@ -0,0 +1,4 @@
+  o Major bugfix
+    - Possibility of an infinite loop if the returned value of the read/recv
+      was 0. A returned value of 0 means that we've reached the EOF thus the
+      pipe/sock is drained so return success not an error.

+ 10 - 6
src/common/compat_threads.c

@@ -171,10 +171,12 @@ pipe_drain(int fd)
 {
   char buf[32];
   ssize_t r;
-  while ((r = read_ni(fd, buf, sizeof(buf))) >= 0)
-    ;
-  if (r == 0 || errno != EAGAIN)
+  do {
+    r = read_ni(fd, buf, sizeof(buf));
+  } while (r > 0);
+  if (r < 0 && errno != EAGAIN)
     return -1;
+  /* A value of r = 0 means EOF on the fd so successfully drained. */
   return 0;
 }
 #endif
@@ -193,10 +195,12 @@ sock_drain(tor_socket_t fd)
 {
   char buf[32];
   ssize_t r;
-  while ((r = recv_ni(fd, buf, sizeof(buf), 0)) >= 0)
-    ;
-  if (r == 0 || !ERRNO_IS_EAGAIN(tor_socket_errno(fd)))
+  do {
+    r = recv_ni(fd, buf, sizeof(buf), 0);
+  } while (r > 0);
+  if (r < 0 && !ERRNO_IS_EAGAIN(tor_socket_errno(fd)))
     return -1;
+  /* A value of r = 0 means EOF on the fd so successfully drained. */
   return 0;
 }