ravb: Fix use-after-free ravb_tstamp_skb [Linux 4.14.143]

This Linux kernel change "ravb: Fix use-after-free ravb_tstamp_skb" is included in the Linux 4.14.143 release. This change is authored by Tho Vu <tho.vu.wh [at] rvc.renesas.com> on Fri Aug 16 17:17:02 2019 +0200. The commit for this change in Linux stable tree is 6fba160 (patch) which is from upstream commit cfef46d. The same Linux upstream change may have been applied to various maintained Linux releases and you can find all Linux releases containing changes from upstream cfef46d.

ravb: Fix use-after-free ravb_tstamp_skb

[ Upstream commit cfef46d692efd852a0da6803f920cc756eea2855 ]

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: c156633f1353 ("Renesas Ethernet AVB driver proper")
Signed-off-by: Tho Vu <tho.vu.wh@rvc.renesas.com>
Signed-off-by: Kazuya Mizuguchi <kazuya.mizuguchi.ks@renesas.com>
Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>

There are 8 lines of Linux source code added/deleted in this change. Code changes to Linux kernel are as follows.

 drivers/net/ethernet/renesas/ravb_main.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/renesas/ravb_main.c b/drivers/net/ethernet/renesas/ravb_main.c
index ce79af4..d73617c 100644
--- a/drivers/net/ethernet/renesas/ravb_main.c
+++ b/drivers/net/ethernet/renesas/ravb_main.c
@@ -1,6 +1,6 @@
 /* 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-2016 Cogent Embedded, Inc. <source@cogentembedded.com>
  *
@@ -513,7 +513,10 @@ static void ravb_get_tx_tstamp(struct net_device *ndev)
            kfree(ts_skb);
            if (tag == tfa_tag) {
                skb_tstamp_tx(skb, &shhwtstamps);
+               dev_consume_skb_any(skb);
                break;
+           } else {
+               dev_kfree_skb_any(skb);
            }
        }
        ravb_modify(ndev, TCCR, TCCR_TFR, TCCR_TFR);
@@ -1576,7 +1579,7 @@ static netdev_tx_t ravb_start_xmit(struct sk_buff *skb, struct net_device *ndev)
                     DMA_TO_DEVICE);
            goto unmap;
        }
-       ts_skb->skb = skb;
+       ts_skb->skb = skb_get(skb);
        ts_skb->tag = priv->ts_skb_tag++;
        priv->ts_skb_tag &= 0x3ff;
        list_add_tail(&ts_skb->list, &priv->ts_skb_list);
@@ -1704,6 +1707,7 @@ static int ravb_close(struct net_device *ndev)
    /* Clear the timestamp list */
    list_for_each_entry_safe(ts_skb, ts_skb2, &priv->ts_skb_list, list) {
        list_del(&ts_skb->list);
+       kfree_skb(ts_skb->skb);
        kfree(ts_skb);
    }

Leave a Reply

Your email address will not be published. Required fields are marked *