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
This commit is contained in:
Bjoern A. Zeeb 2008-08-23 14:22:12 +00:00
parent 3b7c344be4
commit c06f087ccb
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=182056

View File

@ -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)