]> git.ipfire.org Git - thirdparty/e2fsprogs.git/commitdiff
libuuid, uuidd: Avoid infinite loop while reading from the socket fd
authorTheodore Ts'o <tytso@mit.edu>
Tue, 30 Jun 2009 00:03:20 +0000 (20:03 -0400)
committerTheodore Ts'o <tytso@mit.edu>
Tue, 30 Jun 2009 00:03:20 +0000 (20:03 -0400)
If for some reason the uuidd daemon or the process calling uuidd
exited unexpectely, the read_all() function would end up looping
forever, either in uuidd or in libuuid.  Fix this terminating the loop
if no data can be read after five tries to read from the file
descriptor.

Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
lib/uuid/gen_uuid.c
misc/uuidd.c

index aa313efed06398a42546435ec7bd56d405327042..5893aff3c800963c2e885f5c6451836070f8bc43 100644 (file)
@@ -419,15 +419,19 @@ static ssize_t read_all(int fd, char *buf, size_t count)
 {
        ssize_t ret;
        ssize_t c = 0;
+       int tries = 0;
 
        memset(buf, 0, count);
        while (count > 0) {
                ret = read(fd, buf, count);
-               if (ret < 0) {
-                       if ((errno == EAGAIN) || (errno == EINTR))
+               if (ret <= 0) {
+                       if ((errno == EAGAIN || errno == EINTR || ret == 0) &&
+                           (tries++ < 5))
                                continue;
-                       return -1;
+                       return c ? c : -1;
                }
+               if (ret > 0)
+                       tries = 0;
                count -= ret;
                buf += ret;
                c += ret;
index 6913bf7e2125eeb42030c5ea8bde351e30849f23..89bff721f1354d59ae613e685f20a6a6b4d0cfd2 100644 (file)
@@ -85,19 +85,23 @@ static void create_daemon(void)
                die("setreuid");
 }
 
-static int read_all(int fd, char *buf, size_t count)
+static ssize_t read_all(int fd, char *buf, size_t count)
 {
        ssize_t ret;
-       int c = 0;
+       ssize_t c = 0;
+       int tries = 0;
 
        memset(buf, 0, count);
        while (count > 0) {
                ret = read(fd, buf, count);
-               if (ret < 0) {
-                       if ((errno == EAGAIN) || (errno == EINTR))
+               if (ret <= 0) {
+                       if ((errno == EAGAIN || errno == EINTR || ret == 0) &&
+                           (tries++ < 5))
                                continue;
-                       return -1;
+                       return c ? c : -1;
                }
+               if (ret > 0)
+                       tries = 0;
                count -= ret;
                buf += ret;
                c += ret;