From: Aaron Durbin Date: Sat, 8 Feb 2014 00:25:51 +0000 (-0800) Subject: mwifiex: don't leak DMA command skbuffs X-Git-Tag: v6.6-pxa1908~23545^2~289^2^2~50 X-Git-Url: https://git.dujemihanovic.xyz/?a=commitdiff_plain;h=189b3299fe46c3d3f7555e1c80e8e8691e71faf1;p=linux.git mwifiex: don't leak DMA command skbuffs The current mwifiex pcie driver assumed that it would get its cmdrsp_complete() callback called before another command was sent to unmap the command's skbuff. However, that is not true. The mwifiex_check_ps_cond() will send a sleep command to the card without having adapter->curr_cmd set. Within the workqueue's state machine the adapter's state would be set to allow commands (curr_cmd = NULL && cmd_sent = false) after having receieved the response from the sleep command. The card->cmd_buf would then be overridden with the new command but the first command's skbuff was not unmapped. This leaks mapped skbuffs when a bounce buffer is employed. To rectify this unmap the card->cmd_buf when the response is received from the card instead of waiting for the cmdrsp_complete() callback. Signed-off-by: Aaron Durbin Reviewed-by: Paul Stewart Reviewed-by: Avinash Patil Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- diff --git a/drivers/net/wireless/mwifiex/pcie.c b/drivers/net/wireless/mwifiex/pcie.c index 4e1c6b268f99..d11d4acf0890 100644 --- a/drivers/net/wireless/mwifiex/pcie.c +++ b/drivers/net/wireless/mwifiex/pcie.c @@ -1513,6 +1513,13 @@ static int mwifiex_pcie_process_cmd_complete(struct mwifiex_adapter *adapter) mwifiex_unmap_pci_memory(adapter, skb, PCI_DMA_FROMDEVICE); + /* Unmap the command as a response has been received. */ + if (card->cmd_buf) { + mwifiex_unmap_pci_memory(adapter, card->cmd_buf, + PCI_DMA_TODEVICE); + card->cmd_buf = NULL; + } + pkt_len = *((__le16 *)skb->data); rx_len = le16_to_cpu(pkt_len); skb_trim(skb, rx_len); @@ -1569,7 +1576,6 @@ static int mwifiex_pcie_cmdrsp_complete(struct mwifiex_adapter *adapter, struct sk_buff *skb) { struct pcie_service_card *card = adapter->card; - struct sk_buff *skb_tmp; if (skb) { card->cmdrsp_buf = skb; @@ -1579,12 +1585,6 @@ static int mwifiex_pcie_cmdrsp_complete(struct mwifiex_adapter *adapter, return -1; } - skb_tmp = card->cmd_buf; - if (skb_tmp) { - mwifiex_unmap_pci_memory(adapter, skb_tmp, PCI_DMA_FROMDEVICE); - card->cmd_buf = NULL; - } - return 0; }