From c06f087ccb1207c14e96a7a9911566f95ff582a6 Mon Sep 17 00:00:00 2001 From: "Bjoern A. Zeeb" Date: Sat, 23 Aug 2008 14:22:12 +0000 Subject: [PATCH] Cache the cred locally in _syncache_add() while holding the locks, so we can be sure that it's valid. In case we abort early free it again else put it into the syncache. We need the cred in the syncache to be able to restrict what will be exportet by the sysctl helper function syncache_pcblist() (to netstat) within jails. PR: kern/126493 Reviewed by: rwatson (earlier versions) MFC after: 3 days --- sys/netinet/tcp_syncache.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/sys/netinet/tcp_syncache.c b/sys/netinet/tcp_syncache.c index 99f12c2640ff..60a0295f2c20 100644 --- a/sys/netinet/tcp_syncache.c +++ b/sys/netinet/tcp_syncache.c @@ -53,6 +53,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include @@ -146,6 +147,7 @@ struct syncache { #ifdef MAC struct label *sc_label; /* MAC label reference */ #endif + struct ucred *sc_cred; /* cred cache for jail checks */ }; #ifdef TCP_OFFLOAD_DISABLE @@ -264,6 +266,8 @@ syncache_free(struct syncache *sc) { if (sc->sc_ipopts) (void) m_free(sc->sc_ipopts); + if (sc->sc_cred) + crfree(sc->sc_cred); #ifdef MAC mac_syncache_destroy(&sc->sc_label); #endif @@ -1010,6 +1014,7 @@ _syncache_add(struct in_conninfo *inc, struct tcpopt *to, struct tcphdr *th, struct label *maclabel; #endif struct syncache scs; + struct ucred *cred; INP_INFO_WLOCK_ASSERT(&V_tcbinfo); INP_WLOCK_ASSERT(inp); /* listen socket */ @@ -1022,6 +1027,7 @@ _syncache_add(struct in_conninfo *inc, struct tcpopt *to, struct tcphdr *th, */ so = *lsop; tp = sototcpcb(so); + cred = crhold(so->so_cred); #ifdef INET6 if (inc->inc_isipv6 && @@ -1151,6 +1157,8 @@ _syncache_add(struct in_conninfo *inc, struct tcpopt *to, struct tcphdr *th, #ifdef MAC sc->sc_label = maclabel; #endif + sc->sc_cred = cred; + cred = NULL; sc->sc_ipopts = ipopts; sc->sc_inc.inc_fibnum = inp->inp_inc.inc_fibnum; bcopy(inc, &sc->sc_inc, sizeof(struct in_conninfo)); @@ -1272,6 +1280,8 @@ _syncache_add(struct in_conninfo *inc, struct tcpopt *to, struct tcphdr *th, } done: + if (cred != NULL) + crfree(cred); #ifdef MAC if (sc == &scs) mac_syncache_destroy(&maclabel); @@ -1762,6 +1772,8 @@ syncache_pcblist(struct sysctl_req *req, int max_pcbs, int *pcbs_exported) SCH_UNLOCK(sch); goto exit; } + if (cr_cansee(req->td->td_ucred, sc->sc_cred) != 0) + continue; bzero(&xt, sizeof(xt)); xt.xt_len = sizeof(xt); if (sc->sc_inc.inc_isipv6)