On 5/14/25 3:56 PM, chia-yu.ch...@nokia-bell-labs.com wrote: > From: Ilpo Järvinen <i...@kernel.org> > > 1) Don't early return when sack doesn't fit. AccECN code will be > placed after this fragment so no early returns please. > > 2) Make sure opts->num_sack_blocks is not left undefined. E.g., > tcp_current_mss() does not memset its opts struct to zero. > AccECN code checks if SACK option is present and may even > alter it to make room for AccECN option when many SACK blocks > are present. Thus, num_sack_blocks needs to be always valid. > > Signed-off-by: Ilpo Järvinen <i...@kernel.org> > Signed-off-by: Chia-Yu Chang <chia-yu.ch...@nokia-bell-labs.com> > --- > net/ipv4/tcp_output.c | 23 ++++++++++++----------- > 1 file changed, 12 insertions(+), 11 deletions(-) > > diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c > index d0f0fee8335e..d7fef3d2698b 100644 > --- a/net/ipv4/tcp_output.c > +++ b/net/ipv4/tcp_output.c > @@ -1092,17 +1092,18 @@ static unsigned int tcp_established_options(struct > sock *sk, struct sk_buff *skb > eff_sacks = tp->rx_opt.num_sacks + tp->rx_opt.dsack; > if (unlikely(eff_sacks)) { > const unsigned int remaining = MAX_TCP_OPTION_SPACE - size; > - if (unlikely(remaining < TCPOLEN_SACK_BASE_ALIGNED + > - TCPOLEN_SACK_PERBLOCK)) > - return size; > - > - opts->num_sack_blocks = > - min_t(unsigned int, eff_sacks, > - (remaining - TCPOLEN_SACK_BASE_ALIGNED) / > - TCPOLEN_SACK_PERBLOCK); > - > - size += TCPOLEN_SACK_BASE_ALIGNED + > - opts->num_sack_blocks * TCPOLEN_SACK_PERBLOCK; > + if (likely(remaining >= TCPOLEN_SACK_BASE_ALIGNED + > + TCPOLEN_SACK_PERBLOCK)) { > + opts->num_sack_blocks = > + min_t(unsigned int, eff_sacks, > + (remaining - TCPOLEN_SACK_BASE_ALIGNED) / > + TCPOLEN_SACK_PERBLOCK); > + > + size += TCPOLEN_SACK_BASE_ALIGNED + > + opts->num_sack_blocks * TCPOLEN_SACK_PERBLOCK; > + } > + } else { > + opts->num_sack_blocks = 0; > }
AFAICS here opts->num_sack_blocks is still uninitialized when: eff_acks != 0 && remaining < (TCPOLEN_SACK_BASE_ALIGNED + TCPOLEN_SACK_PERBLOCK) /P