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:
parent
3b7c344be4
commit
c06f087ccb
@ -53,6 +53,7 @@ __FBSDID("$FreeBSD$");
|
|||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <sys/socketvar.h>
|
#include <sys/socketvar.h>
|
||||||
#include <sys/syslog.h>
|
#include <sys/syslog.h>
|
||||||
|
#include <sys/ucred.h>
|
||||||
#include <sys/vimage.h>
|
#include <sys/vimage.h>
|
||||||
|
|
||||||
#include <vm/uma.h>
|
#include <vm/uma.h>
|
||||||
@ -146,6 +147,7 @@ struct syncache {
|
|||||||
#ifdef MAC
|
#ifdef MAC
|
||||||
struct label *sc_label; /* MAC label reference */
|
struct label *sc_label; /* MAC label reference */
|
||||||
#endif
|
#endif
|
||||||
|
struct ucred *sc_cred; /* cred cache for jail checks */
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef TCP_OFFLOAD_DISABLE
|
#ifdef TCP_OFFLOAD_DISABLE
|
||||||
@ -264,6 +266,8 @@ syncache_free(struct syncache *sc)
|
|||||||
{
|
{
|
||||||
if (sc->sc_ipopts)
|
if (sc->sc_ipopts)
|
||||||
(void) m_free(sc->sc_ipopts);
|
(void) m_free(sc->sc_ipopts);
|
||||||
|
if (sc->sc_cred)
|
||||||
|
crfree(sc->sc_cred);
|
||||||
#ifdef MAC
|
#ifdef MAC
|
||||||
mac_syncache_destroy(&sc->sc_label);
|
mac_syncache_destroy(&sc->sc_label);
|
||||||
#endif
|
#endif
|
||||||
@ -1010,6 +1014,7 @@ _syncache_add(struct in_conninfo *inc, struct tcpopt *to, struct tcphdr *th,
|
|||||||
struct label *maclabel;
|
struct label *maclabel;
|
||||||
#endif
|
#endif
|
||||||
struct syncache scs;
|
struct syncache scs;
|
||||||
|
struct ucred *cred;
|
||||||
|
|
||||||
INP_INFO_WLOCK_ASSERT(&V_tcbinfo);
|
INP_INFO_WLOCK_ASSERT(&V_tcbinfo);
|
||||||
INP_WLOCK_ASSERT(inp); /* listen socket */
|
INP_WLOCK_ASSERT(inp); /* listen socket */
|
||||||
@ -1022,6 +1027,7 @@ _syncache_add(struct in_conninfo *inc, struct tcpopt *to, struct tcphdr *th,
|
|||||||
*/
|
*/
|
||||||
so = *lsop;
|
so = *lsop;
|
||||||
tp = sototcpcb(so);
|
tp = sototcpcb(so);
|
||||||
|
cred = crhold(so->so_cred);
|
||||||
|
|
||||||
#ifdef INET6
|
#ifdef INET6
|
||||||
if (inc->inc_isipv6 &&
|
if (inc->inc_isipv6 &&
|
||||||
@ -1151,6 +1157,8 @@ _syncache_add(struct in_conninfo *inc, struct tcpopt *to, struct tcphdr *th,
|
|||||||
#ifdef MAC
|
#ifdef MAC
|
||||||
sc->sc_label = maclabel;
|
sc->sc_label = maclabel;
|
||||||
#endif
|
#endif
|
||||||
|
sc->sc_cred = cred;
|
||||||
|
cred = NULL;
|
||||||
sc->sc_ipopts = ipopts;
|
sc->sc_ipopts = ipopts;
|
||||||
sc->sc_inc.inc_fibnum = inp->inp_inc.inc_fibnum;
|
sc->sc_inc.inc_fibnum = inp->inp_inc.inc_fibnum;
|
||||||
bcopy(inc, &sc->sc_inc, sizeof(struct in_conninfo));
|
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:
|
done:
|
||||||
|
if (cred != NULL)
|
||||||
|
crfree(cred);
|
||||||
#ifdef MAC
|
#ifdef MAC
|
||||||
if (sc == &scs)
|
if (sc == &scs)
|
||||||
mac_syncache_destroy(&maclabel);
|
mac_syncache_destroy(&maclabel);
|
||||||
@ -1762,6 +1772,8 @@ syncache_pcblist(struct sysctl_req *req, int max_pcbs, int *pcbs_exported)
|
|||||||
SCH_UNLOCK(sch);
|
SCH_UNLOCK(sch);
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
if (cr_cansee(req->td->td_ucred, sc->sc_cred) != 0)
|
||||||
|
continue;
|
||||||
bzero(&xt, sizeof(xt));
|
bzero(&xt, sizeof(xt));
|
||||||
xt.xt_len = sizeof(xt);
|
xt.xt_len = sizeof(xt);
|
||||||
if (sc->sc_inc.inc_isipv6)
|
if (sc->sc_inc.inc_isipv6)
|
||||||
|
Loading…
Reference in New Issue
Block a user