Author: bz
Date: Sat Mar 27 17:51:27 2010
New Revision: 205762
URL: http://svn.freebsd.org/changeset/base/205762

Log:
  MFC r205251:
  
    Add pcb reference counting to the pcblist sysctl handler functions
    to ensure type stability while caching the pcb pointers for the
    copyout.
  
    Reviewed by:  rwatson

Modified:
  stable/8/sys/netinet/ip_divert.c
  stable/8/sys/netinet/raw_ip.c
  stable/8/sys/netinet/tcp_subr.c
  stable/8/sys/netinet/udp_usrreq.c
Directory Properties:
  stable/8/sys/   (props changed)
  stable/8/sys/amd64/include/xen/   (props changed)
  stable/8/sys/cddl/contrib/opensolaris/   (props changed)
  stable/8/sys/contrib/dev/acpica/   (props changed)
  stable/8/sys/contrib/pf/   (props changed)
  stable/8/sys/dev/xen/xenpci/   (props changed)

Modified: stable/8/sys/netinet/ip_divert.c
==============================================================================
--- stable/8/sys/netinet/ip_divert.c    Sat Mar 27 17:50:02 2010        
(r205761)
+++ stable/8/sys/netinet/ip_divert.c    Sat Mar 27 17:51:27 2010        
(r205762)
@@ -653,11 +653,13 @@ div_pcblist(SYSCTL_HANDLER_ARGS)
        INP_INFO_RLOCK(&V_divcbinfo);
        for (inp = LIST_FIRST(V_divcbinfo.ipi_listhead), i = 0; inp && i < n;
             inp = LIST_NEXT(inp, inp_list)) {
-               INP_RLOCK(inp);
+               INP_WLOCK(inp);
                if (inp->inp_gencnt <= gencnt &&
-                   cr_canseeinpcb(req->td->td_ucred, inp) == 0)
+                   cr_canseeinpcb(req->td->td_ucred, inp) == 0) {
+                       in_pcbref(inp);
                        inp_list[i++] = inp;
-               INP_RUNLOCK(inp);
+               }
+               INP_WUNLOCK(inp);
        }
        INP_INFO_RUNLOCK(&V_divcbinfo);
        n = i;
@@ -679,6 +681,15 @@ div_pcblist(SYSCTL_HANDLER_ARGS)
                } else
                        INP_RUNLOCK(inp);
        }
+       INP_INFO_WLOCK(&V_divcbinfo);
+       for (i = 0; i < n; i++) {
+               inp = inp_list[i];
+               INP_WLOCK(inp);
+               if (!in_pcbrele(inp))
+                       INP_WUNLOCK(inp);
+       }
+       INP_INFO_WUNLOCK(&V_divcbinfo);
+
        if (!error) {
                /*
                 * Give the user an updated idea of our state.

Modified: stable/8/sys/netinet/raw_ip.c
==============================================================================
--- stable/8/sys/netinet/raw_ip.c       Sat Mar 27 17:50:02 2010        
(r205761)
+++ stable/8/sys/netinet/raw_ip.c       Sat Mar 27 17:51:27 2010        
(r205762)
@@ -1025,13 +1025,13 @@ rip_pcblist(SYSCTL_HANDLER_ARGS)
        INP_INFO_RLOCK(&V_ripcbinfo);
        for (inp = LIST_FIRST(V_ripcbinfo.ipi_listhead), i = 0; inp && i < n;
             inp = LIST_NEXT(inp, inp_list)) {
-               INP_RLOCK(inp);
+               INP_WLOCK(inp);
                if (inp->inp_gencnt <= gencnt &&
                    cr_canseeinpcb(req->td->td_ucred, inp) == 0) {
-                       /* XXX held references? */
+                       in_pcbref(inp);
                        inp_list[i++] = inp;
                }
-               INP_RUNLOCK(inp);
+               INP_WUNLOCK(inp);
        }
        INP_INFO_RUNLOCK(&V_ripcbinfo);
        n = i;
@@ -1054,6 +1054,15 @@ rip_pcblist(SYSCTL_HANDLER_ARGS)
                } else
                        INP_RUNLOCK(inp);
        }
