]> err.no Git - util-linux/commitdiff
libuuid, uuidd: Avoid infinite loop while reading from the socket fd
authorTheodore Ts'o <tytso@mit.edu>
Wed, 1 Jul 2009 02:49:49 +0000 (22:49 -0400)
committerTheodore Ts'o <tytso@mit.edu>
Wed, 1 Jul 2009 03:26:09 +0000 (23:26 -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>
misc-utils/uuidd.c
shlibs/uuid/src/gen_uuid.c

index 4284457183f49b511c0b9f4499f0696a0dde5737..74bab693808be7fab3cec84770d170a4d4e3b128 100644 (file)
@@ -84,19 +84,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;
index 32a6453bf1124c2e533a98425f941e7eca733d75..13096c0d29644fbf2bb1bd7b49f6791e4d9d2a34 100644 (file)
@@ -425,15 +425,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;