summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbz <bz@FreeBSD.org>2008-08-23 14:22:12 +0000
committerbz <bz@FreeBSD.org>2008-08-23 14:22:12 +0000
commitc38717bcc7cc2cd9b41dc0888928a5775db939db (patch)
treef510a41839e772527e6ef3b4d90bf96934f29748
parente7f32da60c7604abdce7808278d857e6ec6fe989 (diff)
downloadFreeBSD-src-c38717bcc7cc2cd9b41dc0888928a5775db939db.zip
FreeBSD-src-c38717bcc7cc2cd9b41dc0888928a5775db939db.tar.gz
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
-rw-r--r--sys/netinet/tcp_syncache.c12
1 files changed, 12 insertions, 0 deletions
diff --git a/sys/netinet/tcp_syncache.c b/sys/netinet/tcp_syncache.c
index 99f12c2..60a0295 100644
--- a/sys/netinet/tcp_syncache.c
+++ b/sys/netinet/tcp_syncache.c
@@ -53,6 +53,7 @@ __FBSDID("$FreeBSD$");
#include <sys/socket.h>
#include <sys/socketvar.h>
#include <sys/syslog.h>
+#include <sys/ucred.h>
#include <sys/vimage.h>
#include <vm/uma.h>
@@ -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)
OpenPOWER on IntegriCloud