From patchwork Tue Jul 28 05:51:01 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mike Looijmans X-Patchwork-Id: 501034 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 22732140D24 for ; Tue, 28 Jul 2015 15:51:45 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754808AbbG1Fv2 (ORCPT ); Tue, 28 Jul 2015 01:51:28 -0400 Received: from atl4mhob12.myregisteredsite.com ([209.17.115.50]:52868 "EHLO atl4mhob12.myregisteredsite.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751597AbbG1Fv1 (ORCPT ); Tue, 28 Jul 2015 01:51:27 -0400 X-Greylist: delayed 86841 seconds by postgrey-1.27 at vger.kernel.org; Tue, 28 Jul 2015 01:51:27 EDT Received: from mailpod.hostingplatform.com ([10.30.71.203]) by atl4mhob12.myregisteredsite.com (8.14.4/8.14.4) with ESMTP id t6S5p5OP002920 for ; Tue, 28 Jul 2015 01:51:05 -0400 Received: (qmail 11853 invoked by uid 0); 28 Jul 2015 05:51:05 -0000 X-TCPREMOTEIP: 88.159.208.100 X-Authenticated-UID: mike@milosoftware.com Received: from unknown (HELO mikebuntu.TOPIC.LOCAL) (mike@milosoftware.com@88.159.208.100) by 0 with ESMTPA; 28 Jul 2015 05:51:05 -0000 From: Mike Looijmans To: linux-wireless@vger.kernel.org Cc: kvalo@codeaurora.org, khoroshilov@ispras.ru, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, Mike Looijmans , stable@vger.kernel.org Subject: [PATCH v2] rsi: Fix failure to load firmware after memory leak fix and fix the leak Date: Tue, 28 Jul 2015 07:51:01 +0200 Message-Id: <1438062661-3173-1-git-send-email-mike.looijmans@topic.nl> X-Mailer: git-send-email 1.9.1 References: <1437975813-3285-1-git-send-email-mike.looijmans@topic.nl> In-Reply-To: <1437975813-3285-1-git-send-email-mike.looijmans@topic.nl> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Fixes commit eae79b4f3e82 ("rsi: fix memory leak in rsi_load_ta_instructions()") which stopped the driver from functioning. Firmware data has been allocated using vmalloc(), resulting in memory that cannot be used for DMA. Hence the firmware was first copied to a buffer allocated with kmalloc() in the original code. This patch reverts the commit and only calls "kfree()" to release the buffer after sending the data. This fixes the memory leak without breaking the driver. Add a comment to the kmemdup() calls to explain why this is done, and abort if memory allocation fails. Tested on a Topic Miami-Florida board which contains the rsi SDIO chip. Also added the same kfree() call to the USB glue driver. This was not tested on actual hardware though, as I only have the SDIO version. Fixes: eae79b4f3e82 ("rsi: fix memory leak in rsi_load_ta_instructions()") Signed-off-by: Mike Looijmans Cc: stable@vger.kernel.org --- v2: Add "Fixes:" header and abbreviate git hashes. Return -ENOMEM if kmemdup() fails. drivers/net/wireless/rsi/rsi_91x_sdio_ops.c | 8 +++++++- drivers/net/wireless/rsi/rsi_91x_usb_ops.c | 4 ++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/rsi/rsi_91x_sdio_ops.c b/drivers/net/wireless/rsi/rsi_91x_sdio_ops.c index b6cc9ff..1c6788a 100644 --- a/drivers/net/wireless/rsi/rsi_91x_sdio_ops.c +++ b/drivers/net/wireless/rsi/rsi_91x_sdio_ops.c @@ -172,6 +172,7 @@ static int rsi_load_ta_instructions(struct rsi_common *common) (struct rsi_91x_sdiodev *)adapter->rsi_dev; u32 len; u32 num_blocks; + const u8 *fw; const struct firmware *fw_entry = NULL; u32 block_size = dev->tx_blk_size; int status = 0; @@ -200,6 +201,10 @@ static int rsi_load_ta_instructions(struct rsi_common *common) return status; } + /* Copy firmware into DMA-accessible memory */ + fw = kmemdup(fw_entry->data, fw_entry->size, GFP_KERNEL); + if (!fw) + return -ENOMEM; len = fw_entry->size; if (len % 4) @@ -210,7 +215,8 @@ static int rsi_load_ta_instructions(struct rsi_common *common) rsi_dbg(INIT_ZONE, "%s: Instruction size:%d\n", __func__, len); rsi_dbg(INIT_ZONE, "%s: num blocks: %d\n", __func__, num_blocks); - status = rsi_copy_to_card(common, fw_entry->data, len, num_blocks); + status = rsi_copy_to_card(common, fw, len, num_blocks); + kfree(fw); release_firmware(fw_entry); return status; } diff --git a/drivers/net/wireless/rsi/rsi_91x_usb_ops.c b/drivers/net/wireless/rsi/rsi_91x_usb_ops.c index 1106ce7..30c2cf7 100644 --- a/drivers/net/wireless/rsi/rsi_91x_usb_ops.c +++ b/drivers/net/wireless/rsi/rsi_91x_usb_ops.c @@ -146,7 +146,10 @@ static int rsi_load_ta_instructions(struct rsi_common *common) return status; } + /* Copy firmware into DMA-accessible memory */ fw = kmemdup(fw_entry->data, fw_entry->size, GFP_KERNEL); + if (!fw) + return -ENOMEM; len = fw_entry->size; if (len % 4) @@ -158,6 +161,7 @@ static int rsi_load_ta_instructions(struct rsi_common *common) rsi_dbg(INIT_ZONE, "%s: num blocks: %d\n", __func__, num_blocks); status = rsi_copy_to_card(common, fw, len, num_blocks); + kfree(fw); release_firmware(fw_entry); return status; }