]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
gve: Clear napi->skb before dev_kfree_skb_any()
authorZiwei Xiao <ziweixiao@google.com>
Wed, 12 Jun 2024 00:16:54 +0000 (00:16 +0000)
committerJakub Kicinski <kuba@kernel.org>
Thu, 13 Jun 2024 14:37:35 +0000 (07:37 -0700)
gve_rx_free_skb incorrectly leaves napi->skb referencing an skb after it
is freed with dev_kfree_skb_any(). This can result in a subsequent call
to napi_get_frags returning a dangling pointer.

Fix this by clearing napi->skb before the skb is freed.

Fixes: 9b8dd5e5ea48 ("gve: DQO: Add RX path")
Cc: stable@vger.kernel.org
Reported-by: Shailend Chand <shailend@google.com>
Signed-off-by: Ziwei Xiao <ziweixiao@google.com>
Reviewed-by: Harshitha Ramamurthy <hramamurthy@google.com>
Reviewed-by: Shailend Chand <shailend@google.com>
Reviewed-by: Praveen Kaligineedi <pkaligineedi@google.com>
Link: https://lore.kernel.org/r/20240612001654.923887-1-ziweixiao@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/ethernet/google/gve/gve_rx_dqo.c

index c1c912de59c72679b075117728cec70997b682dc..1154c1d8f66f05872c394afafb7815ba8408ecfb 100644 (file)
@@ -647,11 +647,13 @@ static void gve_rx_skb_hash(struct sk_buff *skb,
        skb_set_hash(skb, le32_to_cpu(compl_desc->hash), hash_type);
 }
 
-static void gve_rx_free_skb(struct gve_rx_ring *rx)
+static void gve_rx_free_skb(struct napi_struct *napi, struct gve_rx_ring *rx)
 {
        if (!rx->ctx.skb_head)
                return;
 
+       if (rx->ctx.skb_head == napi->skb)
+               napi->skb = NULL;
        dev_kfree_skb_any(rx->ctx.skb_head);
        rx->ctx.skb_head = NULL;
        rx->ctx.skb_tail = NULL;
@@ -950,7 +952,7 @@ int gve_rx_poll_dqo(struct gve_notify_block *block, int budget)
 
                err = gve_rx_dqo(napi, rx, compl_desc, complq->head, rx->q_num);
                if (err < 0) {
-                       gve_rx_free_skb(rx);
+                       gve_rx_free_skb(napi, rx);
                        u64_stats_update_begin(&rx->statss);
                        if (err == -ENOMEM)
                                rx->rx_skb_alloc_fail++;
@@ -993,7 +995,7 @@ int gve_rx_poll_dqo(struct gve_notify_block *block, int budget)
 
                /* gve_rx_complete_skb() will consume skb if successful */
                if (gve_rx_complete_skb(rx, napi, compl_desc, feat) != 0) {
-                       gve_rx_free_skb(rx);
+                       gve_rx_free_skb(napi, rx);
                        u64_stats_update_begin(&rx->statss);
                        rx->rx_desc_err_dropped_pkt++;
                        u64_stats_update_end(&rx->statss);