]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
um: vector: fix use-after-free in vector_mmsg_rx()
authorMichael Bommarito <michael.bommarito@gmail.com>
Mon, 22 Jun 2026 12:47:22 +0000 (08:47 -0400)
committerRichard Weinberger <richard@nod.at>
Thu, 23 Jul 2026 19:31:14 +0000 (21:31 +0200)
When vector_mmsg_rx() discards a packet whose overlay header fails
verify_header(), it frees the skb and continues the loop:

if (header_check < 0) {
dev_kfree_skb_irq(skb);
vp->estats.rx_encaps_errors++;
continue;
}

The normal and short-packet paths fall through to the bottom of the
loop body, which clears the consumed slot and advances the cursors:

(*skbuff_vector) = NULL;
mmsg_vector++;
skbuff_vector++;

The verify_header() < 0 path skips that via continue, so the freed skb
is left in skbuff_vector[] and the cursors do not advance. The next
iteration reads the same slot, gets the freed skb, and frees it again,
producing a refcount underflow / use-after-free in the RX path.

Discard the slot the same way the other paths do before continuing.

Only transports whose verify_header() can return negative are affected:
GRE and L2TPv3 do so on a cookie/session-id mismatch (raw/tap do not),
so any peer on such a transport can trigger it without authentication.

Fixes: 49da7e64f33e ("High Performance UML Vector Network Driver")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com>
Signed-off-by: Richard Weinberger <richard@nod.at>
arch/um/drivers/vector_kern.c

index 2cc90055499a54e0f6a75e04277aecf9a2a12078..8a70b3a625537cbe0cd7d94e23f31f25226010a8 100644 (file)
@@ -995,6 +995,9 @@ static int vector_mmsg_rx(struct vector_private *vp, int budget)
                                 */
                                        dev_kfree_skb_irq(skb);
                                        vp->estats.rx_encaps_errors++;
+                                       (*skbuff_vector) = NULL;
+                                       mmsg_vector++;
+                                       skbuff_vector++;
                                        continue;
                                }
                                if (header_check > 0) {