mirror of
https://github.com/freebsd/freebsd-src
synced 2024-10-15 12:54:27 +00:00
TCP: Fix a rack bug that skyzall found which results in a crash.
So when we call the fast_rsm retransmit path, we should always move snd_nxt back up to snd_max. In fact during ack-processing if snd_nxt falls behind it should be moved up there as well. Otherwise what can happen is we have an incorrect mark on snd_nxt and incorrectly calculate the offset when we go through the front path (which is what skzyall was able to do) then when we go to clean up the send the offset is all wrong and we crash. Special thanks to Gleb for pointing out the problem and the email that had the reproducer so I could find the issue. Reported-by: syzbot+f5061a372f74f021ec02@syzkaller.appspotmail.com Sponsored by: Netflix Inc
This commit is contained in:
parent
1ee29160c5
commit
8818f0f112
|
@ -12342,8 +12342,8 @@ rack_process_ack(struct mbuf *m, struct tcphdr *th, struct socket *so,
|
|||
if (SEQ_GT(tp->snd_una, tp->snd_recover))
|
||||
tp->snd_recover = tp->snd_una;
|
||||
|
||||
if (SEQ_LT(tp->snd_nxt, tp->snd_una)) {
|
||||
tp->snd_nxt = tp->snd_una;
|
||||
if (SEQ_LT(tp->snd_nxt, tp->snd_max)) {
|
||||
tp->snd_nxt = tp->snd_max;
|
||||
}
|
||||
if (under_pacing &&
|
||||
(rack->use_fixed_rate == 0) &&
|
||||
|
@ -16363,8 +16363,8 @@ rack_do_compressed_ack_processing(struct tcpcb *tp, struct socket *so, struct mb
|
|||
/* Send recover and snd_nxt must be dragged along */
|
||||
if (SEQ_GT(tp->snd_una, tp->snd_recover))
|
||||
tp->snd_recover = tp->snd_una;
|
||||
if (SEQ_LT(tp->snd_nxt, tp->snd_una))
|
||||
tp->snd_nxt = tp->snd_una;
|
||||
if (SEQ_LT(tp->snd_nxt, tp->snd_max))
|
||||
tp->snd_nxt = tp->snd_max;
|
||||
/*
|
||||
* If the RXT timer is running we want to
|
||||
* stop it, so we can restart a TLP (or new RXT).
|
||||
|
@ -19112,6 +19112,8 @@ rack_fast_rsm_output(struct tcpcb *tp, struct tcp_rack *rack, struct rack_sendma
|
|||
lgb->tlb_errno = error;
|
||||
lgb = NULL;
|
||||
}
|
||||
/* Move snd_nxt to snd_max so we don't have false retransmissions */
|
||||
tp->snd_nxt = tp->snd_max;
|
||||
if (error) {
|
||||
goto failed;
|
||||
} else if (rack->rc_hw_nobuf && (ip_sendflag != IP_NO_SND_TAG_RL)) {
|
||||
|
|
Loading…
Reference in a new issue