4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ioana Radulescu ruxandra.radulescu@nxp.com
[ Upstream commit 6a9bbe53db9a5aa0be9788aa8a2c250dee55444b ]
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 --- drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-)
--- 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_ /* 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_ 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 dpaa 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);