Cache so_cred as inp_cred in the inpcb.
This means that inp_cred is always there, even after the socket has gone away. It also means that it is constant for the lifetime of the inp. Both facts lead to simpler code and possibly less locking. Suggested by: rwatson Reviewed by: rwatson MFC after: 6 weeks X-MFC Note: use a inp_pspare for inp_cred
This commit is contained in:
parent
848f285a65
commit
77f80e0672
@ -2941,13 +2941,9 @@ pf_socket_lookup(int direction, struct pf_pdesc *pd)
|
||||
#ifdef __FreeBSD__
|
||||
if (inp_arg != NULL) {
|
||||
INP_LOCK_ASSERT(inp_arg);
|
||||
if (inp_arg->inp_socket) {
|
||||
pd->lookup.uid = inp_arg->inp_socket->so_cred->cr_uid;
|
||||
pd->lookup.gid =
|
||||
inp_arg->inp_socket->so_cred->cr_groups[0];
|
||||
return (1);
|
||||
} else
|
||||
return (-1);
|
||||
pd->lookup.uid = inp_arg->inp_cred->cr_uid;
|
||||
pd->lookup.gid = inp_arg->inp_cred->cr_groups[0];
|
||||
return (1);
|
||||
}
|
||||
#endif
|
||||
switch (pd->proto) {
|
||||
@ -3043,15 +3039,9 @@ pf_socket_lookup(int direction, struct pf_pdesc *pd)
|
||||
return (-1);
|
||||
}
|
||||
#ifdef __FreeBSD__
|
||||
INP_RLOCK(inp);
|
||||
pd->lookup.uid = inp->inp_cred->cr_uid;
|
||||
pd->lookup.gid = inp->inp_cred->cr_groups[0];
|
||||
INP_INFO_RUNLOCK(pi);
|
||||
if ((inp->inp_socket == NULL) || (inp->inp_socket->so_cred == NULL)) {
|
||||
INP_RUNLOCK(inp);
|
||||
return (-1);
|
||||
}
|
||||
pd->lookup.uid = inp->inp_socket->so_cred->cr_uid;
|
||||
pd->lookup.gid = inp->inp_socket->so_cred->cr_groups[0];
|
||||
INP_RUNLOCK(inp);
|
||||
#else
|
||||
pd->lookup.uid = inp->inp_socket->so_euid;
|
||||
pd->lookup.gid = inp->inp_socket->so_egid;
|
||||
|
@ -197,6 +197,7 @@ in_pcballoc(struct socket *so, struct inpcbinfo *pcbinfo)
|
||||
bzero(inp, inp_zero_size);
|
||||
inp->inp_pcbinfo = pcbinfo;
|
||||
inp->inp_socket = so;
|
||||
inp->inp_cred = crhold(so->so_cred);
|
||||
inp->inp_inc.inc_fibnum = so->so_fibnum;
|
||||
#ifdef MAC
|
||||
error = mac_inpcb_init(inp, M_NOWAIT);
|
||||
@ -235,8 +236,10 @@ in_pcballoc(struct socket *so, struct inpcbinfo *pcbinfo)
|
||||
|
||||
#if defined(IPSEC) || defined(MAC)
|
||||
out:
|
||||
if (error != 0)
|
||||
if (error != 0) {
|
||||
crfree(inp->inp_cred);
|
||||
uma_zfree(pcbinfo->ipi_zone, inp);
|
||||
}
|
||||
#endif
|
||||
return (error);
|
||||
}
|
||||
@ -357,7 +360,7 @@ in_pcbbind_setup(struct inpcb *inp, struct sockaddr *nam, in_addr_t *laddrp,
|
||||
if (jailed(cred))
|
||||
prison = 1;
|
||||
if (!IN_MULTICAST(ntohl(sin->sin_addr.s_addr)) &&
|
||||
priv_check_cred(so->so_cred,
|
||||
priv_check_cred(inp->inp_cred,
|
||||
PRIV_NETINET_REUSEPORT, 0) != 0) {
|
||||
t = in_pcblookup_local(pcbinfo, sin->sin_addr,
|
||||
lport, prison ? 0 : INPLOOKUP_WILDCARD,
|
||||
@ -374,8 +377,8 @@ in_pcbbind_setup(struct inpcb *inp, struct sockaddr *nam, in_addr_t *laddrp,
|
||||
ntohl(t->inp_laddr.s_addr) != INADDR_ANY ||
|
||||
(t->inp_socket->so_options &
|
||||
SO_REUSEPORT) == 0) &&
|
||||
(so->so_cred->cr_uid !=
|
||||
t->inp_socket->so_cred->cr_uid))
|
||||
(inp->inp_cred->cr_uid !=
|
||||
t->inp_cred->cr_uid))
|
||||
return (EADDRINUSE);
|
||||
}
|
||||
if (prison && prison_ip(cred, 0, &sin->sin_addr.s_addr))
|
||||
@ -901,6 +904,7 @@ in_pcbfree(struct inpcb *inp)
|
||||
if (inp->inp_moptions != NULL)
|
||||
inp_freemoptions(inp->inp_moptions);
|
||||
inp->inp_vflag = 0;
|
||||
crfree(inp->inp_cred);
|
||||
|
||||
#ifdef MAC
|
||||
mac_inpcb_destroy(inp);
|
||||
|
@ -153,6 +153,7 @@ struct inpcb {
|
||||
void *inp_ppcb; /* (i) pointer to per-protocol pcb */
|
||||
struct inpcbinfo *inp_pcbinfo; /* (c) PCB list info */
|
||||
struct socket *inp_socket; /* (i) back pointer to socket */
|
||||
struct ucred *inp_cred; /* (c) cache of socket cred */
|
||||
|
||||
u_int32_t inp_flow; /* (i) IPv6 flow information */
|
||||
int inp_flags; /* (i) generic IP/datagram flags */
|
||||
|
@ -1977,15 +1977,11 @@ fill_ugid_cache(struct inpcb *inp, struct ip_fw_ugid *ugp)
|
||||
{
|
||||
struct ucred *cr;
|
||||
|
||||
if (inp->inp_socket != NULL) {
|
||||
cr = inp->inp_socket->so_cred;
|
||||
ugp->fw_prid = jailed(cr) ?
|
||||
cr->cr_prison->pr_id : -1;
|
||||
ugp->fw_uid = cr->cr_uid;
|
||||
ugp->fw_ngroups = cr->cr_ngroups;
|
||||
bcopy(cr->cr_groups, ugp->fw_groups,
|
||||
sizeof(ugp->fw_groups));
|
||||
}
|
||||
cr = inp->inp_cred;
|
||||
ugp->fw_prid = jailed(cr) ? cr->cr_prison->pr_id : -1;
|
||||
ugp->fw_uid = cr->cr_uid;
|
||||
ugp->fw_ngroups = cr->cr_ngroups;
|
||||
bcopy(cr->cr_groups, ugp->fw_groups, sizeof(ugp->fw_groups));
|
||||
}
|
||||
|
||||
static int
|
||||
@ -2042,12 +2038,8 @@ check_uidgid(ipfw_insn_u32 *insn, int proto, struct ifnet *oif,
|
||||
dst_ip, htons(dst_port),
|
||||
wildcard, NULL);
|
||||
if (pcb != NULL) {
|
||||
INP_RLOCK(pcb);
|
||||
if (pcb->inp_socket != NULL) {
|
||||
fill_ugid_cache(pcb, ugp);
|
||||
*ugid_lookupp = 1;
|
||||
}
|
||||
INP_RUNLOCK(pcb);
|
||||
fill_ugid_cache(pcb, ugp);
|
||||
*ugid_lookupp = 1;
|
||||
}
|
||||
INP_INFO_RUNLOCK(pi);
|
||||
if (*ugid_lookupp == 0) {
|
||||
|
@ -261,6 +261,7 @@ rip_input(struct mbuf *m, int off)
|
||||
if (inp->inp_ip_p != proto)
|
||||
continue;
|
||||
#ifdef INET6
|
||||
/* XXX inp locking */
|
||||
if ((inp->inp_vflag & INP_IPV4) == 0)
|
||||
continue;
|
||||
#endif
|
||||
@ -268,11 +269,9 @@ rip_input(struct mbuf *m, int off)
|
||||
continue;
|
||||
if (inp->inp_faddr.s_addr != ip->ip_src.s_addr)
|
||||
continue;
|
||||
INP_RLOCK(inp);
|
||||
if (jailed(inp->inp_socket->so_cred) &&
|
||||
(htonl(prison_getip(inp->inp_socket->so_cred)) !=
|
||||
if (jailed(inp->inp_cred) &&
|
||||
(htonl(prison_getip(inp->inp_cred)) !=
|
||||
ip->ip_dst.s_addr)) {
|
||||
INP_RUNLOCK(inp);
|
||||
continue;
|
||||
}
|
||||
if (last) {
|
||||
@ -284,12 +283,14 @@ rip_input(struct mbuf *m, int off)
|
||||
/* XXX count dropped packet */
|
||||
INP_RUNLOCK(last);
|
||||
}
|
||||
INP_RLOCK(inp);
|
||||
last = inp;
|
||||
}
|
||||
LIST_FOREACH(inp, &V_ripcbinfo.ipi_hashbase[0], inp_hash) {
|
||||
if (inp->inp_ip_p && inp->inp_ip_p != proto)
|
||||
continue;
|
||||
#ifdef INET6
|
||||
/* XXX inp locking */
|
||||
if ((inp->inp_vflag & INP_IPV4) == 0)
|
||||
continue;
|
||||
#endif
|
||||
@ -299,9 +300,8 @@ rip_input(struct mbuf *m, int off)
|
||||
if (inp->inp_faddr.s_addr &&
|
||||
inp->inp_faddr.s_addr != ip->ip_src.s_addr)
|
||||
continue;
|
||||
INP_RLOCK(inp);
|
||||
if (jailed(inp->inp_socket->so_cred) &&
|
||||
(htonl(prison_getip(inp->inp_socket->so_cred)) !=
|
||||
if (jailed(inp->inp_cred) &&
|
||||
(htonl(prison_getip(inp->inp_cred)) !=
|
||||
ip->ip_dst.s_addr)) {
|
||||
INP_RUNLOCK(inp);
|
||||
continue;
|
||||
@ -315,6 +315,7 @@ rip_input(struct mbuf *m, int off)
|
||||
/* XXX count dropped packet */
|
||||
INP_RUNLOCK(last);
|
||||
}
|
||||
INP_RLOCK(inp);
|
||||
last = inp;
|
||||
}
|
||||
INP_INFO_RUNLOCK(&V_ripcbinfo);
|
||||
@ -365,9 +366,9 @@ rip_output(struct mbuf *m, struct socket *so, u_long dst)
|
||||
ip->ip_off = 0;
|
||||
ip->ip_p = inp->inp_ip_p;
|
||||
ip->ip_len = m->m_pkthdr.len;
|
||||
if (jailed(inp->inp_socket->so_cred))
|
||||
if (jailed(inp->inp_cred))
|
||||
ip->ip_src.s_addr =
|
||||
htonl(prison_getip(inp->inp_socket->so_cred));
|
||||
htonl(prison_getip(inp->inp_cred));
|
||||
else
|
||||
ip->ip_src = inp->inp_laddr;
|
||||
ip->ip_dst.s_addr = dst;
|
||||
@ -379,9 +380,9 @@ rip_output(struct mbuf *m, struct socket *so, u_long dst)
|
||||
}
|
||||
INP_RLOCK(inp);
|
||||
ip = mtod(m, struct ip *);
|
||||
if (jailed(inp->inp_socket->so_cred)) {
|
||||
if (jailed(inp->inp_cred)) {
|
||||
if (ip->ip_src.s_addr !=
|
||||
htonl(prison_getip(inp->inp_socket->so_cred))) {
|
||||
htonl(prison_getip(inp->inp_cred))) {
|
||||
INP_RUNLOCK(inp);
|
||||
m_freem(m);
|
||||
return (EPERM);
|
||||
|
@ -1107,7 +1107,7 @@ tcp_getcred(SYSCTL_HANDLER_ARGS)
|
||||
error = cr_canseesocket(req->td->td_ucred,
|
||||
inp->inp_socket);
|
||||
if (error == 0)
|
||||
cru2x(inp->inp_socket->so_cred, &xuc);
|
||||
cru2x(inp->inp_cred, &xuc);
|
||||
INP_RUNLOCK(inp);
|
||||
} else {
|
||||
INP_INFO_RUNLOCK(&V_tcbinfo);
|
||||
@ -1171,7 +1171,7 @@ tcp6_getcred(SYSCTL_HANDLER_ARGS)
|
||||
error = cr_canseesocket(req->td->td_ucred,
|
||||
inp->inp_socket);
|
||||
if (error == 0)
|
||||
cru2x(inp->inp_socket->so_cred, &xuc);
|
||||
cru2x(inp->inp_cred, &xuc);
|
||||
INP_RUNLOCK(inp);
|
||||
} else {
|
||||
INP_INFO_RUNLOCK(&V_tcbinfo);
|
||||
|
@ -761,7 +761,7 @@ udp_getcred(SYSCTL_HANDLER_ARGS)
|
||||
error = cr_canseesocket(req->td->td_ucred,
|
||||
inp->inp_socket);
|
||||
if (error == 0)
|
||||
cru2x(inp->inp_socket->so_cred, &xuc);
|
||||
cru2x(inp->inp_cred, &xuc);
|
||||
INP_RUNLOCK(inp);
|
||||
} else {
|
||||
INP_INFO_RUNLOCK(&V_udbinfo);
|
||||
|
@ -189,7 +189,7 @@ in6_pcbbind(register struct inpcb *inp, struct sockaddr *nam,
|
||||
0))
|
||||
return (EACCES);
|
||||
if (!IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr) &&
|
||||
priv_check_cred(so->so_cred,
|
||||
priv_check_cred(inp->inp_cred,
|
||||
PRIV_NETINET_REUSEPORT, 0) != 0) {
|
||||
t = in6_pcblookup_local(pcbinfo,
|
||||
&sin6->sin6_addr, lport,
|
||||
@ -201,8 +201,8 @@ in6_pcbbind(register struct inpcb *inp, struct sockaddr *nam,
|
||||
(!IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr) ||
|
||||
!IN6_IS_ADDR_UNSPECIFIED(&t->in6p_laddr) ||
|
||||
(t->inp_socket->so_options & SO_REUSEPORT)
|
||||
== 0) && (so->so_cred->cr_uid !=
|
||||
t->inp_socket->so_cred->cr_uid))
|
||||
== 0) && (inp->inp_cred->cr_uid !=
|
||||
t->inp_cred->cr_uid))
|
||||
return (EADDRINUSE);
|
||||
if ((inp->inp_flags & IN6P_IPV6_V6ONLY) == 0 &&
|
||||
IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
|
||||
@ -218,8 +218,8 @@ in6_pcbbind(register struct inpcb *inp, struct sockaddr *nam,
|
||||
(so->so_type != SOCK_STREAM ||
|
||||
ntohl(t->inp_faddr.s_addr) ==
|
||||
INADDR_ANY) &&
|
||||
(so->so_cred->cr_uid !=
|
||||
t->inp_socket->so_cred->cr_uid))
|
||||
(inp->inp_cred->cr_uid !=
|
||||
t->inp_cred->cr_uid))
|
||||
return (EADDRINUSE);
|
||||
}
|
||||
}
|
||||
@ -323,7 +323,7 @@ in6_pcbladdr(register struct inpcb *inp, struct sockaddr *nam,
|
||||
*/
|
||||
*plocal_addr6 = in6_selectsrc(sin6, inp->in6p_outputopts,
|
||||
inp, NULL,
|
||||
inp->inp_socket->so_cred,
|
||||
inp->inp_cred,
|
||||
&ifp, &error);
|
||||
if (ifp && scope_ambiguous &&
|
||||
(error = in6_setscope(&sin6->sin6_addr, ifp, NULL)) != 0) {
|
||||
|
@ -466,7 +466,7 @@ udp6_getcred(SYSCTL_HANDLER_ARGS)
|
||||
error = cr_canseesocket(req->td->td_ucred,
|
||||
inp->inp_socket);
|
||||
if (error == 0)
|
||||
cru2x(inp->inp_socket->so_cred, &xuc);
|
||||
cru2x(inp->inp_cred, &xuc);
|
||||
INP_RUNLOCK(inp);
|
||||
} else {
|
||||
INP_INFO_RUNLOCK(&V_udbinfo);
|
||||
|
Loading…
x
Reference in New Issue
Block a user