From owner-svn-src-head@FreeBSD.ORG Sun Dec 13 13:57:33 2009 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 92FAB106566C; Sun, 13 Dec 2009 13:57:33 +0000 (UTC) (envelope-from bz@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 812858FC21; Sun, 13 Dec 2009 13:57:33 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id nBDDvX6l088065; Sun, 13 Dec 2009 13:57:33 GMT (envelope-from bz@svn.freebsd.org) Received: (from bz@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id nBDDvXVT088059; Sun, 13 Dec 2009 13:57:33 GMT (envelope-from bz@svn.freebsd.org) Message-Id: <200912131357.nBDDvXVT088059@svn.freebsd.org> From: "Bjoern A. Zeeb" Date: Sun, 13 Dec 2009 13:57:33 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r200473 - in head/sys: kern net netinet netinet6 sys X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 13 Dec 2009 13:57:33 -0000 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);