]>
Commit | Line | Data |
---|---|---|
7748c0ed SL |
1 | From 4e8f2535c8078c8c9d6538a645ae2206b3151850 Mon Sep 17 00:00:00 2001 |
2 | From: Julian Wiedmann <jwi@linux.ibm.com> | |
3 | Date: Mon, 4 Feb 2019 17:40:08 +0100 | |
4 | Subject: s390/qeth: cancel close_dev work before removing a card | |
5 | ||
6 | [ Upstream commit c2780c1a3fb724560b1d44f7976e0de17bf153c7 ] | |
7 | ||
8 | A card's close_dev work is scheduled on a driver-wide workqueue. If the | |
9 | card is removed and freed while the work is still active, this causes a | |
10 | use-after-free. | |
11 | So make sure that the work is completed before freeing the card. | |
12 | ||
13 | Fixes: 0f54761d167f ("qeth: Support VEPA mode") | |
14 | Signed-off-by: Julian Wiedmann <jwi@linux.ibm.com> | |
15 | Signed-off-by: David S. Miller <davem@davemloft.net> | |
16 | Signed-off-by: Sasha Levin <sashal@kernel.org> | |
17 | --- | |
18 | drivers/s390/net/qeth_core.h | 1 + | |
19 | drivers/s390/net/qeth_l2_main.c | 2 ++ | |
20 | drivers/s390/net/qeth_l3_main.c | 1 + | |
21 | 3 files changed, 4 insertions(+) | |
22 | ||
23 | diff --git a/drivers/s390/net/qeth_core.h b/drivers/s390/net/qeth_core.h | |
24 | index 970654fcc48d..2d1f6a583641 100644 | |
25 | --- a/drivers/s390/net/qeth_core.h | |
26 | +++ b/drivers/s390/net/qeth_core.h | |
27 | @@ -22,6 +22,7 @@ | |
28 | #include <linux/hashtable.h> | |
29 | #include <linux/ip.h> | |
30 | #include <linux/refcount.h> | |
31 | +#include <linux/workqueue.h> | |
32 | ||
33 | #include <net/ipv6.h> | |
34 | #include <net/if_inet6.h> | |
35 | diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c | |
36 | index 76b2fba5fba2..b7513c5848cf 100644 | |
37 | --- a/drivers/s390/net/qeth_l2_main.c | |
38 | +++ b/drivers/s390/net/qeth_l2_main.c | |
39 | @@ -854,6 +854,8 @@ static void qeth_l2_remove_device(struct ccwgroup_device *cgdev) | |
40 | ||
41 | if (cgdev->state == CCWGROUP_ONLINE) | |
42 | qeth_l2_set_offline(cgdev); | |
43 | + | |
44 | + cancel_work_sync(&card->close_dev_work); | |
45 | if (qeth_netdev_is_registered(card->dev)) | |
46 | unregister_netdev(card->dev); | |
47 | } | |
48 | diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c | |
49 | index b7f6a8384543..7f71ca0d08e7 100644 | |
50 | --- a/drivers/s390/net/qeth_l3_main.c | |
51 | +++ b/drivers/s390/net/qeth_l3_main.c | |
52 | @@ -2611,6 +2611,7 @@ static void qeth_l3_remove_device(struct ccwgroup_device *cgdev) | |
53 | if (cgdev->state == CCWGROUP_ONLINE) | |
54 | qeth_l3_set_offline(cgdev); | |
55 | ||
56 | + cancel_work_sync(&card->close_dev_work); | |
57 | if (qeth_netdev_is_registered(card->dev)) | |
58 | unregister_netdev(card->dev); | |
59 | qeth_l3_clear_ip_htable(card, 0); | |
60 | -- | |
61 | 2.19.1 | |
62 |