+       INP_INFO_WLOCK(&V_ripcbinfo);
+       for (i = 0; i < n; i++) {
+               inp = inp_list[i];
+               INP_WLOCK(inp);
+               if (!in_pcbrele(inp))
+                       INP_WUNLOCK(inp);
+       }
+       INP_INFO_WUNLOCK(&V_ripcbinfo);
+
        if (!error) {
                /*
                 * Give the user an updated idea of our state.  If the

Modified: stable/8/sys/netinet/tcp_subr.c
==============================================================================
--- stable/8/sys/netinet/tcp_subr.c     Sat Mar 27 17:50:02 2010        
(r205761)
+++ stable/8/sys/netinet/tcp_subr.c     Sat Mar 27 17:51:27 2010        
(r205762)
@@ -1102,7 +1102,7 @@ tcp_pcblist(SYSCTL_HANDLER_ARGS)
        INP_INFO_RLOCK(&V_tcbinfo);
        for (inp = LIST_FIRST(V_tcbinfo.ipi_listhead), i = 0;
            inp != NULL && i < n; inp = LIST_NEXT(inp, inp_list)) {
-               INP_RLOCK(inp);
+               INP_WLOCK(inp);
                if (inp->inp_gencnt <= gencnt) {
                        /*
                         * XXX: This use of cr_cansee(), introduced with
@@ -1117,10 +1117,12 @@ tcp_pcblist(SYSCTL_HANDLER_ARGS)
                                        error = EINVAL; /* Skip this inp. */
                        } else
                                error = cr_canseeinpcb(req->td->td_ucred, inp);
-                       if (error == 0)
+                       if (error == 0) {
+                               in_pcbref(inp);
                                inp_list[i++] = inp;
+                       }
                }
-               INP_RUNLOCK(inp);
+               INP_WUNLOCK(inp);
        }
        INP_INFO_RUNLOCK(&V_tcbinfo);
        n = i;
@@ -1156,8 +1158,16 @@ tcp_pcblist(SYSCTL_HANDLER_ARGS)
                        error = SYSCTL_OUT(req, &xt, sizeof xt);
                } else
                        INP_RUNLOCK(inp);
-       
        }
+       INP_INFO_WLOCK(&V_tcbinfo);
+       for (i = 0; i < n; i++) {
+               inp = inp_list[i];
+               INP_WLOCK(inp);
+               if (!in_pcbrele(inp))
+                       INP_WUNLOCK(inp);
+       }
+       INP_INFO_WUNLOCK(&V_tcbinfo);
+
        if (!error) {
                /*
                 * Give the user an updated idea of our state.

Modified: stable/8/sys/netinet/udp_usrreq.c
==============================================================================
--- stable/8/sys/netinet/udp_usrreq.c   Sat Mar 27 17:50:02 2010        
(r205761)
+++ stable/8/sys/netinet/udp_usrreq.c   Sat Mar 27 17:51:27 2010        
(r205762)
@@ -766,11 +766,13 @@ udp_pcblist(SYSCTL_HANDLER_ARGS)
        INP_INFO_RLOCK(&V_udbinfo);
        for (inp = LIST_FIRST(V_udbinfo.ipi_listhead), i = 0; inp && i < n;
             inp = LIST_NEXT(inp, inp_list)) {
-               INP_RLOCK(inp);
+               INP_WLOCK(inp);
                if (inp->inp_gencnt <= gencnt &&
-                   cr_canseeinpcb(req->td->td_ucred, inp) == 0)
+                   cr_canseeinpcb(req->td->td_ucred, inp) == 0) {
+                       in_pcbref(inp);
                        inp_list[i++] = inp;
-               INP_RUNLOCK(inp);
+               }
+               INP_WUNLOCK(inp);
        }
        INP_INFO_RUNLOCK(&V_udbinfo);
        n = i;
@@ -781,6 +783,7 @@ udp_pcblist(SYSCTL_HANDLER_ARGS)
                INP_RLOCK(inp);
                if (inp->inp_gencnt <= gencnt) {
                        struct xinpcb xi;
+
                        bzero(&xi, sizeof(xi));
                        xi.xi_len = sizeof xi;
                        /* XXX should avoid extra copy */
@@ -793,6 +796,15 @@ udp_pcblist(SYSCTL_HANDLER_ARGS)
                } else
                        INP_RUNLOCK(inp);
        }
+       INP_INFO_WLOCK(&V_udbinfo);
+       for (i = 0; i < n; i++) {
+               inp = inp_list[i];
+               INP_WLOCK(inp);
+               if (!in_pcbrele(inp))
+                       INP_WUNLOCK(inp);
+       }
+       INP_INFO_WUNLOCK(&V_udbinfo);
+
        if (!error) {
                /*
                 * Give the user an updated idea of our state.  If the
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to