[gnome-keyring] Fix endless loop in reading data.
- From: Stefan Walter <stefw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-keyring] Fix endless loop in reading data.
- Date: Mon, 8 Mar 2010 04:51:22 +0000 (UTC)
commit 6c25bf1ba2772ac56e9f0430661290a40cbefed1
Author: Stef Walter <stef memberwebs com>
Date: Mon Mar 8 04:39:18 2010 +0000
Fix endless loop in reading data.
Fix problems with EINTR and EAGAIN handling, and some possible
endless loops in various places.
Fixes bug #610678
daemon/control/gkd-control-server.c | 16 +++++++++++-----
daemon/prompt/gkd-prompt-tool.c | 4 +++-
daemon/ssh-agent/gkd-ssh-agent.c | 19 +++++++++++--------
pkcs11/gck/gck-data-file.c | 26 +++++++++++++++-----------
4 files changed, 40 insertions(+), 25 deletions(-)
---
diff --git a/daemon/control/gkd-control-server.c b/daemon/control/gkd-control-server.c
index db7ea29..18d4bf7 100644
--- a/daemon/control/gkd-control-server.c
+++ b/daemon/control/gkd-control-server.c
@@ -169,9 +169,11 @@ control_output (GIOChannel *channel, GIOCondition cond, gpointer user_data)
if (cond & G_IO_OUT) {
res = write (fd, buffer->buf + cdata->position, buffer->len - cdata->position);
- if (res <= 0) {
+ if (res < 0) {
if (errno != EAGAIN && errno != EINTR)
cdata->position = buffer->len;
+ } else if (res == 0) {
+ cdata->position = buffer->len;
} else {
cdata->position += res;
g_assert (cdata->position <= buffer->len);
@@ -247,7 +249,7 @@ control_input (GIOChannel *channel, GIOCondition cond, gpointer user_data)
/* Time for reading credentials */
if (cdata->position == 0) {
if (egg_unix_credentials_read (fd, &pid, &uid) < 0) {
- if (errno != EAGAIN || errno != EINTR)
+ if (errno != EAGAIN && errno != EINTR)
finished = TRUE;
} else if (getuid () != uid) {
g_message ("control request from bad uid: %u, should be %u\n", uid, getuid ());
@@ -260,9 +262,11 @@ control_input (GIOChannel *channel, GIOCondition cond, gpointer user_data)
} else if (egg_buffer_length (buffer) < 4) {
egg_buffer_reserve (buffer, 4);
res = read (fd, buffer->buf + buffer->len, 4 - buffer->len);
- if (res <= 0) {
- if (errno != EAGAIN || errno != EINTR)
+ if (res < 0) {
+ if (errno != EAGAIN && errno != EINTR)
finished = TRUE;
+ } else if (res == 0) {
+ finished = TRUE;
} else {
buffer->len += res;
}
@@ -276,9 +280,11 @@ control_input (GIOChannel *channel, GIOCondition cond, gpointer user_data)
g_assert (buffer->len < packet_size);
egg_buffer_reserve (buffer, packet_size);
res = read (fd, buffer->buf + buffer->len, packet_size - buffer->len);
- if (res <= 0) {
+ if (res < 0) {
if (errno != EAGAIN && errno != EINTR)
finished = TRUE;
+ } else if (res == 0) {
+ finished = TRUE;
} else {
buffer->len += res;
g_assert (buffer->len <= packet_size);
diff --git a/daemon/prompt/gkd-prompt-tool.c b/daemon/prompt/gkd-prompt-tool.c
index b98de97..19257f2 100644
--- a/daemon/prompt/gkd-prompt-tool.c
+++ b/daemon/prompt/gkd-prompt-tool.c
@@ -798,13 +798,15 @@ write_all_output (const gchar *data, gsize len)
while (len > 0) {
res = write (1, data, len);
- if (res <= 0) {
+ if (res < 0) {
if (errno == EAGAIN || errno == EINTR)
continue;
if (errno != EPIPE)
g_warning ("couldn't write dialog response to output: %s",
g_strerror (errno));
exit (1);
+ } else if (res == 0) {
+ g_warning ("couldn't write all dialog response to output");
} else {
len -= res;
data += res;
diff --git a/daemon/ssh-agent/gkd-ssh-agent.c b/daemon/ssh-agent/gkd-ssh-agent.c
index 0a851ce..50a1b79 100644
--- a/daemon/ssh-agent/gkd-ssh-agent.c
+++ b/daemon/ssh-agent/gkd-ssh-agent.c
@@ -56,12 +56,13 @@ read_all (int fd, guchar *buf, int len)
res = read (fd, buf, len);
- if (res <= 0) {
- if (errno == EAGAIN && errno == EINTR)
+ if (res < 0) {
+ if (errno == EAGAIN || errno == EINTR)
continue;
- if (res < 0)
- g_warning ("couldn't read %u bytes from client: %s", all,
- g_strerror (errno));
+ g_warning ("couldn't read %u bytes from client: %s", all,
+ g_strerror (errno));
+ return FALSE;
+ } else if (res == 0) {
return FALSE;
} else {
len -= res;
@@ -81,13 +82,15 @@ write_all (int fd, const guchar *buf, int len)
while (len > 0) {
res = write (fd, buf, len);
-
- if (res <= 0) {
+ if (res < 0) {
if (errno == EAGAIN && errno == EINTR)
continue;
if (errno != EPIPE)
g_warning ("couldn't write %u bytes to client: %s", all,
- res < 0 ? g_strerror (errno) : "");
+ g_strerror (errno));
+ return FALSE;
+ } else if (res == 0) {
+ g_warning ("couldn't write %u bytes to client", all);
return FALSE;
} else {
len -= res;
diff --git a/pkcs11/gck/gck-data-file.c b/pkcs11/gck/gck-data-file.c
index e4e8c27..54d794f 100644
--- a/pkcs11/gck/gck-data-file.c
+++ b/pkcs11/gck/gck-data-file.c
@@ -132,23 +132,25 @@ read_all_bytes (int fd, guchar *buf, gsize len)
{
gsize all = len;
int res;
-
+
while (len > 0) {
-
res = read (fd, buf, len);
- if (res <= 0) {
+ if (res < 0) {
if (errno == EAGAIN || errno == EINTR)
continue;
- if (res < 0 || len != all)
- g_warning ("couldn't read %u bytes from store file: %s",
- (guint)all, g_strerror (errno));
+ g_warning ("couldn't read %u bytes from store file: %s",
+ (guint)all, g_strerror (errno));
+ return FALSE;
+ } else if (res == 0) {
+ if (len != all)
+ g_warning ("couldn't read %u bytes from store file", (guint)all);
return FALSE;
} else {
len -= res;
buf += res;
}
}
-
+
return TRUE;
}
@@ -161,12 +163,14 @@ write_all_bytes (int fd, const guchar *buf, gsize len)
while (len > 0) {
res = write (fd, buf, len);
-
- if (res <= 0) {
+ if (res < 0) {
if (errno == EAGAIN || errno == EINTR)
continue;
g_warning ("couldn't write %u bytes to store file: %s",
- (guint)all, res < 0 ? g_strerror (errno) : "");
+ (guint)all, g_strerror (errno));
+ return FALSE;
+ } else if (res == 0) {
+ g_warning ("couldn't write %u bytes to store file", (guint)all);
return FALSE;
} else {
len -= res;
@@ -219,7 +223,7 @@ parse_file_blocks (int file, BlockFunc block_func, GckSecret *login, gpointer us
if (!egg_buffer_get_uint32 (&buffer, offset, &offset, &length) ||
!egg_buffer_get_uint32 (&buffer, offset, &offset, &block) ||
length < 8) {
- res = GCK_DATA_SUCCESS;
+ res = GCK_DATA_FAILURE;
g_message ("invalid block size or length in store file");
break;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]