linux/drivers/net/wireless
Lyude Paul 33b2f66c27 brcmfmac: Fix out of bounds memory access during fw load
commit b72c51a58e upstream.

I ended up tracking down some rather nasty issues with f2fs (and other
filesystem modules) constantly crashing on my kernel down to a
combination of out of bounds memory accesses, one of which was coming
from brcmfmac during module load:

[   30.891382] brcmfmac: brcmf_fw_alloc_request: using brcm/brcmfmac4356-sdio for chip BCM4356/2
[   30.894437] ==================================================================
[   30.901581] BUG: KASAN: global-out-of-bounds in brcmf_fw_alloc_request+0x42c/0x480 [brcmfmac]
[   30.909935] Read of size 1 at addr ffff2000024865df by task kworker/6:2/387
[   30.916805]
[   30.918261] CPU: 6 PID: 387 Comm: kworker/6:2 Tainted: G           O      4.20.0-rc3Lyude-Test+ #19
[   30.927251] Hardware name: amlogic khadas-vim2/khadas-vim2, BIOS 2018.07-rc2-armbian 09/11/2018
[   30.935964] Workqueue: events brcmf_driver_register [brcmfmac]
[   30.941641] Call trace:
[   30.944058]  dump_backtrace+0x0/0x3e8
[   30.947676]  show_stack+0x14/0x20
[   30.950968]  dump_stack+0x130/0x1c4
[   30.954406]  print_address_description+0x60/0x25c
[   30.959066]  kasan_report+0x1b4/0x368
[   30.962683]  __asan_report_load1_noabort+0x18/0x20
[   30.967547]  brcmf_fw_alloc_request+0x42c/0x480 [brcmfmac]
[   30.967639]  brcmf_sdio_probe+0x163c/0x2050 [brcmfmac]
[   30.978035]  brcmf_ops_sdio_probe+0x598/0xa08 [brcmfmac]
[   30.983254]  sdio_bus_probe+0x190/0x398
[   30.983270]  really_probe+0x2a0/0xa70
[   30.983296]  driver_probe_device+0x1b4/0x2d8
[   30.994901]  __driver_attach+0x200/0x280
[   30.994914]  bus_for_each_dev+0x10c/0x1a8
[   30.994925]  driver_attach+0x38/0x50
[   30.994935]  bus_add_driver+0x330/0x608
[   30.994953]  driver_register+0x140/0x388
[   31.013965]  sdio_register_driver+0x74/0xa0
[   31.014076]  brcmf_sdio_register+0x14/0x60 [brcmfmac]
[   31.023177]  brcmf_driver_register+0xc/0x18 [brcmfmac]
[   31.023209]  process_one_work+0x654/0x1080
[   31.032266]  worker_thread+0x4f0/0x1308
[   31.032286]  kthread+0x2a8/0x320
[   31.039254]  ret_from_fork+0x10/0x1c
[   31.039269]
[   31.044226] The buggy address belongs to the variable:
[   31.044351]  brcmf_firmware_path+0x11f/0xfffffffffffd3b40 [brcmfmac]
[   31.055601]
[   31.057031] Memory state around the buggy address:
[   31.061800]  ffff200002486480: 04 fa fa fa fa fa fa fa 00 00 00 00 00 00 00 00
[   31.068983]  ffff200002486500: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[   31.068993] >ffff200002486580: 00 00 00 00 00 00 00 00 fa fa fa fa 00 00 00 00
[   31.068999]                                                     ^
[   31.069017]  ffff200002486600: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[   31.096521]  ffff200002486680: 00 00 00 00 00 00 00 00 00 00 00 00 fa fa fa fa
[   31.096528] ==================================================================
[   31.096533] Disabling lock debugging due to kernel taint

It appears that when trying to determine the length of the string in the
alternate firmware path, we make the mistake of not handling the case
where the firmware path is empty correctly. Since strlen(mp_path) can
return 0, we'll end up accessing mp_path[-1] when the firmware_path
isn't provided through the module arguments.

