summaryrefslogtreecommitdiffstats
path: root/sys/netinet/udp_usrreq.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/netinet/udp_usrreq.c')
-rw-r--r--sys/netinet/udp_usrreq.c18
1 files changed, 15 insertions, 3 deletions
diff --git a/sys/netinet/udp_usrreq.c b/sys/netinet/udp_usrreq.c
index e0189d3..0d8e04d 100644
--- a/sys/netinet/udp_usrreq.c
+++ b/sys/netinet/udp_usrreq.c
@@ -746,11 +746,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;
@@ -761,6 +763,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 */
@@ -773,6 +776,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
OpenPOWER on IntegriCloud