CVE-2026-43194
Publication date:
06/05/2026
In the Linux kernel, the following vulnerability has been resolved:<br />
<br />
net: consume xmit errors of GSO frames<br />
<br />
udpgro_frglist.sh and udpgro_bench.sh are the flakiest tests<br />
currently in NIPA. They fail in the same exact way, TCP GRO<br />
test stalls occasionally and the test gets killed after 10min.<br />
<br />
These tests use veth to simulate GRO. They attach a trivial<br />
("return XDP_PASS;") XDP program to the veth to force TSO off<br />
and NAPI on.<br />
<br />
Digging into the failure mode we can see that the connection<br />
is completely stuck after a burst of drops. The sender&#39;s snd_nxt<br />
is at sequence number N [1], but the receiver claims to have<br />
received (rcv_nxt) up to N + 3 * MSS [2]. Last piece of the puzzle<br />
is that senders rtx queue is not empty (let&#39;s say the block in<br />
the rtx queue is at sequence number N - 4 * MSS [3]).<br />
<br />
In this state, sender sends a retransmission from the rtx queue<br />
with a single segment, and sequence numbers N-4*MSS:N-3*MSS [3].<br />
Receiver sees it and responds with an ACK all the way up to<br />
N + 3 * MSS [2]. But sender will reject this ack as TCP_ACK_UNSENT_DATA<br />
because it has no recollection of ever sending data that far out [1].<br />
And we are stuck.<br />
<br />
The root cause is the mess of the xmit return codes. veth returns<br />
an error when it can&#39;t xmit a frame. We end up with a loss event<br />
like this:<br />
<br />
-------------------------------------------------<br />
| GSO super frame 1 | GSO super frame 2 |<br />
|-----------------------------------------------|<br />
| seg | seg | seg | seg | seg | seg | seg | seg |<br />
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |<br />
-------------------------------------------------<br />
x ok ok | ok ok ok <br />
\\<br />
snd_nxt<br />
<br />
"x" means packet lost by veth, and "ok" means it went thru.<br />
Since veth has TSO disabled in this test it sees individual segments.<br />
Segment 1 is on the retransmit queue and will be resent.<br />
<br />
So why did the sender not advance snd_nxt even tho it clearly did<br />
send up to seg 8? tcp_write_xmit() interprets the return code<br />
from the core to mean that data has not been sent at all. Since<br />
TCP deals with GSO super frames, not individual segment the crux<br />
of the problem is that loss of a single segment can be interpreted<br />
as loss of all. TCP only sees the last return code for the last<br />
segment of the GSO frame (in brackets in the diagram above).<br />
<br />
Of course for the problem to occur we need a setup or a device<br />
without a Qdisc. Otherwise Qdisc layer disconnects the protocol<br />
layer from the device errors completely.<br />
<br />
We have multiple ways to fix this.<br />
<br />
1) make veth not return an error when it lost a packet.<br />
While this is what I think we did in the past, the issue keeps<br />
reappearing and it&#39;s annoying to debug. The game of whack<br />
a mole is not great.<br />
<br />
2) fix the damn return codes<br />
We only talk about NETDEV_TX_OK and NETDEV_TX_BUSY in the<br />
documentation, so maybe we should make the return code from<br />
ndo_start_xmit() a boolean. I like that the most, but perhaps<br />
some ancient, not-really-networking protocol would suffer.<br />
<br />
3) make TCP ignore the errors<br />
It is not entirely clear to me what benefit TCP gets from<br />
interpreting the result of ip_queue_xmit()? Specifically once<br />
the connection is established and we&#39;re pushing data - packet<br />
loss is just packet loss?<br />
<br />
4) this fix<br />
Ignore the rc in the Qdisc-less+GSO case, since it&#39;s unreliable.<br />
We already always return OK in the TCQ_F_CAN_BYPASS case.<br />
In the Qdisc-less case let&#39;s be a bit more conservative and only<br />
mask the GSO errors. This path is taken by non-IP-"networks"<br />
like CAN, MCTP etc, so we could regress some ancient thing.<br />
This is the simplest, but also maybe the hackiest fix?<br />
<br />
Similar fix has been proposed by Eric in the past but never committed<br />
because original reporter was working with an OOT driver and wasn&#39;t<br />
providing feedback (see Link).
Severity CVSS v4.0: Pending analysis
Last modification:
08/05/2026