1. 20 Apr, 2017 6 commits
    • Brian Norris's avatar
      mwifiex: pcie: fix cmd_buf use-after-free in remove/reset · 3c8cb9ad
      Brian Norris authored
      Command buffers (skb's) are allocated by the main driver, and freed upon
      the last use. That last use is often in mwifiex_free_cmd_buffer(). In
      the meantime, if the command buffer gets used by the PCI driver, we map
      it as DMA-able, and store the mapping information in the 'cb' memory.
      
      However, if a command was in-flight when resetting the device (and
      therefore was still mapped), we don't get a chance to unmap this memory
      until after the core has cleaned up its command handling.
      
      Let's keep a refcount within the PCI driver, so we ensure the memory
      only gets freed after we've finished unmapping it.
      
      Noticed by KASAN when forcing a reset via:
      
        echo 1 > /sys/bus/pci/.../reset
      
      The same code path can presumably be exercised in remove() and
      shutdown().
      
      [  205.390377] mwifiex_pcie 0000:01:00.0: info: shutdown mwifiex...
      [  205.400393] ==================================================================
      [  205.407719] BUG: KASAN: use-after-free in mwifiex_unmap_pci_memory.isra.14+0x4c/0x100 [mwifiex_pcie] at addr ffffffc0ad471b28
      [  205.419040] Read of size 16 by task bash/1913
      [  205.423421] =============================================================================
      [  205.431625] BUG skbuff_head_cache (Tainted: G    B          ): kasan: bad access detected
      [  205.439815] -----------------------------------------------------------------------------
      [  205.439815]
      [  205.449534] INFO: Allocated in __build_skb+0x48/0x114 age=1311 cpu=4 pid=1913
      [  205.456709] 	alloc_debug_processing+0x124/0x178
      [  205.461282] 	___slab_alloc.constprop.58+0x528/0x608
      [  205.466196] 	__slab_alloc.isra.54.constprop.57+0x44/0x54
      [  205.471542] 	kmem_cache_alloc+0xcc/0x278
      [  205.475497] 	__build_skb+0x48/0x114
      [  205.479019] 	__netdev_alloc_skb+0xe0/0x170
      [  205.483244] 	mwifiex_alloc_cmd_buffer+0x68/0xdc [mwifiex]
      [  205.488759] 	mwifiex_init_fw+0x40/0x6cc [mwifiex]
      [  205.493584] 	_mwifiex_fw_dpc+0x158/0x520 [mwifiex]
      [  205.498491] 	mwifiex_reinit_sw+0x2c4/0x398 [mwifiex]
      [  205.503510] 	mwifiex_pcie_reset_notify+0x114/0x15c [mwifiex_pcie]
      [  205.509643] 	pci_reset_notify+0x5c/0x6c
      [  205.513519] 	pci_reset_function+0x6c/0x7c
      [  205.517567] 	reset_store+0x68/0x98
      [  205.521003] 	dev_attr_store+0x54/0x60
      [  205.524705] 	sysfs_kf_write+0x9c/0xb0
      [  205.528413] INFO: Freed in __kfree_skb+0xb0/0xbc age=131 cpu=4 pid=1913
      [  205.535064] 	free_debug_processing+0x264/0x370
      [  205.539550] 	__slab_free+0x84/0x40c
      [  205.543075] 	kmem_cache_free+0x1c8/0x2a0
      [  205.547030] 	__kfree_skb+0xb0/0xbc
      [  205.550465] 	consume_skb+0x164/0x178
      [  205.554079] 	__dev_kfree_skb_any+0x58/0x64
      [  205.558304] 	mwifiex_free_cmd_buffer+0xa0/0x158 [mwifiex]
      [  205.563817] 	mwifiex_shutdown_drv+0x578/0x5c4 [mwifiex]
      [  205.569164] 	mwifiex_shutdown_sw+0x178/0x310 [mwifiex]
      [  205.574353] 	mwifiex_pcie_reset_notify+0xd4/0x15c [mwifiex_pcie]
      [  205.580398] 	pci_reset_notify+0x5c/0x6c
      [  205.584274] 	pci_dev_save_and_disable+0x24/0x6c
      [  205.588837] 	pci_reset_function+0x30/0x7c
      [  205.592885] 	reset_store+0x68/0x98
      [  205.596324] 	dev_attr_store+0x54/0x60
      [  205.600017] 	sysfs_kf_write+0x9c/0xb0
      ...
      [  205.800488] Call trace:
      [  205.802980] [<ffffffc00020a69c>] dump_backtrace+0x0/0x190
      [  205.808415] [<ffffffc00020a96c>] show_stack+0x20/0x28
      [  205.813506] [<ffffffc0005d020c>] dump_stack+0xa4/0xcc
      [  205.818598] [<ffffffc0003be44c>] print_trailer+0x158/0x168
      [  205.824120] [<ffffffc0003be5f0>] object_err+0x4c/0x5c
      [  205.829210] [<ffffffc0003c45bc>] kasan_report+0x334/0x500
      [  205.834641] [<ffffffc0003c3994>] check_memory_region+0x20/0x14c
      [  205.840593] [<ffffffc0003c3b14>] __asan_loadN+0x14/0x1c
      [  205.845879] [<ffffffbffc46171c>] mwifiex_unmap_pci_memory.isra.14+0x4c/0x100 [mwifiex_pcie]
      [  205.854282] [<ffffffbffc461864>] mwifiex_pcie_delete_cmdrsp_buf+0x94/0xa8 [mwifiex_pcie]
      [  205.862421] [<ffffffbffc462028>] mwifiex_pcie_free_buffers+0x11c/0x158 [mwifiex_pcie]
      [  205.870302] [<ffffffbffc4620d4>] mwifiex_pcie_down_dev+0x70/0x80 [mwifiex_pcie]
      [  205.877736] [<ffffffbffc1397a8>] mwifiex_shutdown_sw+0x190/0x310 [mwifiex]
      [  205.884658] [<ffffffbffc4606b4>] mwifiex_pcie_reset_notify+0xd4/0x15c [mwifiex_pcie]
      [  205.892446] [<ffffffc000635f54>] pci_reset_notify+0x5c/0x6c
      [  205.898048] [<ffffffc00063a044>] pci_dev_save_and_disable+0x24/0x6c
      [  205.904350] [<ffffffc00063cf0c>] pci_reset_function+0x30/0x7c
      [  205.910134] [<ffffffc000641118>] reset_store+0x68/0x98
      [  205.915312] [<ffffffc000771588>] dev_attr_store+0x54/0x60
      [  205.920750] [<ffffffc00046f53c>] sysfs_kf_write+0x9c/0xb0
      [  205.926182] [<ffffffc00046dfb0>] kernfs_fop_write+0x184/0x1f8
      [  205.931963] [<ffffffc0003d64f4>] __vfs_write+0x6c/0x17c
      [  205.937221] [<ffffffc0003d7164>] vfs_write+0xf0/0x1c4
      [  205.942310] [<ffffffc0003d7da0>] SyS_write+0x78/0xd8
      [  205.947312] [<ffffffc000204634>] el0_svc_naked+0x24/0x28
      ...
      [  205.998268] ==================================================================
      
      This bug has been around in different forms for a while. It was sort of
      noticed in commit 955ab095 ("mwifiex: Do not kfree cmd buf while
      unregistering PCIe"), but it just fixed the double-free, without
      acknowledging the potential for use-after-free.
      
      Fixes: fc331460 ("mwifiex: use pci_alloc/free_consistent APIs for PCIe")
      Cc: <stable@vger.kernel.org>
      Signed-off-by: default avatarBrian Norris <briannorris@chromium.org>
      Signed-off-by: default avatarKalle Valo <kvalo@codeaurora.org>
      3c8cb9ad
    • Xinming Hu's avatar
      mwifiex: pcie: extract wifi part from combo firmware during function level reset · efde6648
      Xinming Hu authored
      A separate wifi-only firmware was download during pcie function level
      reset. It is in fact the tail part of wifi/bt combo firmware. Per
      Brian's and Dmitry's suggestion, this patch extract the wifi part from
      combo firmware.
      
      After that, the mrvl/pcie8997_wlan_v4.bin image in linux-firmware repo
      is redundant (though I guess we keep it around to support older
      kernels).
      Signed-off-by: default avatarXinming Hu <huxm@marvell.com>
      Signed-off-by: default avatarGanapathi Bhat <gbhat@marvell.com>
      Signed-off-by: default avatarCathy Luo <cluo@marvell.com>
      Signed-off-by: default avatarBrian Norris <briannorris@chromium.org>
      Signed-off-by: default avatarKalle Valo <kvalo@codeaurora.org>
      efde6648
    • Xinming Hu's avatar
      mwifiex: pcie: correct scratch register name · 127ee1db
      Xinming Hu authored
      This patch correct pcie scratch register name, to keep the same with
      chipset side definition.
      Signed-off-by: default avatarXinming Hu <huxm@marvell.com>
      Signed-off-by: default avatarKalle Valo <kvalo@codeaurora.org>
      127ee1db
    • Xinming Hu's avatar
      mwifiex: fall back mwifiex_dbg to pr_info when adapter->dev not set · ef6c7d3c
      Xinming Hu authored
      mwifiex_dbg will do nothing before adapter->dev get assigned. several logs
      lost in this case. it can be avoided by fall back to pr_info.
      Signed-off-by: default avatarXinming Hu <huxm@marvell.com>
      Reviewed-by: default avatarBrian Norris <briannorris@chromium.org>
      Reviewed-by: default avatarDmitry Torokhov <dtor@chromium.org>
      Signed-off-by: default avatarKalle Valo <kvalo@codeaurora.org>
      ef6c7d3c
    • Xinming Hu's avatar
      mwifiex: remove unnecessary wakeup interrupt number sanity check · 625b4dba
      Xinming Hu authored
      If wakeup interrupt handler is called, we know that the wakeup
      interrupt number is valid, there is no need to check it.
      Signed-off-by: default avatarXinming Hu <huxm@marvell.com>
      Signed-off-by: default avatarCathy Luo <cluo@marvell.com>
      Reviewed-by: default avatarDmitry Torokhov <dtor@chromium.org>
      Reviewed-by: default avatarBrian Norris <briannorris@chromium.org>
      Signed-off-by: default avatarKalle Valo <kvalo@codeaurora.org>
      625b4dba
    • Brian Norris's avatar
      mwifiex: MAC randomization should not be persistent · 7e2f18f0
      Brian Norris authored
      nl80211 provides the NL80211_SCAN_FLAG_RANDOM_ADDR for every scan
      request that should be randomized; the absence of such a flag means we
      should not randomize. However, mwifiex was stashing the latest
      randomization request and *always* using it for future scans, even those
      that didn't set the flag.
      
      Let's zero out the randomization info whenever we get a scan request
      without NL80211_SCAN_FLAG_RANDOM_ADDR. I'd prefer to remove
      priv->random_mac entirely (and plumb the randomization MAC properly
      through the call sequence), but the spaghetti is a little difficult to
      unravel here for me.
      
      Fixes: c2a8f0ff ("mwifiex: support random MAC address for scanning")
      Cc: <stable@vger.kernel.org> # 4.9+
      Signed-off-by: default avatarBrian Norris <briannorris@chromium.org>
      Signed-off-by: default avatarKalle Valo <kvalo@codeaurora.org>
      7e2f18f0
  2. 19 Apr, 2017 1 commit
  3. 18 Apr, 2017 1 commit
  4. 13 Apr, 2017 32 commits