lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20171011132951.25297-6-ruxandra.radulescu@nxp.com>
Date:   Wed, 11 Oct 2017 08:29:48 -0500
From:   Ioana Radulescu <ruxandra.radulescu@....com>
To:     <gregkh@...uxfoundation.org>
CC:     <devel@...verdev.osuosl.org>, <linux-kernel@...r.kernel.org>,
        <agraf@...e.de>, <arnd@...db.de>, <bogdan.purcareata@....com>,
        <stuyoder@...il.com>, <laurentiu.tudor@....com>
Subject: [PATCH 6/9] staging: fsl-dpaa2/eth: Fix double DMA unmap

In case we fail to allocate a skb for a fragmented ingress
frame, the cleanup function will attempt to unmap again the
first frame fragment, which had already been unmapped during
early Rx processing.

Avoid this by freeing the first buffer immediately in case
we hit an error, leaving the cleanup function to free only
the subsequent buffers.

Signed-off-by: Ioana Radulescu <ruxandra.radulescu@....com>
---
 drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.c | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.c b/drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.c
index a0be9ab..6540ab0 100644
--- a/drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.c
+++ b/drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.c
@@ -104,9 +104,11 @@ static void free_rx_fd(struct dpaa2_eth_priv *priv,
 		/* We don't support any other format */
 		return;
 
-	/* For S/G frames, we first need to free all SG entries */
+	/* For S/G frames, we first need to free all SG entries
+	 * except the first one, which was taken care of already
+	 */
 	sgt = vaddr + dpaa2_fd_get_offset(fd);
-	for (i = 0; i < DPAA2_ETH_MAX_SG_ENTRIES; i++) {
+	for (i = 1; i < DPAA2_ETH_MAX_SG_ENTRIES; i++) {
 		addr = dpaa2_sg_get_addr(&sgt[i]);
 		sg_vaddr = dpaa2_iova_to_virt(priv->iommu_domain, addr);
 		dma_unmap_single(dev, addr, DPAA2_ETH_RX_BUF_SIZE,
@@ -179,6 +181,11 @@ static struct sk_buff *build_frag_skb(struct dpaa2_eth_priv *priv,
 			skb = build_skb(sg_vaddr, DPAA2_ETH_RX_BUF_SIZE +
 				SKB_DATA_ALIGN(sizeof(struct skb_shared_info)));
 			if (unlikely(!skb)) {
+				/* Free the first SG entry now, since we already
+				 * unmapped it and obtained the virtual address
+				 */
+				skb_free_frag(sg_vaddr);
+
 				/* We still need to subtract the buffers used
 				 * by this FD from our software counter
 				 */
-- 
2.7.4

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