Don't allow creating a socket with a protocol family that the current

jail doesn't support.  This involves a new function prison_check_af,
like prison_check_ip[46] but that checks only the family.

With this change, most of the errors generated by jailed sockets
shouldn't ever occur, at least until jails are changeable.

Approved by:	bz (mentor)
This commit is contained in:
Jamie Gritton 2009-02-05 14:15:18 +00:00
parent b89e82dd87
commit ca04ba6430
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=188146
3 changed files with 44 additions and 8 deletions

View File

@ -1098,6 +1098,48 @@ prison_check_ip6(struct ucred *cred, struct in6_addr *ia6)
}
#endif
/*
* Check if a jail supports the given address family.
*
* Returns 0 if not jailed or the address family is supported, EAFNOSUPPORT
* if not.
*/
int
prison_check_af(struct ucred *cred, int af)
{
int error;
KASSERT(cred != NULL, ("%s: cred is NULL", __func__));
if (!jailed(cred))
return (0);
error = 0;
switch (af)
{
#ifdef INET
case AF_INET:
if (cred->cr_prison->pr_ip4 == NULL)
error = EAFNOSUPPORT;
break;
#endif
#ifdef INET6
case AF_INET6:
if (cred->cr_prison->pr_ip6 == NULL)
error = EAFNOSUPPORT;
break;
#endif
case AF_LOCAL:
case AF_ROUTE:
break;
default:
if (jail_socket_unixiproute_only)
error = EAFNOSUPPORT;
}
return (error);
}
/*
* Check if given address belongs to the jail referenced by cred (wrapper to
* prison_check_ip[46]).

View File

@ -347,15 +347,8 @@ socreate(int dom, struct socket **aso, int type, int proto,
prp->pr_usrreqs->pru_attach == pru_attach_notsupp)
return (EPROTONOSUPPORT);
if (jailed(cred) && jail_socket_unixiproute_only &&
prp->pr_domain->dom_family != PF_LOCAL &&
prp->pr_domain->dom_family != PF_INET &&
#ifdef INET6
prp->pr_domain->dom_family != PF_INET6 &&
#endif
prp->pr_domain->dom_family != PF_ROUTE) {
if (prison_check_af(cred, prp->pr_domain->dom_family) != 0)
return (EPROTONOSUPPORT);
}
if (prp->pr_type != type)
return (EPROTOTYPE);

View File

@ -191,6 +191,7 @@ int prison_local_ip6(struct ucred *, struct in6_addr *, int);
int prison_remote_ip6(struct ucred *, struct in6_addr *);
int prison_check_ip6(struct ucred *, struct in6_addr *);
#endif
int prison_check_af(struct ucred *cred, int af);
int prison_if(struct ucred *cred, struct sockaddr *sa);
int prison_priv_check(struct ucred *cred, int priv);