bbr_pacing_inter() divides by the connection's pacing rate without
checking it. That rate is recomputed as a truncated integer product of the
estimated bandwidth by the pacing gain, and once full bandwidth has been
reached the new value is stored unconditionally, even when it truncated
down to zero. So a QUIC peer that acknowledges slowly and sparsely enough
to drive the bandwidth estimate down to a single byte per second, then
lets the connection leave Startup, makes the next pacing computation
divide by zero.
The resulting SIGFPE is not caught, so it takes down the whole worker
along with every connection it was serving, which any remote QUIC client
controls the conditions of.
Let's floor the divisor at 1, as the default pacing helper effectively
does.
Must be backported as far as 3.1.
Reported-by: Claude (ANT-2026-6B82W4A7)
struct bbr *bbr = quic_cc_priv(cc);
struct quic_cc_path *p = container_of(cc, struct quic_cc_path, cc);
- return p->mtu * 1000000000 / bbr->pacing_rate;
+ /* the rate may be truncated down to zero for very low bandwidths */
+ return p->mtu * 1000000000 / (bbr->pacing_rate ? bbr->pacing_rate : 1);
}
/* Return the pacing burst size in datagrams */