]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
s390/qeth: cancel close_dev work before removing a card
authorJulian Wiedmann <jwi@linux.ibm.com>
Mon, 4 Feb 2019 16:40:08 +0000 (17:40 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 13 Mar 2019 21:04:15 +0000 (14:04 -0700)
[ Upstream commit c2780c1a3fb724560b1d44f7976e0de17bf153c7 ]

A card's close_dev work is scheduled on a driver-wide workqueue. If the
card is removed and freed while the work is still active, this causes a
use-after-free.
So make sure that the work is completed before freeing the card.

Fixes: 0f54761d167f ("qeth: Support VEPA mode")
Signed-off-by: Julian Wiedmann <jwi@linux.ibm.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/s390/net/qeth_core.h
drivers/s390/net/qeth_l2_main.c
drivers/s390/net/qeth_l3_main.c

index 99af1a0a331478d9210d82755bd1354eb75534c1..8999be74c5451d2645857da052adc3fd17d63432 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/hashtable.h>
 #include <linux/ip.h>
 #include <linux/refcount.h>
+#include <linux/workqueue.h>
 
 #include <net/ipv6.h>
 #include <net/if_inet6.h>
index 8d3601891c62db3a58175d645a1ae30933a1520c..49fa09c67d49f52ada71e4b8431bd840859abe77 100644 (file)
@@ -823,6 +823,8 @@ static void qeth_l2_remove_device(struct ccwgroup_device *cgdev)
 
        if (cgdev->state == CCWGROUP_ONLINE)
                qeth_l2_set_offline(cgdev);
+
+       cancel_work_sync(&card->close_dev_work);
        if (qeth_netdev_is_registered(card->dev))
                unregister_netdev(card->dev);
 }
index f08b745c20073b92bd2a78da983ff2a9ade3ca77..d1bf55b5c8e1b7814f872f77242bfd88063ff90b 100644 (file)
@@ -2428,6 +2428,7 @@ static void qeth_l3_remove_device(struct ccwgroup_device *cgdev)
        if (cgdev->state == CCWGROUP_ONLINE)
                qeth_l3_set_offline(cgdev);
 
+       cancel_work_sync(&card->close_dev_work);
        if (qeth_netdev_is_registered(card->dev))
                unregister_netdev(card->dev);
        qeth_l3_clear_ip_htable(card, 0);