diff options
author | Keir Fraser <keir@xensource.com> | 2007-11-01 16:34:43 +0000 |
---|---|---|
committer | Keir Fraser <keir@xensource.com> | 2007-11-01 16:34:43 +0000 |
commit | ed8c66a1f64e03aa0c28a599b785976b8f894ea2 (patch) | |
tree | f13c349927ef5a24894900c6e012a58ca4f38c91 /tools/console/daemon | |
parent | 50c994308afc37f31974795d1391612904d1282c (diff) | |
download | xen-ed8c66a1f64e03aa0c28a599b785976b8f894ea2.tar.gz xen-ed8c66a1f64e03aa0c28a599b785976b8f894ea2.tar.bz2 xen-ed8c66a1f64e03aa0c28a599b785976b8f894ea2.zip |
Fix use-after-free in xenconsoled.
shutdown_domain() MUST NOT call cleanup_domain(), just flagging them
as dead is enough. cleanup_domains() for dead domains is called by
the main loop in handle_io() in a safe way already.
shutdown_domain() calling cleanup_domain() too leads struct domain
being accessed after freeing and to a double-free.
Fixed by simply dropping the cleanup_domain() call and by making the
functions called by the main loop in handle_io() ignore dead domains.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Diffstat (limited to 'tools/console/daemon')
-rw-r--r-- | tools/console/daemon/io.c | 10 |
1 files changed, 9 insertions, 1 deletions
diff --git a/tools/console/daemon/io.c b/tools/console/daemon/io.c index 87b45cb9bd..b699384780 100644 --- a/tools/console/daemon/io.c +++ b/tools/console/daemon/io.c @@ -628,7 +628,6 @@ static void shutdown_domain(struct domain *d) if (d->xce_handle != -1) xc_evtchn_close(d->xce_handle); d->xce_handle = -1; - cleanup_domain(d); } void enum_domains(void) @@ -674,6 +673,9 @@ static void handle_tty_read(struct domain *dom) struct xencons_interface *intf = dom->interface; XENCONS_RING_IDX prod; + if (dom->is_dead) + return; + len = ring_free_bytes(dom); if (len == 0) return; @@ -711,6 +713,9 @@ static void handle_tty_write(struct domain *dom) { ssize_t len; + if (dom->is_dead) + return; + len = write(dom->tty_fd, dom->buffer.data + dom->buffer.consumed, dom->buffer.size - dom->buffer.consumed); if (len < 1) { @@ -734,6 +739,9 @@ static void handle_ring_read(struct domain *dom) { evtchn_port_or_error_t port; + if (dom->is_dead) + return; + if ((port = xc_evtchn_pending(dom->xce_handle)) == -1) return; |