[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [linux-2.6.18-xen] blkback/blktap/netback: Fix CVE-2010-3699
# HG changeset patch # User Keir Fraser <keir@xxxxxxx> # Date 1290520718 0 # Node ID 59f097ef181b2d131fdc72a56071b964d771bcaa # Parent 26562626c866026c62c4be83b4c4c87b4cdc31a4 blkback/blktap/netback: Fix CVE-2010-3699 A guest can cause the backend driver to leak a kernel thread. Such leaked threads hold references to the device, whichmakes the device impossible to tear down. If shut down, the guest remains a zombie domain, the xenwatch process hangs, and most xm commands will stop working. This patch tries to do the following, for all of netback, blkback, blktap: - identify/extract idempotent teardown operations, - add/move the invocation of said teardown operation right before we're about to allocate new resources in the Connected states. Signed-off-by: Laszlo Ersek <lersek@xxxxxxxxxx> --- drivers/xen/blkback/xenbus.c | 6 ++++++ drivers/xen/blktap/xenbus.c | 26 +++++++++++++++++++++----- drivers/xen/netback/xenbus.c | 32 +++++++++++++++++++++----------- 3 files changed, 48 insertions(+), 16 deletions(-) diff -r 26562626c866 -r 59f097ef181b drivers/xen/blkback/xenbus.c --- a/drivers/xen/blkback/xenbus.c Fri Nov 19 13:22:43 2010 +0000 +++ b/drivers/xen/blkback/xenbus.c Tue Nov 23 13:58:38 2010 +0000 @@ -380,6 +380,11 @@ static void frontend_changed(struct xenb if (dev->state == XenbusStateConnected) break; + /* Enforce precondition before potential leak point. + * blkif_disconnect() is idempotent. + */ + blkif_disconnect(be->blkif); + err = connect_ring(be); if (err) break; @@ -397,6 +402,7 @@ static void frontend_changed(struct xenb break; /* fall through if not online */ case XenbusStateUnknown: + /* implies blkif_disconnect() via blkback_remove() */ device_unregister(&dev->dev); break; diff -r 26562626c866 -r 59f097ef181b drivers/xen/blktap/xenbus.c --- a/drivers/xen/blktap/xenbus.c Fri Nov 19 13:22:43 2010 +0000 +++ b/drivers/xen/blktap/xenbus.c Tue Nov 23 13:58:38 2010 +0000 @@ -339,6 +339,18 @@ static void tap_backend_changed(struct x tap_update_blkif_status(be->blkif); } + +static void blkif_disconnect(blkif_t *blkif) +{ + if (blkif->xenblkd) { + kthread_stop(blkif->xenblkd); + blkif->xenblkd = NULL; + } + + /* idempotent */ + tap_blkif_free(blkif); +} + /** * Callback received when the frontend's state changes. */ @@ -367,6 +379,11 @@ static void tap_frontend_changed(struct if (dev->state == XenbusStateConnected) break; + /* Enforce precondition before potential leak point. + * blkif_disconnect() is idempotent. + */ + blkif_disconnect(be->blkif); + err = connect_ring(be); if (err) break; @@ -374,11 +391,7 @@ static void tap_frontend_changed(struct break; case XenbusStateClosing: - if (be->blkif->xenblkd) { - kthread_stop(be->blkif->xenblkd); - be->blkif->xenblkd = NULL; - } - tap_blkif_free(be->blkif); + blkif_disconnect(be->blkif); xenbus_switch_state(dev, XenbusStateClosing); break; @@ -388,6 +401,9 @@ static void tap_frontend_changed(struct break; /* fall through if not online */ case XenbusStateUnknown: + /* Implies the effects of blkif_disconnect() via + * blktap_remove(). + */ device_unregister(&dev->dev); break; diff -r 26562626c866 -r 59f097ef181b drivers/xen/netback/xenbus.c --- a/drivers/xen/netback/xenbus.c Fri Nov 19 13:22:43 2010 +0000 +++ b/drivers/xen/netback/xenbus.c Tue Nov 23 13:58:38 2010 +0000 @@ -32,6 +32,7 @@ static int connect_rings(struct backend_ static int connect_rings(struct backend_info *); static void connect(struct backend_info *); static void backend_create_netif(struct backend_info *be); +static void netback_disconnect(struct device *); static int netback_remove(struct xenbus_device *dev) { @@ -39,16 +40,22 @@ static int netback_remove(struct xenbus_ netback_remove_accelerators(be, dev); + netback_disconnect(&dev->dev); + kfree(be); + dev->dev.driver_data = NULL; + return 0; +} + +static void netback_disconnect(struct device *xbdev_dev) +{ + struct backend_info *be = xbdev_dev->driver_data; + if (be->netif) { - kobject_uevent(&dev->dev.kobj, KOBJ_OFFLINE); + kobject_uevent(&xbdev_dev->kobj, KOBJ_OFFLINE); netif_disconnect(be->netif); be->netif = NULL; } - kfree(be); - dev->dev.driver_data = NULL; - return 0; -} - +} /** * Entry point to this code when a new device is created. Allocate the basic @@ -234,17 +241,19 @@ static void frontend_changed(struct xenb case XenbusStateConnected: if (dev->state == XenbusStateConnected) break; + + /* Enforce precondition before potential leak point. + * netback_disconnect() is idempotent. + */ + netback_disconnect(&dev->dev); + backend_create_netif(be); if (be->netif) connect(be); break; case XenbusStateClosing: - if (be->netif) { - kobject_uevent(&dev->dev.kobj, KOBJ_OFFLINE); - netif_disconnect(be->netif); - be->netif = NULL; - } + netback_disconnect(&dev->dev); xenbus_switch_state(dev, XenbusStateClosing); break; @@ -254,6 +263,7 @@ static void frontend_changed(struct xenb break; /* fall through if not online */ case XenbusStateUnknown: + /* implies netback_disconnect() via netback_remove() */ device_unregister(&dev->dev); break; _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |