From 3b90c50066969cfa40a392d0290cb8d762351f65 Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Tue, 30 Jun 2009 22:49:49 -0400 Subject: [PATCH] libuuid, uuidd: Avoid infinite loop while reading from the socket fd 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" --- misc-utils/uuidd.c | 14 +++++++++----- shlibs/uuid/src/gen_uuid.c | 10 +++++++--- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/misc-utils/uuidd.c b/misc-utils/uuidd.c index 42844571..74bab693 100644 --- a/misc-utils/uuidd.c +++ b/misc-utils/uuidd.c @@ -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; diff --git a/shlibs/uuid/src/gen_uuid.c b/shlibs/uuid/src/gen_uuid.c index 32a6453b..13096c0d 100644 --- a/shlibs/uuid/src/gen_uuid.c +++ b/shlibs/uuid/src/gen_uuid.c @@ -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; -- 2.39.5