]> git.ipfire.org Git - thirdparty/tor.git/commitdiff
Fix possible infinite loop on pipe/sock_drain()
authorDavid Goulet <dgoulet@ev0ke.net>
Fri, 30 Jan 2015 19:59:48 +0000 (14:59 -0500)
committerDavid Goulet <dgoulet@ev0ke.net>
Fri, 30 Jan 2015 20:05:18 +0000 (15:05 -0500)
If the returned value of read/recv is 0 (meaning EOF), we'll end up in an
infinite loop (active wait) until something is written on the pipe which is
not really what we want here especially because those functions are called
from the main thread.

Signed-off-by: David Goulet <dgoulet@ev0ke.net>
changes/bug14554 [new file with mode: 0644]
src/common/compat_threads.c

diff --git a/changes/bug14554 b/changes/bug14554
new file mode 100644 (file)
index 0000000..ff2566f
--- /dev/null
@@ -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.
index d2d929e4302642d737b9a44362c56aa8a292124d..ff8dc1ca61eb96be4c6dbcb1d709cb72f4cd0695 100644 (file)
@@ -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 (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 (!ERRNO_IS_EAGAIN(tor_socket_errno(fd)))
     return -1;
+  /* A value of r = 0 means EOF on the fd so successfully drained. */
   return 0;
 }