So, fix this by just setting the end char to '\0' by default, and only
changing it if we have a non-zero length. Additionally, use strnlen()
with BRCMF_FW_ALTPATH_LEN instead of strlen() just to be extra safe.

Fixes: 2baa3aaee2 ("brcmfmac: introduce brcmf_fw_alloc_request() function")
Cc: Hante Meuleman <hante.meuleman@broadcom.com>
Cc: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com>
Cc: Franky Lin <franky.lin@broadcom.com>
Cc: Arend van Spriel <arend.vanspriel@broadcom.com>
Cc: Kalle Valo <kvalo@codeaurora.org>
Cc: Arend Van Spriel <arend.vanspriel@broadcom.com>
Cc: Himanshu Jha <himanshujha199640@gmail.com>
Cc: Dan Haab <dhaab@luxul.com>
Cc: Jia-Shyr Chuang <saint.chuang@cypress.com>
Cc: Ian Molton <ian@mnementh.co.uk>
Cc: <stable@vger.kernel.org> # v4.17+
Signed-off-by: Lyude Paul <lyude@redhat.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
History 2019-01-09 17:46:00 +01:00
..
admtek net/wireless: fix spaces and grammar copy/paste in vendor Kconfig help text 2018-03-13 18:52:25 +02:00
ath ath10k: skip sending quiet mode cmd for WCN3990 2018-12-19 15:37:01 +02:00
atmel atmel: Replace mdelay() with msleep() in probe_atmel_card() 2018-07-31 10:25:33 +03:00
broadcom brcmfmac: Fix out of bounds memory access during fw load 2019-01-09 17:46:00 +01:00
cisco airo: remove unused variables len and dev and clean up formatting 2018-07-31 10:17:19 +03:00
intel iwlwifi: add new cards for 9560, 9462, 9461 and killer series 2019-01-09 17:45:49 +01:00
intersil wireless-drivers-next patches for 4.20 2018-10-02 11:46:29 -07:00
marvell Revert "mwifiex: restructure rx_reorder_tbl_lock usage" 2018-12-13 15:53:27 +02:00
mediatek mt76: fix potential NULL pointer dereference in mt76_stop_tx_queues 2018-12-13 16:19:56 +02:00
quantenna qtnfmac_pcie: cleanup Pearl platform headers 2018-10-13 20:04:48 +03:00
ralink rt2800: flush and txstatus rework for rt2800mmio 2018-10-01 18:37:35 +03:00
realtek rtlwifi: Fix leak of skb when processing C2H_BT_INFO 2018-12-13 15:35:07 +02:00
rsi rsi: Remove unnecessary boolean condition 2018-10-01 18:31:10 +03:00
st cw1200: Remove extra parentheses 2018-08-31 18:42:25 +03:00
ti wlcore: Fixup "Add support for optional wakeirq" 2018-11-06 18:44:36 +02:00
zydas zd1211rw: Replace spin_is_locked() with lockdep 2018-10-05 11:35:05 +03:00
Kconfig qtnfmac: introduce new FullMAC driver for Quantenna chipsets 2017-05-24 17:04:13 +03:00
mac80211_hwsim.c mac80211_hwsim: Timer should be initialized before device registered 2018-11-09 08:55:32 +01:00
mac80211_hwsim.h mac80211_hwsim: add permanent mac address option for new radios 2018-01-31 12:45:35 +01:00
Makefile License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
ray_cs.c ray_cs: remove redundant pointer 'p' 2018-07-31 10:19:50 +03:00
ray_cs.h License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
rayctl.h License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
rndis_wlan.c wireless-drivers: use BIT_ULL for NL80211_STA_INFO_ attribute types 2018-06-27 19:07:39 +03:00
wl3501.h License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
wl3501_cs.c wl3501_cs: fix spelling mistake: "Insupported" -> "Unsupported" 2017-07-28 18:06:31 +03:00