Date: Sun, 13 Dec 2009 13:57:33 +0000 (UTC) From: "Bjoern A. Zeeb" <bz@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r200473 - in head/sys: kern net netinet netinet6 sys Message-ID: <200912131357.nBDDvXVT088059@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: bz Date: Sun Dec 13 13:57:32 2009 New Revision: 200473 URL: http://svn.freebsd.org/changeset/base/200473 Log: Throughout the network stack we have a few places of if (jailed(cred)) left. If you are running with a vnet (virtual network stack) those will return true and defer you to classic IP-jails handling and thus things will be "denied" or returned with an error. Work around this problem by introducing another "jailed()" function, jailed_without_vnet(), that also takes vnets into account, and permits the calls, should the jail from the given cred have its own virtual network stack. We cannot change the classic jailed() call to do that, as it is used outside the network stack as well. Discussed with: julian, zec, jamie, rwatson (back in Sept) MFC after: 5 days Modified: head/sys/kern/kern_jail.c head/sys/net/rtsock.c head/sys/netinet/raw_ip.c head/sys/netinet6/raw_ip6.c head/sys/sys/jail.h Modified: head/sys/kern/kern_jail.c ============================================================================== --- head/sys/kern/kern_jail.c Sun Dec 13 13:40:41 2009 (r200472) +++ head/sys/kern/kern_jail.c Sun Dec 13 13:57:32 2009 (r200473) @@ -3161,7 +3161,7 @@ prison_check_af(struct ucred *cred, int pr = cred->cr_prison; #ifdef VIMAGE /* Prisons with their own network stack are not limited. */ - if (pr->pr_flags & PR_VNET) + if (prison_owns_vnet(cred)) return (0); #endif @@ -3222,6 +3222,11 @@ prison_if(struct ucred *cred, struct soc KASSERT(cred != NULL, ("%s: cred is NULL", __func__)); KASSERT(sa != NULL, ("%s: sa is NULL", __func__)); +#ifdef VIMAGE + if (prison_owns_vnet(cred)) + return (0); +#endif + error = 0; switch (sa->sa_family) { @@ -3279,6 +3284,24 @@ jailed(struct ucred *cred) } /* + * Return 1 if the passed credential is in a jail and that jail does not + * have its own virtual network stack, otherwise 0. + */ +int +jailed_without_vnet(struct ucred *cred) +{ + + if (!jailed(cred)) + return (0); +#ifdef VIMAGE + if (prison_owns_vnet(cred)) + return (0); +#endif + + return (1); +} + +/* * Return the correct hostname (domainname, et al) for the passed credential. */ void Modified: head/sys/net/rtsock.c ============================================================================== --- head/sys/net/rtsock.c Sun Dec 13 13:40:41 2009 (r200472) +++ head/sys/net/rtsock.c Sun Dec 13 13:57:32 2009 (r200473) @@ -651,7 +651,7 @@ route_output(struct mbuf *m, struct sock report: RT_LOCK_ASSERT(rt); if ((rt->rt_flags & RTF_HOST) == 0 - ? jailed(curthread->td_ucred) + ? jailed_without_vnet(curthread->td_ucred) : prison_if(curthread->td_ucred, rt_key(rt)) != 0) { RT_UNLOCK(rt); @@ -1312,7 +1312,7 @@ sysctl_dumpentry(struct radix_node *rn, if (w->w_op == NET_RT_FLAGS && !(rt->rt_flags & w->w_arg)) return 0; if ((rt->rt_flags & RTF_HOST) == 0 - ? jailed(w->w_req->td->td_ucred) + ? jailed_without_vnet(w->w_req->td->td_ucred) : prison_if(w->w_req->td->td_ucred, rt_key(rt)) != 0) return (0); bzero((caddr_t)&info, sizeof(info)); Modified: head/sys/netinet/raw_ip.c ============================================================================== --- head/sys/netinet/raw_ip.c Sun Dec 13 13:40:41 2009 (r200472) +++ head/sys/netinet/raw_ip.c Sun Dec 13 13:57:32 2009 (r200473) @@ -291,7 +291,7 @@ rip_input(struct mbuf *m, int off) continue; if (inp->inp_faddr.s_addr != ip->ip_src.s_addr) continue; - if (jailed(inp->inp_cred)) { + if (jailed_without_vnet(inp->inp_cred)) { /* * XXX: If faddr was bound to multicast group, * jailed raw socket will drop datagram. @@ -325,7 +325,7 @@ rip_input(struct mbuf *m, int off) if (!in_nullhost(inp->inp_faddr) && !in_hosteq(inp->inp_faddr, ip->ip_src)) continue; - if (jailed(inp->inp_cred)) { + if (jailed_without_vnet(inp->inp_cred)) { /* * Allow raw socket in jail to receive multicast; * assume process had PRIV_NETINET_RAW at attach, Modified: head/sys/netinet6/raw_ip6.c ============================================================================== --- head/sys/netinet6/raw_ip6.c Sun Dec 13 13:40:41 2009 (r200472) +++ head/sys/netinet6/raw_ip6.c Sun Dec 13 13:57:32 2009 (r200473) @@ -184,7 +184,7 @@ rip6_input(struct mbuf **mp, int *offp, if (!IN6_IS_ADDR_UNSPECIFIED(&in6p->in6p_faddr) && !IN6_ARE_ADDR_EQUAL(&in6p->in6p_faddr, &ip6->ip6_src)) continue; - if (jailed(in6p->inp_cred)) { + if (jailed_without_vnet(in6p->inp_cred)) { /* * Allow raw socket in jail to receive multicast; * assume process had PRIV_NETINET_RAW at attach, Modified: head/sys/sys/jail.h ============================================================================== --- head/sys/sys/jail.h Sun Dec 13 13:40:41 2009 (r200472) +++ head/sys/sys/jail.h Sun Dec 13 13:57:32 2009 (r200473) @@ -335,6 +335,7 @@ struct mount; struct sockaddr; struct statfs; int jailed(struct ucred *cred); +int jailed_without_vnet(struct ucred *); void getcredhostname(struct ucred *, char *, size_t); void getcreddomainname(struct ucred *, char *, size_t); void getcredhostuuid(struct ucred *, char *, size_t);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200912131357.nBDDvXVT088059>