summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorrwatson <rwatson@FreeBSD.org>2003-04-10 20:33:10 +0000
committerrwatson <rwatson@FreeBSD.org>2003-04-10 20:33:10 +0000
commitc879a35dfec807e5e1738128357759e96aa38919 (patch)
tree027d8706a8bea770ce4e8c638bda86ace427ad7e
parent798a01c63fd2ef56c68a97300484838da3f8643a (diff)
downloadFreeBSD-src-c879a35dfec807e5e1738128357759e96aa38919.zip
FreeBSD-src-c879a35dfec807e5e1738128357759e96aa38919.tar.gz
Remove a potential panic condition introduced by reduced TCP wait
state. Those changed attempted to work around the changed invariant that inp->in_socket was sometimes now NULL, but the logic wasn't quite right, meaning that inp->in_socket would be dereferenced by cr_canseesocket() if security.bsd.see_other_uids, jail, or MAC were in use. Attempt to clarify and correct the logic. Note: the work-around originally introduced with the reduced TCP wait state handling to use cr_cansee() instead of cr_canseesocket() in this case isn't really right, although it "Does the right thing" for most of the cases in the base system. We'll need to address this at some point in the future. Pointed out by: dcs Obtained from: TrustedBSD Project Sponsored by: DARPA, Network Associates Laboratories
-rw-r--r--sys/netinet/tcp_subr.c20
-rw-r--r--sys/netinet/tcp_timewait.c20
2 files changed, 30 insertions, 10 deletions
diff --git a/sys/netinet/tcp_subr.c b/sys/netinet/tcp_subr.c
index e96647f..58395f5 100644
--- a/sys/netinet/tcp_subr.c
+++ b/sys/netinet/tcp_subr.c
@@ -926,11 +926,21 @@ tcp_pcblist(SYSCTL_HANDLER_ARGS)
for (inp = LIST_FIRST(tcbinfo.listhead), i = 0; inp && i < n;
inp = LIST_NEXT(inp, inp_list)) {
INP_LOCK(inp);
- if (inp->inp_gencnt <= gencnt &&
- (((inp->inp_vflag & INP_TIMEWAIT) &&
- cr_cansee(req->td->td_ucred, intotw(inp)->tw_cred) == 0) ||
- cr_canseesocket(req->td->td_ucred, inp->inp_socket) == 0))
- inp_list[i++] = inp;
+ if (inp->inp_gencnt <= gencnt) {
+ /*
+ * XXX: This use of cr_cansee(), introduced with
+ * TCP state changes, is not quite right, but for
+ * now, better than nothing.
+ */
+ if (inp->inp_vflag & INP_TIMEWAIT)
+ error = cr_cansee(req->td->td_ucred,
+ intotw(inp)->tw_cred);
+ else
+ error = cr_canseesocket(req->td->td_ucred,
+ inp->inp_socket);
+ if (error == 0)
+ inp_list[i++] = inp;
+ }
INP_UNLOCK(inp);
}
INP_INFO_RUNLOCK(&tcbinfo);
diff --git a/sys/netinet/tcp_timewait.c b/sys/netinet/tcp_timewait.c
index e96647f..58395f5 100644
--- a/sys/netinet/tcp_timewait.c
+++ b/sys/netinet/tcp_timewait.c
@@ -926,11 +926,21 @@ tcp_pcblist(SYSCTL_HANDLER_ARGS)
for (inp = LIST_FIRST(tcbinfo.listhead), i = 0; inp && i < n;
inp = LIST_NEXT(inp, inp_list)) {
INP_LOCK(inp);
- if (inp->inp_gencnt <= gencnt &&
- (((inp->inp_vflag & INP_TIMEWAIT) &&
- cr_cansee(req->td->td_ucred, intotw(inp)->tw_cred) == 0) ||
- cr_canseesocket(req->td->td_ucred, inp->inp_socket) == 0))
- inp_list[i++] = inp;
+ if (inp->inp_gencnt <= gencnt) {
+ /*
+ * XXX: This use of cr_cansee(), introduced with
+ * TCP state changes, is not quite right, but for
+ * now, better than nothing.
+ */
+ if (inp->inp_vflag & INP_TIMEWAIT)
+ error = cr_cansee(req->td->td_ucred,
+ intotw(inp)->tw_cred);
+ else
+ error = cr_canseesocket(req->td->td_ucred,
+ inp->inp_socket);
+ if (error == 0)
+ inp_list[i++] = inp;
+ }
INP_UNLOCK(inp);
}
INP_INFO_RUNLOCK(&tcbinfo);
OpenPOWER on IntegriCloud