Commit 4fd7827b authored by Tho Vu's avatar Tho Vu Committed by Kleber Sacilotto de Souza

ravb: Fix use-after-free ravb_tstamp_skb

BugLink: https://bugs.launchpad.net/bugs/1845374

[ Upstream commit cfef46d6 ]

When a Tx timestamp is requested, a pointer to the skb is stored in the
ravb_tstamp_skb struct. This was done without an skb_get. There exists
the possibility that the skb could be freed by ravb_tx_free (when
ravb_tx_free is called from ravb_start_xmit) before the timestamp was
processed, leading to a use-after-free bug.

Use skb_get when filling a ravb_tstamp_skb struct, and add appropriate
frees/consumes when a ravb_tstamp_skb struct is freed.

Fixes: c156633f ("Renesas Ethernet AVB driver proper")
Signed-off-by: default avatarTho Vu <tho.vu.wh@rvc.renesas.com>
Signed-off-by: default avatarKazuya Mizuguchi <kazuya.mizuguchi.ks@renesas.com>
Signed-off-by: default avatarSimon Horman <horms+renesas@verge.net.au>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
Signed-off-by: default avatarConnor Kuehl <connor.kuehl@canonical.com>
Signed-off-by: default avatarKhalid Elmously <khalid.elmously@canonical.com>
parent c894d645
/* Renesas Ethernet AVB device driver /* Renesas Ethernet AVB device driver
* *
* Copyright (C) 2014-2015 Renesas Electronics Corporation * Copyright (C) 2014-2019 Renesas Electronics Corporation
* Copyright (C) 2015 Renesas Solutions Corp. * Copyright (C) 2015 Renesas Solutions Corp.
* Copyright (C) 2015 Cogent Embedded, Inc. <source@cogentembedded.com> * Copyright (C) 2015 Cogent Embedded, Inc. <source@cogentembedded.com>
* *
...@@ -501,7 +501,10 @@ static void ravb_get_tx_tstamp(struct net_device *ndev) ...@@ -501,7 +501,10 @@ static void ravb_get_tx_tstamp(struct net_device *ndev)
kfree(ts_skb); kfree(ts_skb);
if (tag == tfa_tag) { if (tag == tfa_tag) {
skb_tstamp_tx(skb, &shhwtstamps); skb_tstamp_tx(skb, &shhwtstamps);
dev_consume_skb_any(skb);
break; break;
} else {
dev_kfree_skb_any(skb);
} }
} }
ravb_write(ndev, ravb_read(ndev, TCCR) | TCCR_TFR, TCCR); ravb_write(ndev, ravb_read(ndev, TCCR) | TCCR_TFR, TCCR);
...@@ -1382,7 +1385,7 @@ static netdev_tx_t ravb_start_xmit(struct sk_buff *skb, struct net_device *ndev) ...@@ -1382,7 +1385,7 @@ static netdev_tx_t ravb_start_xmit(struct sk_buff *skb, struct net_device *ndev)
DMA_TO_DEVICE); DMA_TO_DEVICE);
goto unmap; goto unmap;
} }
ts_skb->skb = skb; ts_skb->skb = skb_get(skb);
ts_skb->tag = priv->ts_skb_tag++; ts_skb->tag = priv->ts_skb_tag++;
priv->ts_skb_tag &= 0x3ff; priv->ts_skb_tag &= 0x3ff;
list_add_tail(&ts_skb->list, &priv->ts_skb_list); list_add_tail(&ts_skb->list, &priv->ts_skb_list);
...@@ -1514,6 +1517,7 @@ static int ravb_close(struct net_device *ndev) ...@@ -1514,6 +1517,7 @@ static int ravb_close(struct net_device *ndev)
/* Clear the timestamp list */ /* Clear the timestamp list */
list_for_each_entry_safe(ts_skb, ts_skb2, &priv->ts_skb_list, list) { list_for_each_entry_safe(ts_skb, ts_skb2, &priv->ts_skb_list, list) {
list_del(&ts_skb->list); list_del(&ts_skb->list);
kfree_skb(ts_skb->skb);
kfree(ts_skb); kfree(ts_skb);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment