From: Bailey Forrest bcf@google.com
Call skb_shinfo() after gve_prep_tso() on DQO TX path. gve_prep_tso() calls skb_cow_head(), which may reallocate shinfo causing a use after free.
This bug was unintentionally fixed by 'a6fb8d5a8b69 ("gve: Tx path for DQO-QPL")' while adding DQO-QPL format support in 6.6. That patch is not appropriate for stable releases.
Fixes: a57e5de476be ("gve: DQO: Add TX path") Signed-off-by: Praveen Kaligineedi pkaligineedi@google.com Signed-off-by: Bailey Forrest bcf@google.com Reviewed-by: Eric Dumazet edumazet@google.com Reviewed-by: Jeroen de Borst jeroendb@google.com Reviewed-by: Kevin DeCabooter decabooter@google.com --- drivers/net/ethernet/google/gve/gve_tx_dqo.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/google/gve/gve_tx_dqo.c b/drivers/net/ethernet/google/gve/gve_tx_dqo.c index ec394d991668..94e3b74a10f2 100644 --- a/drivers/net/ethernet/google/gve/gve_tx_dqo.c +++ b/drivers/net/ethernet/google/gve/gve_tx_dqo.c @@ -350,6 +350,7 @@ static void gve_tx_fill_pkt_desc_dqo(struct gve_tx_ring *tx, u32 *desc_idx, /* Validates and prepares `skb` for TSO. * * Returns header length, or < 0 if invalid. + * Warning : Might change skb->head (and thus skb_shinfo). */ static int gve_prep_tso(struct sk_buff *skb) { @@ -451,8 +452,8 @@ gve_tx_fill_general_ctx_desc(struct gve_tx_general_context_desc_dqo *desc, static int gve_tx_add_skb_no_copy_dqo(struct gve_tx_ring *tx, struct sk_buff *skb) { - const struct skb_shared_info *shinfo = skb_shinfo(skb); const bool is_gso = skb_is_gso(skb); + struct skb_shared_info *shinfo; u32 desc_idx = tx->dqo_tx.tail;
struct gve_tx_pending_packet_dqo *pkt; @@ -477,6 +478,8 @@ static int gve_tx_add_skb_no_copy_dqo(struct gve_tx_ring *tx, desc_idx = (desc_idx + 1) & tx->mask; }
+ /* Must get after gve_prep_tso(), which can change shinfo. */ + shinfo = skb_shinfo(skb); gve_tx_fill_general_ctx_desc(&tx->dqo.tx_ring[desc_idx].general_ctx, &metadata); desc_idx = (desc_idx + 1) & tx->mask;