diff options
author | jamie <jamie@FreeBSD.org> | 2009-02-05 14:15:18 +0000 |
---|---|---|
committer | jamie <jamie@FreeBSD.org> | 2009-02-05 14:15:18 +0000 |
commit | 8f639d4b9ab34b25f907b609cbfdc7610647394f (patch) | |
tree | 52b30eb1b41e3912554ac0506d04abbeb25da407 | |
parent | 12bbe1869f5926ca7e3457f5424afdca31a1189b (diff) | |
download | FreeBSD-src-8f639d4b9ab34b25f907b609cbfdc7610647394f.zip FreeBSD-src-8f639d4b9ab34b25f907b609cbfdc7610647394f.tar.gz |
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)
-rw-r--r-- | sys/kern/kern_jail.c | 42 | ||||
-rw-r--r-- | sys/kern/uipc_socket.c | 9 | ||||
-rw-r--r-- | sys/sys/jail.h | 1 |
3 files changed, 44 insertions, 8 deletions
diff --git a/sys/kern/kern_jail.c b/sys/kern/kern_jail.c index 9b2f6d8..e802780 100644 --- a/sys/kern/kern_jail.c +++ b/sys/kern/kern_jail.c @@ -1099,6 +1099,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]). * diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c index c815ac1..9d9a731 100644 --- a/sys/kern/uipc_socket.c +++ b/sys/kern/uipc_socket.c @@ -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); diff --git a/sys/sys/jail.h b/sys/sys/jail.h index 7888a80..74c7a6a 100644 --- a/sys/sys/jail.h +++ b/sys/sys/jail.h @@ -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); |