2
0

327-v5.0-brcmfmac-Fix-out-of-bounds-memory-access-during-fw-l.patch 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. From b72c51a58e6d63ef673ac96b8ab5bc98799c5f7b Mon Sep 17 00:00:00 2001
  2. From: Lyude Paul <[email protected]>
  3. Date: Sat, 24 Nov 2018 17:57:05 -0500
  4. Subject: [PATCH] brcmfmac: Fix out of bounds memory access during fw load
  5. I ended up tracking down some rather nasty issues with f2fs (and other
  6. filesystem modules) constantly crashing on my kernel down to a
  7. combination of out of bounds memory accesses, one of which was coming
  8. from brcmfmac during module load:
  9. [ 30.891382] brcmfmac: brcmf_fw_alloc_request: using brcm/brcmfmac4356-sdio for chip BCM4356/2
  10. [ 30.894437] ==================================================================
  11. [ 30.901581] BUG: KASAN: global-out-of-bounds in brcmf_fw_alloc_request+0x42c/0x480 [brcmfmac]
  12. [ 30.909935] Read of size 1 at addr ffff2000024865df by task kworker/6:2/387
  13. [ 30.916805]
  14. [ 30.918261] CPU: 6 PID: 387 Comm: kworker/6:2 Tainted: G O 4.20.0-rc3Lyude-Test+ #19
  15. [ 30.927251] Hardware name: amlogic khadas-vim2/khadas-vim2, BIOS 2018.07-rc2-armbian 09/11/2018
  16. [ 30.935964] Workqueue: events brcmf_driver_register [brcmfmac]
  17. [ 30.941641] Call trace:
  18. [ 30.944058] dump_backtrace+0x0/0x3e8
  19. [ 30.947676] show_stack+0x14/0x20
  20. [ 30.950968] dump_stack+0x130/0x1c4
  21. [ 30.954406] print_address_description+0x60/0x25c
  22. [ 30.959066] kasan_report+0x1b4/0x368
  23. [ 30.962683] __asan_report_load1_noabort+0x18/0x20
  24. [ 30.967547] brcmf_fw_alloc_request+0x42c/0x480 [brcmfmac]
  25. [ 30.967639] brcmf_sdio_probe+0x163c/0x2050 [brcmfmac]
  26. [ 30.978035] brcmf_ops_sdio_probe+0x598/0xa08 [brcmfmac]
  27. [ 30.983254] sdio_bus_probe+0x190/0x398
  28. [ 30.983270] really_probe+0x2a0/0xa70
  29. [ 30.983296] driver_probe_device+0x1b4/0x2d8
  30. [ 30.994901] __driver_attach+0x200/0x280
  31. [ 30.994914] bus_for_each_dev+0x10c/0x1a8
  32. [ 30.994925] driver_attach+0x38/0x50
  33. [ 30.994935] bus_add_driver+0x330/0x608
  34. [ 30.994953] driver_register+0x140/0x388
  35. [ 31.013965] sdio_register_driver+0x74/0xa0
  36. [ 31.014076] brcmf_sdio_register+0x14/0x60 [brcmfmac]
  37. [ 31.023177] brcmf_driver_register+0xc/0x18 [brcmfmac]
  38. [ 31.023209] process_one_work+0x654/0x1080
  39. [ 31.032266] worker_thread+0x4f0/0x1308
  40. [ 31.032286] kthread+0x2a8/0x320
  41. [ 31.039254] ret_from_fork+0x10/0x1c
  42. [ 31.039269]
  43. [ 31.044226] The buggy address belongs to the variable:
  44. [ 31.044351] brcmf_firmware_path+0x11f/0xfffffffffffd3b40 [brcmfmac]
  45. [ 31.055601]
  46. [ 31.057031] Memory state around the buggy address:
  47. [ 31.061800] ffff200002486480: 04 fa fa fa fa fa fa fa 00 00 00 00 00 00 00 00
  48. [ 31.068983] ffff200002486500: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  49. [ 31.068993] >ffff200002486580: 00 00 00 00 00 00 00 00 fa fa fa fa 00 00 00 00
  50. [ 31.068999] ^
  51. [ 31.069017] ffff200002486600: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  52. [ 31.096521] ffff200002486680: 00 00 00 00 00 00 00 00 00 00 00 00 fa fa fa fa
  53. [ 31.096528] ==================================================================
  54. [ 31.096533] Disabling lock debugging due to kernel taint
  55. It appears that when trying to determine the length of the string in the
  56. alternate firmware path, we make the mistake of not handling the case
  57. where the firmware path is empty correctly. Since strlen(mp_path) can
  58. return 0, we'll end up accessing mp_path[-1] when the firmware_path
  59. isn't provided through the module arguments.
  60. So, fix this by just setting the end char to '\0' by default, and only
  61. changing it if we have a non-zero length. Additionally, use strnlen()
  62. with BRCMF_FW_ALTPATH_LEN instead of strlen() just to be extra safe.
  63. Fixes: 2baa3aaee27f ("brcmfmac: introduce brcmf_fw_alloc_request() function")
  64. Cc: Hante Meuleman <[email protected]>
  65. Cc: Pieter-Paul Giesberts <[email protected]>
  66. Cc: Franky Lin <[email protected]>
  67. Cc: Arend van Spriel <[email protected]>
  68. Cc: Kalle Valo <[email protected]>
  69. Cc: Arend Van Spriel <[email protected]>
  70. Cc: Himanshu Jha <[email protected]>
  71. Cc: Dan Haab <[email protected]>
  72. Cc: Jia-Shyr Chuang <[email protected]>
  73. Cc: Ian Molton <[email protected]>
  74. Cc: <[email protected]> # v4.17+
  75. Signed-off-by: Lyude Paul <[email protected]>
  76. Signed-off-by: Kalle Valo <[email protected]>
  77. ---
  78. .../net/wireless/broadcom/brcm80211/brcmfmac/firmware.c | 8 ++++++--
  79. 1 file changed, 6 insertions(+), 2 deletions(-)
  80. --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c
  81. +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c
  82. @@ -708,8 +708,9 @@ brcmf_fw_alloc_request(u32 chip, u32 chi
  83. struct brcmf_fw_request *fwreq;
  84. char chipname[12];
  85. const char *mp_path;
  86. + size_t mp_path_len;
  87. u32 i, j;
  88. - char end;
  89. + char end = '\0';
  90. size_t reqsz;
  91. for (i = 0; i < table_size; i++) {
  92. @@ -734,7 +735,10 @@ brcmf_fw_alloc_request(u32 chip, u32 chi
  93. mapping_table[i].fw_base, chipname);
  94. mp_path = brcmf_mp_global.firmware_path;
  95. - end = mp_path[strlen(mp_path) - 1];
  96. + mp_path_len = strnlen(mp_path, BRCMF_FW_ALTPATH_LEN);
  97. + if (mp_path_len)
  98. + end = mp_path[mp_path_len - 1];
  99. +
  100. fwreq->n_items = n_fwnames;
  101. for (j = 0; j < n_fwnames; j++) {