ia64/xen-unstable

changeset 16303:2462265f09ae

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>
author Keir Fraser <keir@xensource.com>
date Thu Nov 01 16:34:43 2007 +0000 (2007-11-01)
parents 7cd040290f82
children b41333afc9cc
files tools/console/daemon/io.c
line diff
     1.1 --- a/tools/console/daemon/io.c	Thu Nov 01 16:34:20 2007 +0000
     1.2 +++ b/tools/console/daemon/io.c	Thu Nov 01 16:34:43 2007 +0000
     1.3 @@ -628,7 +628,6 @@ static void shutdown_domain(struct domai
     1.4  	if (d->xce_handle != -1)
     1.5  		xc_evtchn_close(d->xce_handle);
     1.6  	d->xce_handle = -1;
     1.7 -	cleanup_domain(d);
     1.8  }
     1.9  
    1.10  void enum_domains(void)
    1.11 @@ -674,6 +673,9 @@ static void handle_tty_read(struct domai
    1.12  	struct xencons_interface *intf = dom->interface;
    1.13  	XENCONS_RING_IDX prod;
    1.14  
    1.15 +	if (dom->is_dead)
    1.16 +		return;
    1.17 +
    1.18  	len = ring_free_bytes(dom);
    1.19  	if (len == 0)
    1.20  		return;
    1.21 @@ -711,6 +713,9 @@ static void handle_tty_write(struct doma
    1.22  {
    1.23  	ssize_t len;
    1.24  
    1.25 +	if (dom->is_dead)
    1.26 +		return;
    1.27 +
    1.28  	len = write(dom->tty_fd, dom->buffer.data + dom->buffer.consumed,
    1.29  		    dom->buffer.size - dom->buffer.consumed);
    1.30   	if (len < 1) {
    1.31 @@ -734,6 +739,9 @@ static void handle_ring_read(struct doma
    1.32  {
    1.33  	evtchn_port_or_error_t port;
    1.34  
    1.35 +	if (dom->is_dead)
    1.36 +		return;
    1.37 +
    1.38  	if ((port = xc_evtchn_pending(dom->xce_handle)) == -1)
    1.39  		return;
    1.40