diff options
author | Ioana Radulescu <ruxandra.radulescu@nxp.com> | 2018-03-14 23:04:51 +0300 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2018-03-19 21:46:51 +0300 |
commit | 6a9bbe53db9a5aa0be9788aa8a2c250dee55444b (patch) | |
tree | 20024210f9204505e18f14a0f4c8b4fc315178a3 /drivers/staging/fsl-dpaa2 | |
parent | bcb4f0d75bde920a3e86eeea743c6002863455fb (diff) | |
download | linux-6a9bbe53db9a5aa0be9788aa8a2c250dee55444b.tar.xz |
staging: fsl-dpaa2/eth: Fix incorrect kfree
Use netdev_alloc_frag() instead of kmalloc to allocate space for
the S/G table of egress multi-buffer frames.
This fixes a bug where an unaligned pointer received from the
allocator would be overwritten with the 64B aligned value,
leading to a wrong address being later passed to kfree.
Signed-off-by: Ioana Radulescu <ruxandra.radulescu@nxp.com>
Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/staging/fsl-dpaa2')
-rw-r--r-- | drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.c | 10 |
1 files changed, 6 insertions, 4 deletions
diff --git a/drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.c b/drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.c index c81a01f62fca..f013af61c447 100644 --- a/drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.c +++ b/drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.c @@ -374,12 +374,14 @@ static int build_sg_fd(struct dpaa2_eth_priv *priv, /* Prepare the HW SGT structure */ sgt_buf_size = priv->tx_data_offset + sizeof(struct dpaa2_sg_entry) * (1 + num_dma_bufs); - sgt_buf = kzalloc(sgt_buf_size + DPAA2_ETH_TX_BUF_ALIGN, GFP_ATOMIC); + sgt_buf = netdev_alloc_frag(sgt_buf_size + DPAA2_ETH_TX_BUF_ALIGN); if (unlikely(!sgt_buf)) { err = -ENOMEM; goto sgt_buf_alloc_failed; } sgt_buf = PTR_ALIGN(sgt_buf, DPAA2_ETH_TX_BUF_ALIGN); + memset(sgt_buf, 0, sgt_buf_size); + sgt = (struct dpaa2_sg_entry *)(sgt_buf + priv->tx_data_offset); /* Fill in the HW SGT structure. @@ -421,7 +423,7 @@ static int build_sg_fd(struct dpaa2_eth_priv *priv, return 0; dma_map_single_failed: - kfree(sgt_buf); + skb_free_frag(sgt_buf); sgt_buf_alloc_failed: dma_unmap_sg(dev, scl, num_sg, DMA_BIDIRECTIONAL); dma_map_sg_failed: @@ -525,9 +527,9 @@ static void free_tx_fd(const struct dpaa2_eth_priv *priv, return; } - /* Free SGT buffer kmalloc'ed on tx */ + /* Free SGT buffer allocated on tx */ if (fd_format != dpaa2_fd_single) - kfree(skbh); + skb_free_frag(skbh); /* Move on with skb release */ dev_kfree_skb(skb); |