Skip to content

Commit

Permalink
gianfar: simplify FCS handling and fix memory leak
Browse files Browse the repository at this point in the history
commit d903ec77118c09f93a610b384d83a6df33a64fe6 upstream.

Previously, buffer descriptors containing only the frame check sequence
(FCS) were skipped and not added to the skb. However, the page reference
count was still incremented, leading to a memory leak.

Fixing this inside gfar_add_rx_frag() is difficult due to reserved
memory handling and page reuse. Instead, move the FCS handling to
gfar_process_frame() and trim off the FCS before passing the skb up the
networking stack.

Signed-off-by: Andy Spencer <[email protected]>
Signed-off-by: Jim Gruen <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Cc: Ben Hutchings <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
  • Loading branch information
aspencer-spacex authored and Pierre2324 committed Feb 6, 2022
1 parent 92c68c7 commit 940e798
Showing 1 changed file with 7 additions and 16 deletions.
23 changes: 7 additions & 16 deletions drivers/net/ethernet/freescale/gianfar.c
Original file line number Diff line number Diff line change
Expand Up @@ -2939,29 +2939,17 @@ static bool gfar_add_rx_frag(struct gfar_rx_buff *rxb, u32 lstatus,
{
int size = lstatus & BD_LENGTH_MASK;
struct page *page = rxb->page;
bool last = !!(lstatus & BD_LFLAG(RXBD_LAST));

/* Remove the FCS from the packet length */
if (last)
size -= ETH_FCS_LEN;

if (likely(first)) {
skb_put(skb, size);
} else {
/* the last fragments' length contains the full frame length */
if (last)
if (lstatus & BD_LFLAG(RXBD_LAST))
size -= skb->len;

/* Add the last fragment if it contains something other than
* the FCS, otherwise drop it and trim off any part of the FCS
* that was already received.
*/
if (size > 0)
skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, page,
rxb->page_offset + RXBUF_ALIGNMENT,
size, GFAR_RXB_TRUESIZE);
else if (size < 0)
pskb_trim(skb, skb->len + size);
skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, page,
rxb->page_offset + RXBUF_ALIGNMENT,
size, GFAR_RXB_TRUESIZE);
}

/* try reuse page */
Expand Down Expand Up @@ -3074,6 +3062,9 @@ static void gfar_process_frame(struct net_device *ndev, struct sk_buff *skb)
if (priv->padding)
skb_pull(skb, priv->padding);

/* Trim off the FCS */
pskb_trim(skb, skb->len - ETH_FCS_LEN);

if (ndev->features & NETIF_F_RXCSUM)
gfar_rx_checksum(skb, fcb);

Expand Down

0 comments on commit 940e798

Please sign in to comment.