The branch main has been updated by rrs:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=ba1b3e48f5be320f0590bc357ea53fdc3e4edc65

commit ba1b3e48f5be320f0590bc357ea53fdc3e4edc65
Author:     Randall Stewart <r...@freebsd.org>
AuthorDate: 2021-06-11 15:38:08 +0000
Commit:     Randall Stewart <r...@freebsd.org>
CommitDate: 2021-06-11 15:38:08 +0000

    tcp: Missing mfree in rack and bbr
    
    Recently (Nov) we added logic that protects against a peer negotiating a 
timestamp, and
    then not including a timestamp. This involved in the input path doing a 
goto done_with_input
    label. Now I suspect the code was cribbed from one in Rack that has to do 
with the SYN.
    This had a bug, i.e. it should have a m_freem(m) before going to the label 
(bbr had this
    missing m_freem() but rack did not). This then caused the missing m_freem 
to show
    up in both BBR and Rack. Also looking at the code referencing 
m->m_pkthdr.lro_nsegs
    later (after processing) is not a good idea, even though its only for 
logging. Best to
    copy that off before any frees can take place.
    
    Reviewed by: mtuexen
    Sponsored by: Netflix Inc
    Differential Revision:  https://reviews.freebsd.org/D30727
---
 sys/netinet/tcp_stacks/bbr.c  | 1 +
 sys/netinet/tcp_stacks/rack.c | 6 +++++-
 2 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/sys/netinet/tcp_stacks/bbr.c b/sys/netinet/tcp_stacks/bbr.c
index d5da2d33c18f..57abbbf694b6 100644
--- a/sys/netinet/tcp_stacks/bbr.c
+++ b/sys/netinet/tcp_stacks/bbr.c
@@ -11441,6 +11441,7 @@ bbr_do_segment_nounlock(struct mbuf *m, struct tcphdr 
*th, struct socket *so,
        if ((tp->t_flags & TF_RCVD_TSTMP) && !(to.to_flags & TOF_TS) &&
            ((thflags & TH_RST) == 0) && (V_tcp_tolerate_missing_ts == 0)) {
                retval = 0;
+               m_freem(m);
                goto done_with_input;
        }
        /*
diff --git a/sys/netinet/tcp_stacks/rack.c b/sys/netinet/tcp_stacks/rack.c
index 6ce866b77450..e5926eaf6171 100644
--- a/sys/netinet/tcp_stacks/rack.c
+++ b/sys/netinet/tcp_stacks/rack.c
@@ -13454,6 +13454,7 @@ rack_do_segment_nounlock(struct mbuf *m, struct tcphdr 
*th, struct socket *so,
 #ifdef TCP_ACCOUNTING
        int ack_val_set = 0xf;
 #endif
+       int nsegs;
        uint32_t us_cts;
        /*
         * tv passed from common code is from either M_TSTMP_LRO or
@@ -13465,6 +13466,7 @@ rack_do_segment_nounlock(struct mbuf *m, struct tcphdr 
*th, struct socket *so,
        if (m->m_flags & M_ACKCMP) {
                panic("Impossible reach m has ackcmp? m:%p tp:%p", m, tp);
        }
+       nsegs = m->m_pkthdr.lro_nsegs;
        counter_u64_add(rack_proc_non_comp_ack, 1);
        thflags = th->th_flags;
 #ifdef TCP_ACCOUNTING
@@ -13607,6 +13609,7 @@ rack_do_segment_nounlock(struct mbuf *m, struct tcphdr 
*th, struct socket *so,
        if ((thflags & TH_SYN) && (thflags & TH_FIN) && V_drop_synfin) {
                way_out = 4;
                retval = 0;
+               m_freem(m);
                goto done_with_input;
        }
        /*
@@ -13641,6 +13644,7 @@ rack_do_segment_nounlock(struct mbuf *m, struct tcphdr 
*th, struct socket *so,
            ((thflags & TH_RST) == 0) && (V_tcp_tolerate_missing_ts == 0)) {
                way_out = 5;
                retval = 0;
+               m_freem(m);
                goto done_with_input;
        }
 
@@ -13944,7 +13948,7 @@ do_output_now:
                        way_out = 2;
                }
        done_with_input:
-               rack_log_doseg_done(rack, cts, nxt_pkt, did_out, way_out, 
max(1, m->m_pkthdr.lro_nsegs));
+               rack_log_doseg_done(rack, cts, nxt_pkt, did_out, way_out, 
max(1, nsegs));
                if (did_out)
                        rack->r_wanted_output = 0;
 #ifdef INVARIANTS
_______________________________________________
dev-commits-src-main@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/dev-commits-src-main
To unsubscribe, send any mail to "dev-commits-src-main-unsubscr...@freebsd.org"

Reply via email to