Author: rrs
Date: Fri Jul 31 10:03:32 2020
New Revision: 363725
URL: https://svnweb.freebsd.org/changeset/base/363725

Log:
  The recent changes to move the ref count increment
  back from the end of the function created an issue.
  If one of the routines returns NULL during setup
  we have inp's with extra references (which is why
  the increment was at the end).
  
  Also the stack switch return code was being ignored
  and actually has meaning if the stack cannot take over
  it should return NULL.
  
  Fix both of these situation by being sure to test the
  return code and of course in any case of return NULL (there
  are 3) make sure we properly reduce the ref count.
  
  Sponsored by: Netflix Inc.
  Differential Revision:        https://reviews.freebsd.org/D25903

Modified:
  head/sys/netinet/tcp_subr.c

Modified: head/sys/netinet/tcp_subr.c
==============================================================================
--- head/sys/netinet/tcp_subr.c Fri Jul 31 07:37:08 2020        (r363724)
+++ head/sys/netinet/tcp_subr.c Fri Jul 31 10:03:32 2020        (r363725)
@@ -1713,6 +1713,7 @@ tcp_newtcpcb(struct inpcb *inp)
                if (CC_ALGO(tp)->cb_init(tp->ccv) > 0) {
                        if (tp->t_fb->tfb_tcp_fb_fini)
                                (*tp->t_fb->tfb_tcp_fb_fini)(tp, 1);
+                       in_pcbrele_wlocked(inp);
                        refcount_release(&tp->t_fb->tfb_refcnt);
                        uma_zfree(V_tcpcb_zone, tm);
                        return (NULL);
@@ -1723,6 +1724,7 @@ tcp_newtcpcb(struct inpcb *inp)
        if (khelp_init_osd(HELPER_CLASS_TCP, tp->osd)) {
                if (tp->t_fb->tfb_tcp_fb_fini)
                        (*tp->t_fb->tfb_tcp_fb_fini)(tp, 1);
+               in_pcbrele_wlocked(inp);
                refcount_release(&tp->t_fb->tfb_refcnt);
                uma_zfree(V_tcpcb_zone, tm);
                return (NULL);
@@ -1783,7 +1785,12 @@ tcp_newtcpcb(struct inpcb *inp)
        tcp_log_tcpcbinit(tp);
 #endif
        if (tp->t_fb->tfb_tcp_fb_init) {
-               (*tp->t_fb->tfb_tcp_fb_init)(tp);
+               if ((*tp->t_fb->tfb_tcp_fb_init)(tp)) {
+                       refcount_release(&tp->t_fb->tfb_refcnt);
+                       in_pcbrele_wlocked(inp);
+                       uma_zfree(V_tcpcb_zone, tm);
+                       return (NULL);
+               }
        }
 #ifdef STATS
        if (V_tcp_perconn_stats_enable == 1)
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to