]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
gve: Fix use-after-free vulnerability
authorPraveen Kaligineedi <pkaligineedi@google.com>
Tue, 30 Jan 2024 21:45:07 +0000 (13:45 -0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 23 Feb 2024 07:54:55 +0000 (08:54 +0100)
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>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/net/ethernet/google/gve/gve_tx_dqo.c

index ec394d9916681ad230d42e99707ed09dc05d6154..94e3b74a10f22f5e08ff7cb52100c6e132b8b912 100644 (file)
@@ -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;