diff options
author | ps <ps@FreeBSD.org> | 2005-07-01 22:52:46 +0000 |
---|---|---|
committer | ps <ps@FreeBSD.org> | 2005-07-01 22:52:46 +0000 |
commit | 513734e2faf1e33963e9b5cf0c68d8398ed8de37 (patch) | |
tree | 3b57983fa8f90c9a1801514a42c596acdfa28c16 /sys | |
parent | 0b830ea12be133ca1a4a16f6c52a06a8f82cf22e (diff) | |
download | FreeBSD-src-513734e2faf1e33963e9b5cf0c68d8398ed8de37.zip FreeBSD-src-513734e2faf1e33963e9b5cf0c68d8398ed8de37.tar.gz |
Fix for a SACK crash caused by a bug in tcp_reass(). tcp_reass()
does not clear tlen and frees the mbuf (leaving th pointing at
freed memory), if the data segment is a complete duplicate.
This change works around that bug. A fix for the tcp_reass() bug
will appear later (that bug is benign for now, as neither th nor
tlen is referenced in tcp_input() after the call to tcp_reass()).
Found by: Pawel Jakub Dawidek.
Submitted by: Raja Mukerji, Noritoshi Demizu.
Approved by: re
Diffstat (limited to 'sys')
-rw-r--r-- | sys/netinet/tcp_input.c | 4 | ||||
-rw-r--r-- | sys/netinet/tcp_reass.c | 4 |
2 files changed, 6 insertions, 2 deletions
diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c index b6c2812..93cf272 100644 --- a/sys/netinet/tcp_input.c +++ b/sys/netinet/tcp_input.c @@ -2311,6 +2311,8 @@ dodata: /* XXX */ */ if ((tlen || (thflags & TH_FIN)) && TCPS_HAVERCVDFIN(tp->t_state) == 0) { + tcp_seq save_start = th->th_seq; + tcp_seq save_end = th->th_seq + tlen; m_adj(m, drop_hdrlen); /* delayed header drop */ /* * Insert segment which includes th into TCP reassembly queue @@ -2347,7 +2349,7 @@ dodata: /* XXX */ tp->t_flags |= TF_ACKNOW; } if (tlen > 0 && tp->sack_enable) - tcp_update_sack_list(tp, th->th_seq, th->th_seq + tlen); + tcp_update_sack_list(tp, save_start, save_end); /* * Note the amount of data that peer has sent into * our window, in order to estimate the sender's diff --git a/sys/netinet/tcp_reass.c b/sys/netinet/tcp_reass.c index b6c2812..93cf272 100644 --- a/sys/netinet/tcp_reass.c +++ b/sys/netinet/tcp_reass.c @@ -2311,6 +2311,8 @@ dodata: /* XXX */ */ if ((tlen || (thflags & TH_FIN)) && TCPS_HAVERCVDFIN(tp->t_state) == 0) { + tcp_seq save_start = th->th_seq; + tcp_seq save_end = th->th_seq + tlen; m_adj(m, drop_hdrlen); /* delayed header drop */ /* * Insert segment which includes th into TCP reassembly queue @@ -2347,7 +2349,7 @@ dodata: /* XXX */ tp->t_flags |= TF_ACKNOW; } if (tlen > 0 && tp->sack_enable) - tcp_update_sack_list(tp, th->th_seq, th->th_seq + tlen); + tcp_update_sack_list(tp, save_start, save_end); /* * Note the amount of data that peer has sent into * our window, in order to estimate the sender's |