aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTheodore Ts'o <tytso@mit.edu>2009-06-29 20:03:20 -0400
committerTheodore Ts'o <tytso@mit.edu>2009-06-29 20:03:20 -0400
commitcaa6003b6419d001593478a46fb4cbf8e502e818 (patch)
tree26e046457fef03f6ee15b8113e0b09b1f30c7e7a
parent2842bb31880643f270e79622769def0f9b1fac59 (diff)
downloadandroid_external_e2fsprogs-caa6003b6419d001593478a46fb4cbf8e502e818.tar.gz
android_external_e2fsprogs-caa6003b6419d001593478a46fb4cbf8e502e818.tar.bz2
android_external_e2fsprogs-caa6003b6419d001593478a46fb4cbf8e502e818.zip
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" <tytso@mit.edu>
-rw-r--r--lib/uuid/gen_uuid.c10
-rw-r--r--misc/uuidd.c14
2 files changed, 16 insertions, 8 deletions
diff --git a/lib/uuid/gen_uuid.c b/lib/uuid/gen_uuid.c
index aa313efe..5893aff3 100644
--- a/lib/uuid/gen_uuid.c
+++ b/lib/uuid/gen_uuid.c
@@ -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;
diff --git a/misc/uuidd.c b/misc/uuidd.c
index 6913bf7e..89bff721 100644
--- a/misc/uuidd.c
+++ b/misc/uuidd.c
@@ -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;