summaryrefslogtreecommitdiffstats
path: root/sys/netinet/raw_ip.c
diff options
context:
space:
mode:
authorbz <bz@FreeBSD.org>2010-03-17 18:28:27 +0000
committerbz <bz@FreeBSD.org>2010-03-17 18:28:27 +0000
commitd9875d4fd4c45bebc4c347f0d1fcb22099193183 (patch)
tree85c73f9269f770d5fe3c30e96a831d1f2aa866c2 /sys/netinet/raw_ip.c
parent4b084f1d29afadefc6441a3d8791aa1fac66a125 (diff)
downloadFreeBSD-src-d9875d4fd4c45bebc4c347f0d1fcb22099193183.zip
FreeBSD-src-d9875d4fd4c45bebc4c347f0d1fcb22099193183.tar.gz
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 MFC after: 7 days
Diffstat (limited to 'sys/netinet/raw_ip.c')
-rw-r--r--sys/netinet/raw_ip.c15
1 files changed, 12 insertions, 3 deletions
diff --git a/sys/netinet/raw_ip.c b/sys/netinet/raw_ip.c
index 88c1e61..1db3774 100644
--- a/sys/netinet/raw_ip.c
+++ b/sys/netinet/raw_ip.c
@@ -1011,13 +1011,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;
@@ -1040,6 +1040,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
OpenPOWER on IntegriCloud