]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blame - releases/5.0.8/net-thunderx-fix-null-pointer-dereference-in-nicvf_o.patch
Linux 5.0.8
[thirdparty/kernel/stable-queue.git] / releases / 5.0.8 / net-thunderx-fix-null-pointer-dereference-in-nicvf_o.patch
CommitLineData
6b6035bf
SL
1From f1c8daba109e2244a780a2a0c1ca23780ef7616c Mon Sep 17 00:00:00 2001
2From: Lorenzo Bianconi <lorenzo.bianconi@redhat.com>
3Date: Thu, 4 Apr 2019 12:16:27 +0200
4Subject: net: thunderx: fix NULL pointer dereference in nicvf_open/nicvf_stop
5
6[ Upstream commit 2ec1ed2aa68782b342458681aa4d16b65c9014d6 ]
7
8When a bpf program is uploaded, the driver computes the number of
9xdp tx queues resulting in the allocation of additional qsets.
10Starting from commit '2ecbe4f4a027 ("net: thunderx: replace global
11nicvf_rx_mode_wq work queue for all VFs to private for each of them")'
12the driver runs link state polling for each VF resulting in the
13following NULL pointer dereference:
14
15[ 56.169256] Unable to handle kernel NULL pointer dereference at virtual address 0000000000000020
16[ 56.178032] Mem abort info:
17[ 56.180834] ESR = 0x96000005
18[ 56.183877] Exception class = DABT (current EL), IL = 32 bits
19[ 56.189792] SET = 0, FnV = 0
20[ 56.192834] EA = 0, S1PTW = 0
21[ 56.195963] Data abort info:
22[ 56.198831] ISV = 0, ISS = 0x00000005
23[ 56.202662] CM = 0, WnR = 0
24[ 56.205619] user pgtable: 64k pages, 48-bit VAs, pgdp = 0000000021f0c7a0
25[ 56.212315] [0000000000000020] pgd=0000000000000000, pud=0000000000000000
26[ 56.219094] Internal error: Oops: 96000005 [#1] SMP
27[ 56.260459] CPU: 39 PID: 2034 Comm: ip Not tainted 5.1.0-rc3+ #3
28[ 56.266452] Hardware name: GIGABYTE R120-T33/MT30-GS1, BIOS T49 02/02/2018
29[ 56.273315] pstate: 80000005 (Nzcv daif -PAN -UAO)
30[ 56.278098] pc : __ll_sc___cmpxchg_case_acq_64+0x4/0x20
31[ 56.283312] lr : mutex_lock+0x2c/0x50
32[ 56.286962] sp : ffff0000219af1b0
33[ 56.290264] x29: ffff0000219af1b0 x28: ffff800f64de49a0
34[ 56.295565] x27: 0000000000000000 x26: 0000000000000015
35[ 56.300865] x25: 0000000000000000 x24: 0000000000000000
36[ 56.306165] x23: 0000000000000000 x22: ffff000011117000
37[ 56.311465] x21: ffff800f64dfc080 x20: 0000000000000020
38[ 56.316766] x19: 0000000000000020 x18: 0000000000000001
39[ 56.322066] x17: 0000000000000000 x16: ffff800f2e077080
40[ 56.327367] x15: 0000000000000004 x14: 0000000000000000
41[ 56.332667] x13: ffff000010964438 x12: 0000000000000002
42[ 56.337967] x11: 0000000000000000 x10: 0000000000000c70
43[ 56.343268] x9 : ffff0000219af120 x8 : ffff800f2e077d50
44[ 56.348568] x7 : 0000000000000027 x6 : 000000062a9d6a84
45[ 56.353869] x5 : 0000000000000000 x4 : ffff800f2e077480
46[ 56.359169] x3 : 0000000000000008 x2 : ffff800f2e077080
47[ 56.364469] x1 : 0000000000000000 x0 : 0000000000000020
48[ 56.369770] Process ip (pid: 2034, stack limit = 0x00000000c862da3a)
49[ 56.376110] Call trace:
50[ 56.378546] __ll_sc___cmpxchg_case_acq_64+0x4/0x20
51[ 56.383414] drain_workqueue+0x34/0x198
52[ 56.387247] nicvf_open+0x48/0x9e8 [nicvf]
53[ 56.391334] nicvf_open+0x898/0x9e8 [nicvf]
54[ 56.395507] nicvf_xdp+0x1bc/0x238 [nicvf]
55[ 56.399595] dev_xdp_install+0x68/0x90
56[ 56.403333] dev_change_xdp_fd+0xc8/0x240
57[ 56.407333] do_setlink+0x8e0/0xbe8
58[ 56.410810] __rtnl_newlink+0x5b8/0x6d8
59[ 56.414634] rtnl_newlink+0x54/0x80
60[ 56.418112] rtnetlink_rcv_msg+0x22c/0x2f8
61[ 56.422199] netlink_rcv_skb+0x60/0x120
62[ 56.426023] rtnetlink_rcv+0x28/0x38
63[ 56.429587] netlink_unicast+0x1c8/0x258
64[ 56.433498] netlink_sendmsg+0x1b4/0x350
65[ 56.437410] sock_sendmsg+0x4c/0x68
66[ 56.440887] ___sys_sendmsg+0x240/0x280
67[ 56.444711] __sys_sendmsg+0x68/0xb0
68[ 56.448275] __arm64_sys_sendmsg+0x2c/0x38
69[ 56.452361] el0_svc_handler+0x9c/0x128
70[ 56.456186] el0_svc+0x8/0xc
71[ 56.459056] Code: 35ffff91 2a1003e0 d65f03c0 f9800011 (c85ffc10)
72[ 56.465166] ---[ end trace 4a57fdc27b0a572c ]---
73[ 56.469772] Kernel panic - not syncing: Fatal exception
74
75Fix it by checking nicvf_rx_mode_wq pointer in nicvf_open and nicvf_stop
76
77Fixes: 2ecbe4f4a027 ("net: thunderx: replace global nicvf_rx_mode_wq work queue for all VFs to private for each of them")
78Fixes: 2c632ad8bc74 ("net: thunderx: move link state polling function to VF")
79Reported-by: Matteo Croce <mcroce@redhat.com>
80Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi@redhat.com>
81Tested-by: Matteo Croce <mcroce@redhat.com>
82Signed-off-by: David S. Miller <davem@davemloft.net>
83Signed-off-by: Sasha Levin <sashal@kernel.org>
84---
85 .../net/ethernet/cavium/thunder/nicvf_main.c | 20 +++++++++++--------
86 1 file changed, 12 insertions(+), 8 deletions(-)
87
88diff --git a/drivers/net/ethernet/cavium/thunder/nicvf_main.c b/drivers/net/ethernet/cavium/thunder/nicvf_main.c
89index 503cfadff4ac..d4ee9f9c8c34 100644
90--- a/drivers/net/ethernet/cavium/thunder/nicvf_main.c
91+++ b/drivers/net/ethernet/cavium/thunder/nicvf_main.c
92@@ -1328,10 +1328,11 @@ int nicvf_stop(struct net_device *netdev)
93 struct nicvf_cq_poll *cq_poll = NULL;
94 union nic_mbx mbx = {};
95
96- cancel_delayed_work_sync(&nic->link_change_work);
97-
98 /* wait till all queued set_rx_mode tasks completes */
99- drain_workqueue(nic->nicvf_rx_mode_wq);
100+ if (nic->nicvf_rx_mode_wq) {
101+ cancel_delayed_work_sync(&nic->link_change_work);
102+ drain_workqueue(nic->nicvf_rx_mode_wq);
103+ }
104
105 mbx.msg.msg = NIC_MBOX_MSG_SHUTDOWN;
106 nicvf_send_msg_to_pf(nic, &mbx);
107@@ -1452,7 +1453,8 @@ int nicvf_open(struct net_device *netdev)
108 struct nicvf_cq_poll *cq_poll = NULL;
109
110 /* wait till all queued set_rx_mode tasks completes if any */
111- drain_workqueue(nic->nicvf_rx_mode_wq);
112+ if (nic->nicvf_rx_mode_wq)
113+ drain_workqueue(nic->nicvf_rx_mode_wq);
114
115 netif_carrier_off(netdev);
116
117@@ -1550,10 +1552,12 @@ int nicvf_open(struct net_device *netdev)
118 /* Send VF config done msg to PF */
119 nicvf_send_cfg_done(nic);
120
121- INIT_DELAYED_WORK(&nic->link_change_work,
122- nicvf_link_status_check_task);
123- queue_delayed_work(nic->nicvf_rx_mode_wq,
124- &nic->link_change_work, 0);
125+ if (nic->nicvf_rx_mode_wq) {
126+ INIT_DELAYED_WORK(&nic->link_change_work,
127+ nicvf_link_status_check_task);
128+ queue_delayed_work(nic->nicvf_rx_mode_wq,
129+ &nic->link_change_work, 0);
130+ }
131
132 return 0;
133 cleanup:
134--
1352.19.1
136