lkml.org 
[lkml]   [2015]   [Sep]   [11]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.1 08/78] rsi: Fix failure to load firmware after memory leak fix and fix the leak
    Date
    4.1-stable review patch.  If anyone has any objections, please let me know.

    ------------------

    From: Mike Looijmans <mike.looijmans@topic.nl>

    commit 5d5cd85ff441534a52f23f821d0a7c644d3b6cce upstream.

    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 <mike.looijmans@topic.nl>
    Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    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(-)

    --- 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(stru
    (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(stru
    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(stru
    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;
    }
    --- 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(stru
    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(stru
    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;
    }



    \
     
     \ /
      Last update: 2015-09-12 01:21    [W:4.786 / U:0.024 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site