Commit 6f4d93b7 authored by Ziwei Xiao's avatar Ziwei Xiao Committed by Jakub Kicinski
Browse files

gve: Clear napi->skb before dev_kfree_skb_any()



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: 9b8dd5e5 ("gve: DQO: Add RX path")
Cc: stable@vger.kernel.org
Reported-by: default avatarShailend Chand <shailend@google.com>
Signed-off-by: default avatarZiwei Xiao <ziweixiao@google.com>
Reviewed-by: default avatarHarshitha Ramamurthy <hramamurthy@google.com>
Reviewed-by: default avatarShailend Chand <shailend@google.com>
Reviewed-by: default avatarPraveen Kaligineedi <pkaligineedi@google.com>
Link: https://lore.kernel.org/r/20240612001654.923887-1-ziweixiao@google.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent 79f18a41
Loading
Loading
Loading
Loading
+5 −3
Original line number Diff line number Diff line
@@ -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);