]>
Commit | Line | Data |
---|---|---|
3d4ecfe4 SL |
1 | From 5a98b22368ee2b9e010f5ec5d39fa8b44fe82d42 Mon Sep 17 00:00:00 2001 |
2 | From: Piotr Figiel <p.figiel@camlintechnologies.com> | |
3 | Date: Wed, 13 Mar 2019 09:52:01 +0000 | |
4 | Subject: brcmfmac: fix Oops when bringing up interface during USB disconnect | |
5 | ||
6 | [ Upstream commit 24d413a31afaee9bbbf79226052c386b01780ce2 ] | |
7 | ||
8 | Fix a race which leads to an Oops with NULL pointer dereference. The | |
9 | dereference is in brcmf_config_dongle() when cfg_to_ndev() attempts to get | |
10 | net_device structure of interface with index 0 via if2bss mapping. This | |
11 | shouldn't fail because of check for bus being ready in brcmf_netdev_open(), | |
12 | but it's not synchronised with USB disconnect and there is a race: after | |
13 | the check the bus can be marked down and the mapping for interface 0 may be | |
14 | gone. | |
15 | ||
16 | Solve this by modifying disconnect handling so that the removal of mapping | |
17 | of ifidx to brcmf_if structure happens after netdev removal (which is | |
18 | synchronous with brcmf_netdev_open() thanks to rtln being locked in | |
19 | devinet_ioctl()). This assures brcmf_netdev_open() returns before the | |
20 | mapping is removed during disconnect. | |
21 | ||
22 | Unable to handle kernel NULL pointer dereference at virtual address 00000008 | |
23 | pgd = bcae2612 | |
24 | [00000008] *pgd=8be73831 | |
25 | Internal error: Oops: 17 [#1] PREEMPT SMP ARM | |
26 | Modules linked in: brcmfmac brcmutil nf_log_ipv4 nf_log_common xt_LOG xt_limit | |
27 | iptable_mangle xt_connmark xt_tcpudp xt_conntrack nf_conntrack nf_defrag_ipv6 | |
28 | nf_defrag_ipv4 iptable_filter ip_tables x_tables usb_f_mass_storage usb_f_rndis | |
29 | u_ether usb_serial_simple usbserial cdc_acm smsc95xx usbnet ci_hdrc_imx ci_hdrc | |
30 | usbmisc_imx ulpi 8250_exar 8250_pci 8250 8250_base libcomposite configfs | |
31 | udc_core [last unloaded: brcmutil] | |
32 | CPU: 2 PID: 24478 Comm: ifconfig Not tainted 4.19.23-00078-ga62866d-dirty #115 | |
33 | Hardware name: Freescale i.MX6 Quad/DualLite (Device Tree) | |
34 | PC is at brcmf_cfg80211_up+0x94/0x29c [brcmfmac] | |
35 | LR is at brcmf_cfg80211_up+0x8c/0x29c [brcmfmac] | |
36 | pc : [<7f26a91c>] lr : [<7f26a914>] psr: a0070013 | |
37 | sp : eca99d28 ip : 00000000 fp : ee9c6c00 | |
38 | r10: 00000036 r9 : 00000000 r8 : ece4002c | |
39 | r7 : edb5b800 r6 : 00000000 r5 : 80f08448 r4 : edb5b968 | |
40 | r3 : ffffffff r2 : 00000000 r1 : 00000002 r0 : 00000000 | |
41 | Flags: NzCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment none | |
42 | Control: 10c5387d Table: 7ca0c04a DAC: 00000051 | |
43 | Process ifconfig (pid: 24478, stack limit = 0xd9e85a0e) | |
44 | Stack: (0xeca99d28 to 0xeca9a000) | |
45 | 9d20: 00000000 80f873b0 0000000d 80f08448 eca99d68 50d45f32 | |
46 | 9d40: 7f27de94 ece40000 80f08448 80f08448 7f27de94 ece4002c 00000000 00000036 | |
47 | 9d60: ee9c6c00 7f27262c 00001002 50d45f32 ece40000 00000000 80f08448 80772008 | |
48 | 9d80: 00000001 00001043 00001002 ece40000 00000000 50d45f32 ece40000 00000001 | |
49 | 9da0: 80f08448 00001043 00001002 807723d0 00000000 50d45f32 80f08448 eca99e58 | |
50 | 9dc0: 80f87113 50d45f32 80f08448 ece40000 ece40138 00001002 80f08448 00000000 | |
51 | 9de0: 00000000 80772434 edbd5380 eca99e58 edbd5380 80f08448 ee9c6c0c 80805f70 | |
52 | 9e00: 00000000 ede08e00 00008914 ece40000 00000014 ee9c6c0c 600c0013 00001043 | |
53 | 9e20: 0208a8c0 ffffffff 00000000 50d45f32 eca98000 80f08448 7ee9fc38 00008914 | |
54 | 9e40: 80f68e40 00000051 eca98000 00000036 00000003 80808b9c 6e616c77 00000030 | |
55 | 9e60: 00000000 00000000 00001043 0208a8c0 ffffffff 00000000 80f08448 00000000 | |
56 | 9e80: 00000000 816d8b20 600c0013 00000001 ede09320 801763d4 00000000 50d45f32 | |
57 | 9ea0: eca98000 80f08448 7ee9fc38 50d45f32 00008914 80f08448 7ee9fc38 80f68e40 | |
58 | 9ec0: ed531540 8074721c 00000800 00000001 00000000 6e616c77 00000030 00000000 | |
59 | 9ee0: 00000000 00001002 0208a8c0 ffffffff 00000000 50d45f32 80f08448 7ee9fc38 | |
60 | 9f00: ed531560 ec8fc900 80285a6c 80285138 edb910c0 00000000 ecd91008 ede08e00 | |
61 | 9f20: 80f08448 00000000 00000000 816d8b20 600c0013 00000001 ede09320 801763d4 | |
62 | 9f40: 00000000 50d45f32 00021000 edb91118 edb910c0 80f08448 01b29000 edb91118 | |
63 | 9f60: eca99f7c 50d45f32 00021000 ec8fc900 00000003 ec8fc900 00008914 7ee9fc38 | |
64 | 9f80: eca98000 00000036 00000003 80285a6c 00086364 7ee9fe1c 000000c3 00000036 | |
65 | 9fa0: 801011c4 80101000 00086364 7ee9fe1c 00000003 00008914 7ee9fc38 00086364 | |
66 | 9fc0: 00086364 7ee9fe1c 000000c3 00000036 0008630c 7ee9fe1c 7ee9fc38 00000003 | |
67 | 9fe0: 000a42b8 7ee9fbd4 00019914 76e09acc 600c0010 00000003 00000000 00000000 | |
68 | [<7f26a91c>] (brcmf_cfg80211_up [brcmfmac]) from [<7f27262c>] (brcmf_netdev_open+0x74/0xe8 [brcmfmac]) | |
69 | [<7f27262c>] (brcmf_netdev_open [brcmfmac]) from [<80772008>] (__dev_open+0xcc/0x150) | |
70 | [<80772008>] (__dev_open) from [<807723d0>] (__dev_change_flags+0x168/0x1b4) | |
71 | [<807723d0>] (__dev_change_flags) from [<80772434>] (dev_change_flags+0x18/0x48) | |
72 | [<80772434>] (dev_change_flags) from [<80805f70>] (devinet_ioctl+0x67c/0x79c) | |
73 | [<80805f70>] (devinet_ioctl) from [<80808b9c>] (inet_ioctl+0x210/0x3d4) | |
74 | [<80808b9c>] (inet_ioctl) from [<8074721c>] (sock_ioctl+0x350/0x524) | |
75 | [<8074721c>] (sock_ioctl) from [<80285138>] (do_vfs_ioctl+0xb0/0x9b0) | |
76 | [<80285138>] (do_vfs_ioctl) from [<80285a6c>] (ksys_ioctl+0x34/0x5c) | |
77 | [<80285a6c>] (ksys_ioctl) from [<80101000>] (ret_fast_syscall+0x0/0x28) | |
78 | Exception stack(0xeca99fa8 to 0xeca99ff0) | |
79 | 9fa0: 00086364 7ee9fe1c 00000003 00008914 7ee9fc38 00086364 | |
80 | 9fc0: 00086364 7ee9fe1c 000000c3 00000036 0008630c 7ee9fe1c 7ee9fc38 00000003 | |
81 | 9fe0: 000a42b8 7ee9fbd4 00019914 76e09acc | |
82 | Code: e5970328 eb002021 e1a02006 e3a01002 (e5909008) | |
83 | ---[ end trace 5cbac2333f3ac5df ]--- | |
84 | ||
85 | Signed-off-by: Piotr Figiel <p.figiel@camlintechnologies.com> | |
86 | Signed-off-by: Kalle Valo <kvalo@codeaurora.org> | |
87 | Signed-off-by: Sasha Levin <sashal@kernel.org> | |
88 | --- | |
89 | .../net/wireless/broadcom/brcm80211/brcmfmac/core.c | 10 +++++++--- | |
90 | 1 file changed, 7 insertions(+), 3 deletions(-) | |
91 | ||
92 | diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c | |
93 | index 79eacad387048..bfc0e37b7f344 100644 | |
94 | --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c | |
95 | +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c | |
96 | @@ -664,17 +664,17 @@ static void brcmf_del_if(struct brcmf_pub *drvr, s32 bsscfgidx, | |
97 | bool rtnl_locked) | |
98 | { | |
99 | struct brcmf_if *ifp; | |
100 | + int ifidx; | |
101 | ||
102 | ifp = drvr->iflist[bsscfgidx]; | |
103 | - drvr->iflist[bsscfgidx] = NULL; | |
104 | if (!ifp) { | |
105 | brcmf_err("Null interface, bsscfgidx=%d\n", bsscfgidx); | |
106 | return; | |
107 | } | |
108 | brcmf_dbg(TRACE, "Enter, bsscfgidx=%d, ifidx=%d\n", bsscfgidx, | |
109 | ifp->ifidx); | |
110 | - if (drvr->if2bss[ifp->ifidx] == bsscfgidx) | |
111 | - drvr->if2bss[ifp->ifidx] = BRCMF_BSSIDX_INVALID; | |
112 | + ifidx = ifp->ifidx; | |
113 | + | |
114 | if (ifp->ndev) { | |
115 | if (bsscfgidx == 0) { | |
116 | if (ifp->ndev->netdev_ops == &brcmf_netdev_ops_pri) { | |
117 | @@ -702,6 +702,10 @@ static void brcmf_del_if(struct brcmf_pub *drvr, s32 bsscfgidx, | |
118 | brcmf_p2p_ifp_removed(ifp, rtnl_locked); | |
119 | kfree(ifp); | |
120 | } | |
121 | + | |
122 | + drvr->iflist[bsscfgidx] = NULL; | |
123 | + if (drvr->if2bss[ifidx] == bsscfgidx) | |
124 | + drvr->if2bss[ifidx] = BRCMF_BSSIDX_INVALID; | |
125 | } | |
126 | ||
127 | void brcmf_remove_interface(struct brcmf_if *ifp, bool rtnl_locked) | |
128 | -- | |
129 | 2.20.1 | |
130 |