Under the right circumstances, xenconsoled will corrupt its internal
list of domains causing a SEGV. This is usually characterized by a
rapid number of creations/destructions. The attached patch fixes this.
Regards,
Anthony Liguori
# HG changeset patch
# User Anthony Liguori <aliguori@xxxxxxxxxx>
# Node ID f8e21ceb6820b6bdb48a161c5f401f3577a14fde
# Parent a5e3caa6efbf3a46515c8b4f39219eaed75b2b6c
1) Fix uninitialized next pointer. This could sometimes cause xenconsoled to
SEGV on an invalid domain pointer
2) Fix race condition in iterating domain list where removing a domain in a
callback could lead to the iterators becoming invalid.
Signed-off-by: Anthony Liguori <aliguori@xxxxxxxxxx>
diff -r a5e3caa6efbf -r f8e21ceb6820 tools/console/daemon/io.c
--- a/tools/console/daemon/io.c Sat Aug 13 19:31:13 2005
+++ b/tools/console/daemon/io.c Mon Aug 15 20:11:29 2005
@@ -87,6 +87,7 @@
{
int domid;
int tty_fd;
+ bool is_dead;
struct buffer buffer;
struct domain *next;
};
@@ -156,10 +157,12 @@
dom->domid = domid;
dom->tty_fd = domain_create_tty(dom);
+ dom->is_dead = false;
dom->buffer.data = 0;
dom->buffer.size = 0;
dom->buffer.capacity = 0;
dom->buffer.max_capacity = 0;
+ dom->next = 0;
dolog(LOG_DEBUG, "New domain %d", domid);
@@ -206,6 +209,16 @@
}
}
+static void remove_dead_domains(struct domain *dom)
+{
+ if (dom == NULL) return;
+ remove_dead_domains(dom->next);
+
+ if (dom->is_dead) {
+ remove_domain(dom);
+ }
+}
+
static void handle_tty_read(struct domain *dom)
{
ssize_t len;
@@ -224,7 +237,7 @@
if (domain_is_valid(dom->domid)) {
dom->tty_fd = domain_create_tty(dom);
} else {
- remove_domain(dom);
+ dom->is_dead = true;
}
} else if (domain_is_valid(dom->domid)) {
msg.u.control.msg.length = len;
@@ -235,7 +248,7 @@
}
} else {
close(dom->tty_fd);
- remove_domain(dom);
+ dom->is_dead = true;
}
}
@@ -250,7 +263,7 @@
if (domain_is_valid(dom->domid)) {
dom->tty_fd = domain_create_tty(dom);
} else {
- remove_domain(dom);
+ dom->is_dead = true;
}
} else {
buffer_advance(&dom->buffer, len);
@@ -333,13 +346,15 @@
}
for (d = dom_head; d; d = d->next) {
- if (FD_ISSET(d->tty_fd, &readfds)) {
+ if (!d->is_dead && FD_ISSET(d->tty_fd, &readfds)) {
handle_tty_read(d);
}
- if (FD_ISSET(d->tty_fd, &writefds)) {
+ if (!d->is_dead && FD_ISSET(d->tty_fd, &writefds)) {
handle_tty_write(d);
}
}
+
+ remove_dead_domains(dom_head);
} while (ret > -1);
}
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
|