浏览代码

brcmfmac: fix memory leakage in msgbuf

The kbuild robot came up with the following warning:

tree:   .../kernel/git/linville/wireless-next.git master
head:   dc6be9f54a4ecb0a09765d1f515ed947d86b7528
commit: 9a1bb60250d2b6b546a62e5b73f55c4f1d22016b
	 [5/13] brcmfmac: Adding msgbuf protocol.

coccinelle warnings:
 drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c:1309:1-28:
   alloc with no test, possible model on line 1318

Looking into the issue, it turned out that the referred allocation
buffer was not being released in failure path nor upon module
unload.

Reported-by: Fengguang Wu <fengguang.wu@intel.com>
Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com>
Reviewed-by: Daniel (Deognyoun) Kim <dekim@broadcom.com>
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Arend van Spriel 11 年之前
父节点
当前提交
2d116b8849
共有 1 个文件被更改,包括 4 次插入0 次删除
  1. 4 0
      drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c

+ 4 - 0
drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c

@@ -1318,6 +1318,8 @@ int brcmf_proto_msgbuf_attach(struct brcmf_pub *drvr)
 	msgbuf->nrof_flowrings = if_msgbuf->nrof_flowrings;
 	msgbuf->nrof_flowrings = if_msgbuf->nrof_flowrings;
 	msgbuf->flowring_dma_handle = kzalloc(msgbuf->nrof_flowrings *
 	msgbuf->flowring_dma_handle = kzalloc(msgbuf->nrof_flowrings *
 		sizeof(*msgbuf->flowring_dma_handle), GFP_ATOMIC);
 		sizeof(*msgbuf->flowring_dma_handle), GFP_ATOMIC);
+	if (!msgbuf->flowring_dma_handle)
+		goto fail;
 
 
 	msgbuf->rx_dataoffset = if_msgbuf->rx_dataoffset;
 	msgbuf->rx_dataoffset = if_msgbuf->rx_dataoffset;
 	msgbuf->max_rxbufpost = if_msgbuf->max_rxbufpost;
 	msgbuf->max_rxbufpost = if_msgbuf->max_rxbufpost;
@@ -1362,6 +1364,7 @@ fail:
 		kfree(msgbuf->flow_map);
 		kfree(msgbuf->flow_map);
 		kfree(msgbuf->txstatus_done_map);
 		kfree(msgbuf->txstatus_done_map);
 		brcmf_msgbuf_release_pktids(msgbuf);
 		brcmf_msgbuf_release_pktids(msgbuf);
+		kfree(msgbuf->flowring_dma_handle);
 		if (msgbuf->ioctbuf)
 		if (msgbuf->ioctbuf)
 			dma_free_coherent(drvr->bus_if->dev,
 			dma_free_coherent(drvr->bus_if->dev,
 					  BRCMF_TX_IOCTL_MAX_MSG_SIZE,
 					  BRCMF_TX_IOCTL_MAX_MSG_SIZE,
@@ -1391,6 +1394,7 @@ void brcmf_proto_msgbuf_detach(struct brcmf_pub *drvr)
 				  BRCMF_TX_IOCTL_MAX_MSG_SIZE,
 				  BRCMF_TX_IOCTL_MAX_MSG_SIZE,
 				  msgbuf->ioctbuf, msgbuf->ioctbuf_handle);
 				  msgbuf->ioctbuf, msgbuf->ioctbuf_handle);
 		brcmf_msgbuf_release_pktids(msgbuf);
 		brcmf_msgbuf_release_pktids(msgbuf);
+		kfree(msgbuf->flowring_dma_handle);
 		kfree(msgbuf);
 		kfree(msgbuf);
 		drvr->proto->pd = NULL;
 		drvr->proto->pd = NULL;
 	}
 	}