Standardize the various prison_foo_ip[46] functions and prison_if to
return zero on success and an error code otherwise. The possible errors are EADDRNOTAVAIL if an address being checked for doesn't match the prison, and EAFNOSUPPORT if the prison doesn't have any addresses in that address family. For most callers of these functions, use the returned error code instead of e.g. a hard-coded EADDRNOTAVAIL or EINVAL. Always include a jailed() check in these functions, where a non-jailed cred always returns success (and makes no changes). Remove the explicit jailed() checks that preceded many of the function calls. Approved by: bz (mentor)
This commit is contained in:
parent
2926f8fa43
commit
12bbe1869f
@ -28,7 +28,7 @@
|
||||
.\" From: @(#)send.2 8.2 (Berkeley) 2/21/94
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd September 13, 2006
|
||||
.Dd February 5, 2009
|
||||
.Dt SEND 2
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -190,7 +190,7 @@ receiver is not listening on the remote port.
|
||||
The remote host was down.
|
||||
.It Bq Er ENETDOWN
|
||||
The remote network was down.
|
||||
.It Bq Er EPERM
|
||||
.It Bq Er EADDRNOTAVAIL
|
||||
The process using a
|
||||
.Dv SOCK_RAW
|
||||
socket was jailed and the source
|
||||
|
@ -217,7 +217,7 @@ prison_check_conflicting_ips(struct prison *p)
|
||||
if ((p->pr_ip4s >= 1 && pr->pr_ip4s > 1) ||
|
||||
(p->pr_ip4s > 1 && pr->pr_ip4s >= 1)) {
|
||||
for (i = 0; i < p->pr_ip4s; i++) {
|
||||
if (_prison_check_ip4(pr, &p->pr_ip4[i]))
|
||||
if (_prison_check_ip4(pr, &p->pr_ip4[i]) == 0)
|
||||
return (EINVAL);
|
||||
}
|
||||
}
|
||||
@ -226,7 +226,7 @@ prison_check_conflicting_ips(struct prison *p)
|
||||
if ((p->pr_ip6s >= 1 && pr->pr_ip6s > 1) ||
|
||||
(p->pr_ip6s > 1 && pr->pr_ip6s >= 1)) {
|
||||
for (i = 0; i < p->pr_ip6s; i++) {
|
||||
if (_prison_check_ip6(pr, &p->pr_ip6[i]))
|
||||
if (_prison_check_ip6(pr, &p->pr_ip6[i]) == 0)
|
||||
return (EINVAL);
|
||||
}
|
||||
}
|
||||
@ -807,9 +807,10 @@ prison_proc_free(struct prison *pr)
|
||||
* Pass back primary IPv4 address of this jail.
|
||||
*
|
||||
* If not jailed return success but do not alter the address. Caller has to
|
||||
* make sure to intialize it correctly (INADDR_ANY).
|
||||
* make sure to intialize it correctly (e.g. INADDR_ANY).
|
||||
*
|
||||
* Returns 0 on success, 1 on error. Address returned in NBO.
|
||||
* Returns 0 on success, EAFNOSUPPORT if the jail doesn't allow IPv4.
|
||||
* Address returned in NBO.
|
||||
*/
|
||||
int
|
||||
prison_get_ip4(struct ucred *cred, struct in_addr *ia)
|
||||
@ -823,7 +824,7 @@ prison_get_ip4(struct ucred *cred, struct in_addr *ia)
|
||||
return (0);
|
||||
|
||||
if (cred->cr_prison->pr_ip4 == NULL)
|
||||
return (1);
|
||||
return (EAFNOSUPPORT);
|
||||
|
||||
ia->s_addr = cred->cr_prison->pr_ip4[0].s_addr;
|
||||
return (0);
|
||||
@ -833,8 +834,9 @@ prison_get_ip4(struct ucred *cred, struct in_addr *ia)
|
||||
* Make sure our (source) address is set to something meaningful to this
|
||||
* jail.
|
||||
*
|
||||
* Returns 0 on success, 1 on error. Address passed in in NBO and returned
|
||||
* in NBO.
|
||||
* Returns 0 if not jailed or if address belongs to jail, EADDRNOTAVAIL if
|
||||
* the address doesn't belong, or EAFNOSUPPORT if the jail doesn't allow IPv4.
|
||||
* Address passed in in NBO and returned in NBO.
|
||||
*/
|
||||
int
|
||||
prison_local_ip4(struct ucred *cred, struct in_addr *ia)
|
||||
@ -847,7 +849,7 @@ prison_local_ip4(struct ucred *cred, struct in_addr *ia)
|
||||
if (!jailed(cred))
|
||||
return (0);
|
||||
if (cred->cr_prison->pr_ip4 == NULL)
|
||||
return (1);
|
||||
return (EAFNOSUPPORT);
|
||||
|
||||
ia0.s_addr = ntohl(ia->s_addr);
|
||||
if (ia0.s_addr == INADDR_LOOPBACK) {
|
||||
@ -855,25 +857,23 @@ prison_local_ip4(struct ucred *cred, struct in_addr *ia)
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* In case there is only 1 IPv4 address, bind directly.
|
||||
*/
|
||||
if (ia0.s_addr == INADDR_ANY && cred->cr_prison->pr_ip4s == 1) {
|
||||
ia->s_addr = cred->cr_prison->pr_ip4[0].s_addr;
|
||||
if (ia0.s_addr == INADDR_ANY) {
|
||||
/*
|
||||
* In case there is only 1 IPv4 address, bind directly.
|
||||
*/
|
||||
if (cred->cr_prison->pr_ip4s == 1)
|
||||
ia->s_addr = cred->cr_prison->pr_ip4[0].s_addr;
|
||||
return (0);
|
||||
}
|
||||
|
||||
if (ia0.s_addr == INADDR_ANY || prison_check_ip4(cred, ia))
|
||||
return (0);
|
||||
|
||||
return (1);
|
||||
return (_prison_check_ip4(cred->cr_prison, ia));
|
||||
}
|
||||
|
||||
/*
|
||||
* Rewrite destination address in case we will connect to loopback address.
|
||||
*
|
||||
* Returns 0 on success, 1 on error. Address passed in in NBO and returned
|
||||
* in NBO.
|
||||
* Returns 0 on success, EAFNOSUPPORT if the jail doesn't allow IPv4.
|
||||
* Address passed in in NBO and returned in NBO.
|
||||
*/
|
||||
int
|
||||
prison_remote_ip4(struct ucred *cred, struct in_addr *ia)
|
||||
@ -885,7 +885,8 @@ prison_remote_ip4(struct ucred *cred, struct in_addr *ia)
|
||||
if (!jailed(cred))
|
||||
return (0);
|
||||
if (cred->cr_prison->pr_ip4 == NULL)
|
||||
return (1);
|
||||
return (EAFNOSUPPORT);
|
||||
|
||||
if (ntohl(ia->s_addr) == INADDR_LOOPBACK) {
|
||||
ia->s_addr = cred->cr_prison->pr_ip4[0].s_addr;
|
||||
return (0);
|
||||
@ -898,23 +899,22 @@ prison_remote_ip4(struct ucred *cred, struct in_addr *ia)
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if given address belongs to the jail referenced by cred.
|
||||
* Check if given address belongs to the jail referenced by cred/prison.
|
||||
*
|
||||
* Returns 1 if address belongs to jail, 0 if not. Address passed in in NBO.
|
||||
* Returns 0 if not jailed or if address belongs to jail, EADDRNOTAVAIL if
|
||||
* the address doesn't belong, or EAFNOSUPPORT if the jail doesn't allow IPv4.
|
||||
* Address passed in in NBO.
|
||||
*/
|
||||
static int
|
||||
_prison_check_ip4(struct prison *pr, struct in_addr *ia)
|
||||
{
|
||||
int i, a, z, d;
|
||||
|
||||
if (pr->pr_ip4 == NULL)
|
||||
return (0);
|
||||
|
||||
/*
|
||||
* Check the primary IP.
|
||||
*/
|
||||
if (pr->pr_ip4[0].s_addr == ia->s_addr)
|
||||
return (1);
|
||||
return (0);
|
||||
|
||||
/*
|
||||
* All the other IPs are sorted so we can do a binary search.
|
||||
@ -929,9 +929,10 @@ _prison_check_ip4(struct prison *pr, struct in_addr *ia)
|
||||
else if (d < 0)
|
||||
a = i + 1;
|
||||
else
|
||||
return (1);
|
||||
return (0);
|
||||
}
|
||||
return (0);
|
||||
|
||||
return (EADDRNOTAVAIL);
|
||||
}
|
||||
|
||||
int
|
||||
@ -942,7 +943,9 @@ prison_check_ip4(struct ucred *cred, struct in_addr *ia)
|
||||
KASSERT(ia != NULL, ("%s: ia is NULL", __func__));
|
||||
|
||||
if (!jailed(cred))
|
||||
return (1);
|
||||
return (0);
|
||||
if (cred->cr_prison->pr_ip4 == NULL)
|
||||
return (EAFNOSUPPORT);
|
||||
|
||||
return (_prison_check_ip4(cred->cr_prison, ia));
|
||||
}
|
||||
@ -953,9 +956,9 @@ prison_check_ip4(struct ucred *cred, struct in_addr *ia)
|
||||
* Pass back primary IPv6 address for this jail.
|
||||
*
|
||||
* If not jailed return success but do not alter the address. Caller has to
|
||||
* make sure to intialize it correctly (IN6ADDR_ANY_INIT).
|
||||
* make sure to intialize it correctly (e.g. IN6ADDR_ANY_INIT).
|
||||
*
|
||||
* Returns 0 on success, 1 on error.
|
||||
* Returns 0 on success, EAFNOSUPPORT if the jail doesn't allow IPv6.
|
||||
*/
|
||||
int
|
||||
prison_get_ip6(struct ucred *cred, struct in6_addr *ia6)
|
||||
@ -967,7 +970,8 @@ prison_get_ip6(struct ucred *cred, struct in6_addr *ia6)
|
||||
if (!jailed(cred))
|
||||
return (0);
|
||||
if (cred->cr_prison->pr_ip6 == NULL)
|
||||
return (1);
|
||||
return (EAFNOSUPPORT);
|
||||
|
||||
bcopy(&cred->cr_prison->pr_ip6[0], ia6, sizeof(struct in6_addr));
|
||||
return (0);
|
||||
}
|
||||
@ -978,7 +982,8 @@ prison_get_ip6(struct ucred *cred, struct in6_addr *ia6)
|
||||
* v6only should be set based on (inp->inp_flags & IN6P_IPV6_V6ONLY != 0)
|
||||
* when needed while binding.
|
||||
*
|
||||
* Returns 0 on success, 1 on error.
|
||||
* Returns 0 if not jailed or if address belongs to jail, EADDRNOTAVAIL if
|
||||
* the address doesn't belong, or EAFNOSUPPORT if the jail doesn't allow IPv6.
|
||||
*/
|
||||
int
|
||||
prison_local_ip6(struct ucred *cred, struct in6_addr *ia6, int v6only)
|
||||
@ -990,32 +995,32 @@ prison_local_ip6(struct ucred *cred, struct in6_addr *ia6, int v6only)
|
||||
if (!jailed(cred))
|
||||
return (0);
|
||||
if (cred->cr_prison->pr_ip6 == NULL)
|
||||
return (1);
|
||||
return (EAFNOSUPPORT);
|
||||
|
||||
if (IN6_IS_ADDR_LOOPBACK(ia6)) {
|
||||
bcopy(&cred->cr_prison->pr_ip6[0], ia6,
|
||||
sizeof(struct in6_addr));
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* In case there is only 1 IPv6 address, and v6only is true, then
|
||||
* bind directly.
|
||||
*/
|
||||
if (v6only != 0 && IN6_IS_ADDR_UNSPECIFIED(ia6) &&
|
||||
cred->cr_prison->pr_ip6s == 1) {
|
||||
bcopy(&cred->cr_prison->pr_ip6[0], ia6,
|
||||
sizeof(struct in6_addr));
|
||||
if (IN6_IS_ADDR_UNSPECIFIED(ia6)) {
|
||||
/*
|
||||
* In case there is only 1 IPv6 address, and v6only is true,
|
||||
* then bind directly.
|
||||
*/
|
||||
if (v6only != 0 && cred->cr_prison->pr_ip6s == 1)
|
||||
bcopy(&cred->cr_prison->pr_ip6[0], ia6,
|
||||
sizeof(struct in6_addr));
|
||||
return (0);
|
||||
}
|
||||
if (IN6_IS_ADDR_UNSPECIFIED(ia6) || prison_check_ip6(cred, ia6))
|
||||
return (0);
|
||||
return (1);
|
||||
|
||||
return (_prison_check_ip6(cred->cr_prison, ia6));
|
||||
}
|
||||
|
||||
/*
|
||||
* Rewrite destination address in case we will connect to loopback address.
|
||||
*
|
||||
* Returns 0 on success, 1 on error.
|
||||
* Returns 0 on success, EAFNOSUPPORT if the jail doesn't allow IPv6.
|
||||
*/
|
||||
int
|
||||
prison_remote_ip6(struct ucred *cred, struct in6_addr *ia6)
|
||||
@ -1027,7 +1032,8 @@ prison_remote_ip6(struct ucred *cred, struct in6_addr *ia6)
|
||||
if (!jailed(cred))
|
||||
return (0);
|
||||
if (cred->cr_prison->pr_ip6 == NULL)
|
||||
return (1);
|
||||
return (EAFNOSUPPORT);
|
||||
|
||||
if (IN6_IS_ADDR_LOOPBACK(ia6)) {
|
||||
bcopy(&cred->cr_prison->pr_ip6[0], ia6,
|
||||
sizeof(struct in6_addr));
|
||||
@ -1041,23 +1047,21 @@ prison_remote_ip6(struct ucred *cred, struct in6_addr *ia6)
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if given address belongs to the jail referenced by cred.
|
||||
* Check if given address belongs to the jail referenced by cred/prison.
|
||||
*
|
||||
* Returns 1 if address belongs to jail, 0 if not.
|
||||
* Returns 0 if not jailed or if address belongs to jail, EADDRNOTAVAIL if
|
||||
* the address doesn't belong, or EAFNOSUPPORT if the jail doesn't allow IPv6.
|
||||
*/
|
||||
static int
|
||||
_prison_check_ip6(struct prison *pr, struct in6_addr *ia6)
|
||||
{
|
||||
int i, a, z, d;
|
||||
|
||||
if (pr->pr_ip6 == NULL)
|
||||
return (0);
|
||||
|
||||
/*
|
||||
* Check the primary IP.
|
||||
*/
|
||||
if (IN6_ARE_ADDR_EQUAL(&pr->pr_ip6[0], ia6))
|
||||
return (1);
|
||||
return (0);
|
||||
|
||||
/*
|
||||
* All the other IPs are sorted so we can do a binary search.
|
||||
@ -1072,9 +1076,10 @@ _prison_check_ip6(struct prison *pr, struct in6_addr *ia6)
|
||||
else if (d < 0)
|
||||
a = i + 1;
|
||||
else
|
||||
return (1);
|
||||
return (0);
|
||||
}
|
||||
return (0);
|
||||
|
||||
return (EADDRNOTAVAIL);
|
||||
}
|
||||
|
||||
int
|
||||
@ -1085,7 +1090,9 @@ prison_check_ip6(struct ucred *cred, struct in6_addr *ia6)
|
||||
KASSERT(ia6 != NULL, ("%s: ia6 is NULL", __func__));
|
||||
|
||||
if (!jailed(cred))
|
||||
return (1);
|
||||
return (0);
|
||||
if (cred->cr_prison->pr_ip6 == NULL)
|
||||
return (EAFNOSUPPORT);
|
||||
|
||||
return (_prison_check_ip6(cred->cr_prison, ia6));
|
||||
}
|
||||
@ -1095,8 +1102,9 @@ prison_check_ip6(struct ucred *cred, struct in6_addr *ia6)
|
||||
* Check if given address belongs to the jail referenced by cred (wrapper to
|
||||
* prison_check_ip[46]).
|
||||
*
|
||||
* Returns 1 if address belongs to jail, 0 if not. IPv4 Address passed in in
|
||||
* NBO.
|
||||
* Returns 0 if not jailed or if address belongs to jail, EADDRNOTAVAIL if
|
||||
* the address doesn't belong, or EAFNOSUPPORT if the jail doesn't allow
|
||||
* the address family. IPv4 Address passed in in NBO.
|
||||
*/
|
||||
int
|
||||
prison_if(struct ucred *cred, struct sockaddr *sa)
|
||||
@ -1107,35 +1115,31 @@ prison_if(struct ucred *cred, struct sockaddr *sa)
|
||||
#ifdef INET6
|
||||
struct sockaddr_in6 *sai6;
|
||||
#endif
|
||||
int ok;
|
||||
int error;
|
||||
|
||||
KASSERT(cred != NULL, ("%s: cred is NULL", __func__));
|
||||
KASSERT(sa != NULL, ("%s: sa is NULL", __func__));
|
||||
|
||||
ok = 0;
|
||||
switch(sa->sa_family)
|
||||
error = 0;
|
||||
switch (sa->sa_family)
|
||||
{
|
||||
#ifdef INET
|
||||
case AF_INET:
|
||||
sai = (struct sockaddr_in *)sa;
|
||||
if (prison_check_ip4(cred, &sai->sin_addr))
|
||||
ok = 1;
|
||||
error = prison_check_ip4(cred, &sai->sin_addr);
|
||||
break;
|
||||
|
||||
#endif
|
||||
#ifdef INET6
|
||||
case AF_INET6:
|
||||
sai6 = (struct sockaddr_in6 *)sa;
|
||||
if (prison_check_ip6(cred, (struct in6_addr *)&sai6->sin6_addr))
|
||||
ok = 1;
|
||||
error = prison_check_ip6(cred, &sai6->sin6_addr);
|
||||
break;
|
||||
|
||||
#endif
|
||||
default:
|
||||
if (!jail_socket_unixiproute_only)
|
||||
ok = 1;
|
||||
if (jailed(cred) && jail_socket_unixiproute_only)
|
||||
error = EAFNOSUPPORT;
|
||||
}
|
||||
return (ok);
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -2271,8 +2271,7 @@ ifconf(u_long cmd, caddr_t data)
|
||||
TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
|
||||
struct sockaddr *sa = ifa->ifa_addr;
|
||||
|
||||
if (jailed(curthread->td_ucred) &&
|
||||
!prison_if(curthread->td_ucred, sa))
|
||||
if (prison_if(curthread->td_ucred, sa) != 0)
|
||||
continue;
|
||||
addrs++;
|
||||
#ifdef COMPAT_43
|
||||
|
@ -347,7 +347,7 @@ rtm_get_jailed(struct rt_addrinfo *info, struct ifnet *ifp,
|
||||
* 1. Check if the returned address is part of the jail.
|
||||
*/
|
||||
ia = ((struct sockaddr_in *)rt->rt_ifa->ifa_addr)->sin_addr;
|
||||
if (prison_check_ip4(cred, &ia) != 0) {
|
||||
if (prison_check_ip4(cred, &ia) == 0) {
|
||||
info->rti_info[RTAX_IFA] = rt->rt_ifa->ifa_addr;
|
||||
|
||||
} else {
|
||||
@ -366,7 +366,7 @@ rtm_get_jailed(struct rt_addrinfo *info, struct ifnet *ifp,
|
||||
if (sa->sa_family != AF_INET)
|
||||
continue;
|
||||
ia = ((struct sockaddr_in *)sa)->sin_addr;
|
||||
if (prison_check_ip4(cred, &ia) != 0) {
|
||||
if (prison_check_ip4(cred, &ia) == 0) {
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
@ -399,7 +399,7 @@ rtm_get_jailed(struct rt_addrinfo *info, struct ifnet *ifp,
|
||||
*/
|
||||
bcopy(&((struct sockaddr_in6 *)rt->rt_ifa->ifa_addr)->sin6_addr,
|
||||
&ia6, sizeof(struct in6_addr));
|
||||
if (prison_check_ip6(cred, &ia6) != 0) {
|
||||
if (prison_check_ip6(cred, &ia6) == 0) {
|
||||
info->rti_info[RTAX_IFA] = rt->rt_ifa->ifa_addr;
|
||||
} else {
|
||||
struct ifaddr *ifa;
|
||||
@ -418,7 +418,7 @@ rtm_get_jailed(struct rt_addrinfo *info, struct ifnet *ifp,
|
||||
continue;
|
||||
bcopy(&((struct sockaddr_in6 *)sa)->sin6_addr,
|
||||
&ia6, sizeof(struct in6_addr));
|
||||
if (prison_check_ip6(cred, &ia6) != 0) {
|
||||
if (prison_check_ip6(cred, &ia6) == 0) {
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
@ -612,9 +612,10 @@ route_output(struct mbuf *m, struct socket *so)
|
||||
case RTM_GET:
|
||||
report:
|
||||
RT_LOCK_ASSERT(rt);
|
||||
if (jailed(curthread->td_ucred) &&
|
||||
((rt->rt_flags & RTF_HOST) == 0 ||
|
||||
!prison_if(curthread->td_ucred, rt_key(rt)))) {
|
||||
if ((rt->rt_flags & RTF_HOST) == 0
|
||||
? jailed(curthread->td_ucred)
|
||||
: prison_if(curthread->td_ucred,
|
||||
rt_key(rt)) != 0) {
|
||||
RT_UNLOCK(rt);
|
||||
senderr(ESRCH);
|
||||
}
|
||||
@ -1263,9 +1264,9 @@ sysctl_dumpentry(struct radix_node *rn, void *vw)
|
||||
|
||||
if (w->w_op == NET_RT_FLAGS && !(rt->rt_flags & w->w_arg))
|
||||
return 0;
|
||||
if (jailed(w->w_req->td->td_ucred) &&
|
||||
((rt->rt_flags & RTF_HOST) == 0 ||
|
||||
!prison_if(w->w_req->td->td_ucred, rt_key(rt))))
|
||||
if ((rt->rt_flags & RTF_HOST) == 0
|
||||
? jailed(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));
|
||||
info.rti_info[RTAX_DST] = rt_key(rt);
|
||||
@ -1327,8 +1328,8 @@ sysctl_iflist(int af, struct walkarg *w)
|
||||
while ((ifa = TAILQ_NEXT(ifa, ifa_link)) != NULL) {
|
||||
if (af && af != ifa->ifa_addr->sa_family)
|
||||
continue;
|
||||
if (jailed(w->w_req->td->td_ucred) &&
|
||||
!prison_if(w->w_req->td->td_ucred, ifa->ifa_addr))
|
||||
if (prison_if(w->w_req->td->td_ucred,
|
||||
ifa->ifa_addr) != 0)
|
||||
continue;
|
||||
info.rti_info[RTAX_IFA] = ifa->ifa_addr;
|
||||
info.rti_info[RTAX_NETMASK] = ifa->ifa_netmask;
|
||||
@ -1376,8 +1377,8 @@ sysctl_ifmalist(int af, struct walkarg *w)
|
||||
TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
|
||||
if (af && af != ifma->ifma_addr->sa_family)
|
||||
continue;
|
||||
if (jailed(w->w_req->td->td_ucred) &&
|
||||
!prison_if(w->w_req->td->td_ucred, ifma->ifma_addr))
|
||||
if (prison_if(w->w_req->td->td_ucred,
|
||||
ifma->ifma_addr) != 0)
|
||||
continue;
|
||||
info.rti_info[RTAX_IFA] = ifma->ifma_addr;
|
||||
info.rti_info[RTAX_GATEWAY] =
|
||||
|
@ -264,7 +264,7 @@ in_control(struct socket *so, u_long cmd, caddr_t data, struct ifnet *ifp,
|
||||
if (iap->ia_ifp == ifp &&
|
||||
iap->ia_addr.sin_addr.s_addr == dst.s_addr) {
|
||||
if (td == NULL || prison_check_ip4(
|
||||
td->td_ucred, &dst))
|
||||
td->td_ucred, &dst) == 0)
|
||||
ia = iap;
|
||||
break;
|
||||
}
|
||||
@ -273,8 +273,8 @@ in_control(struct socket *so, u_long cmd, caddr_t data, struct ifnet *ifp,
|
||||
iap = ifatoia(ifa);
|
||||
if (iap->ia_addr.sin_family == AF_INET) {
|
||||
if (td != NULL &&
|
||||
!prison_check_ip4(td->td_ucred,
|
||||
&iap->ia_addr.sin_addr))
|
||||
prison_check_ip4(td->td_ucred,
|
||||
&iap->ia_addr.sin_addr) != 0)
|
||||
continue;
|
||||
ia = iap;
|
||||
break;
|
||||
@ -1199,8 +1199,7 @@ in_lltable_dump(struct lltable *llt, struct sysctl_req *wr)
|
||||
if ((lle->la_flags & (LLE_DELETED|LLE_VALID)) != LLE_VALID)
|
||||
continue;
|
||||
/* Skip if jailed and not a valid IP of the prison. */
|
||||
if (jailed(wr->td->td_ucred) &&
|
||||
!prison_if(wr->td->td_ucred, L3_ADDR(lle)))
|
||||
if (prison_if(wr->td->td_ucred, L3_ADDR(lle)) != 0)
|
||||
continue;
|
||||
/*
|
||||
* produce a msg made of:
|
||||
|
@ -325,8 +325,9 @@ in_pcbbind_setup(struct inpcb *inp, struct sockaddr *nam, in_addr_t *laddrp,
|
||||
if (sin->sin_family != AF_INET)
|
||||
return (EAFNOSUPPORT);
|
||||
#endif
|
||||
if (prison_local_ip4(cred, &sin->sin_addr))
|
||||
return (EINVAL);
|
||||
error = prison_local_ip4(cred, &sin->sin_addr);
|
||||
if (error)
|
||||
return (error);
|
||||
if (sin->sin_port != *lportp) {
|
||||
/* Don't allow the port to change. */
|
||||
if (*lportp != 0)
|
||||
@ -391,8 +392,9 @@ in_pcbbind_setup(struct inpcb *inp, struct sockaddr *nam, in_addr_t *laddrp,
|
||||
t->inp_cred->cr_uid))
|
||||
return (EADDRINUSE);
|
||||
}
|
||||
if (prison_local_ip4(cred, &sin->sin_addr))
|
||||
return (EADDRNOTAVAIL);
|
||||
error = prison_local_ip4(cred, &sin->sin_addr);
|
||||
if (error)
|
||||
return (error);
|
||||
t = in_pcblookup_local(pcbinfo, sin->sin_addr,
|
||||
lport, wild, cred);
|
||||
if (t && (t->inp_vflag & INP_TIMEWAIT)) {
|
||||
@ -426,8 +428,9 @@ in_pcbbind_setup(struct inpcb *inp, struct sockaddr *nam, in_addr_t *laddrp,
|
||||
u_short first, last, aux;
|
||||
int count;
|
||||
|
||||
if (prison_local_ip4(cred, &laddr))
|
||||
return (EINVAL);
|
||||
error = prison_local_ip4(cred, &laddr);
|
||||
if (error)
|
||||
return (error);
|
||||
|
||||
if (inp->inp_flags & INP_HIGHPORT) {
|
||||
first = V_ipport_hifirstauto; /* sysctl */
|
||||
@ -493,8 +496,9 @@ in_pcbbind_setup(struct inpcb *inp, struct sockaddr *nam, in_addr_t *laddrp,
|
||||
} while (in_pcblookup_local(pcbinfo, laddr,
|
||||
lport, wild, cred));
|
||||
}
|
||||
if (prison_local_ip4(cred, &laddr))
|
||||
return (EINVAL);
|
||||
error = prison_local_ip4(cred, &laddr);
|
||||
if (error)
|
||||
return (error);
|
||||
*laddrp = laddr.s_addr;
|
||||
*lportp = lport;
|
||||
return (0);
|
||||
@ -614,7 +618,7 @@ in_pcbladdr(struct inpcb *inp, struct in_addr *faddr, struct in_addr *laddr,
|
||||
if (sa->sa_family != AF_INET)
|
||||
continue;
|
||||
sin = (struct sockaddr_in *)sa;
|
||||
if (prison_check_ip4(cred, &sin->sin_addr)) {
|
||||
if (prison_check_ip4(cred, &sin->sin_addr) == 0) {
|
||||
ia = (struct in_ifaddr *)ifa;
|
||||
break;
|
||||
}
|
||||
@ -625,8 +629,7 @@ in_pcbladdr(struct inpcb *inp, struct in_addr *faddr, struct in_addr *laddr,
|
||||
}
|
||||
|
||||
/* 3. As a last resort return the 'default' jail address. */
|
||||
if (prison_get_ip4(cred, laddr) != 0)
|
||||
error = EADDRNOTAVAIL;
|
||||
error = prison_get_ip4(cred, laddr);
|
||||
goto done;
|
||||
}
|
||||
|
||||
@ -651,7 +654,7 @@ in_pcbladdr(struct inpcb *inp, struct in_addr *faddr, struct in_addr *laddr,
|
||||
/* Jailed. */
|
||||
/* 1. Check if the iface address belongs to the jail. */
|
||||
sin = (struct sockaddr_in *)sro.ro_rt->rt_ifa->ifa_addr;
|
||||
if (prison_check_ip4(cred, &sin->sin_addr)) {
|
||||
if (prison_check_ip4(cred, &sin->sin_addr) == 0) {
|
||||
ia = (struct in_ifaddr *)sro.ro_rt->rt_ifa;
|
||||
laddr->s_addr = ia->ia_addr.sin_addr.s_addr;
|
||||
goto done;
|
||||
@ -667,7 +670,7 @@ in_pcbladdr(struct inpcb *inp, struct in_addr *faddr, struct in_addr *laddr,
|
||||
if (sa->sa_family != AF_INET)
|
||||
continue;
|
||||
sin = (struct sockaddr_in *)sa;
|
||||
if (prison_check_ip4(cred, &sin->sin_addr)) {
|
||||
if (prison_check_ip4(cred, &sin->sin_addr) == 0) {
|
||||
ia = (struct in_ifaddr *)ifa;
|
||||
break;
|
||||
}
|
||||
@ -678,8 +681,7 @@ in_pcbladdr(struct inpcb *inp, struct in_addr *faddr, struct in_addr *laddr,
|
||||
}
|
||||
|
||||
/* 3. As a last resort return the 'default' jail address. */
|
||||
if (prison_get_ip4(cred, laddr) != 0)
|
||||
error = EADDRNOTAVAIL;
|
||||
error = prison_get_ip4(cred, laddr);
|
||||
goto done;
|
||||
}
|
||||
|
||||
@ -729,7 +731,8 @@ in_pcbladdr(struct inpcb *inp, struct in_addr *faddr, struct in_addr *laddr,
|
||||
if (sa->sa_family != AF_INET)
|
||||
continue;
|
||||
sin = (struct sockaddr_in *)sa;
|
||||
if (prison_check_ip4(cred, &sin->sin_addr)) {
|
||||
if (prison_check_ip4(cred,
|
||||
&sin->sin_addr) == 0) {
|
||||
ia = (struct in_ifaddr *)ifa;
|
||||
break;
|
||||
}
|
||||
@ -741,8 +744,7 @@ in_pcbladdr(struct inpcb *inp, struct in_addr *faddr, struct in_addr *laddr,
|
||||
}
|
||||
|
||||
/* 3. As a last resort return the 'default' jail address. */
|
||||
if (prison_get_ip4(cred, laddr) != 0)
|
||||
error = EADDRNOTAVAIL;
|
||||
error = prison_get_ip4(cred, laddr);
|
||||
goto done;
|
||||
}
|
||||
|
||||
@ -776,7 +778,7 @@ in_pcbconnect_setup(struct inpcb *inp, struct sockaddr *nam,
|
||||
struct sockaddr_in *sin = (struct sockaddr_in *)nam;
|
||||
struct in_ifaddr *ia;
|
||||
struct inpcb *oinp;
|
||||
struct in_addr laddr, faddr, jailia;
|
||||
struct in_addr laddr, faddr;
|
||||
u_short lport, fport;
|
||||
int error;
|
||||
|
||||
@ -809,15 +811,11 @@ in_pcbconnect_setup(struct inpcb *inp, struct sockaddr *nam,
|
||||
* choose the broadcast address for that interface.
|
||||
*/
|
||||
if (faddr.s_addr == INADDR_ANY) {
|
||||
if (cred != NULL && jailed(cred)) {
|
||||
if (prison_get_ip4(cred, &jailia) != 0)
|
||||
return (EADDRNOTAVAIL);
|
||||
faddr.s_addr = jailia.s_addr;
|
||||
} else {
|
||||
faddr =
|
||||
IA_SIN(TAILQ_FIRST(&V_in_ifaddrhead))->
|
||||
sin_addr;
|
||||
}
|
||||
faddr =
|
||||
IA_SIN(TAILQ_FIRST(&V_in_ifaddrhead))->sin_addr;
|
||||
if (cred != NULL &&
|
||||
(error = prison_get_ip4(cred, &faddr)) != 0)
|
||||
return (error);
|
||||
} else if (faddr.s_addr == (u_long)INADDR_BROADCAST &&
|
||||
(TAILQ_FIRST(&V_in_ifaddrhead)->ia_ifp->if_flags &
|
||||
IFF_BROADCAST))
|
||||
@ -1375,7 +1373,8 @@ in_pcblookup_hash(struct inpcbinfo *pcbinfo, struct in_addr faddr,
|
||||
|
||||
injail = jailed(inp->inp_cred);
|
||||
if (injail) {
|
||||
if (!prison_check_ip4(inp->inp_cred, &laddr))
|
||||
if (prison_check_ip4(inp->inp_cred,
|
||||
&laddr) != 0)
|
||||
continue;
|
||||
} else {
|
||||
if (local_exact != NULL)
|
||||
|
@ -276,10 +276,8 @@ 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 (!prison_check_ip4(inp->inp_cred, &ip->ip_dst))
|
||||
continue;
|
||||
}
|
||||
if (prison_check_ip4(inp->inp_cred, &ip->ip_dst) != 0)
|
||||
continue;
|
||||
if (last != NULL) {
|
||||
struct mbuf *n;
|
||||
|
||||
@ -306,10 +304,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;
|
||||
if (jailed(inp->inp_cred)) {
|
||||
if (!prison_check_ip4(inp->inp_cred, &ip->ip_dst))
|
||||
continue;
|
||||
}
|
||||
if (prison_check_ip4(inp->inp_cred, &ip->ip_dst) != 0)
|
||||
continue;
|
||||
if (last != NULL) {
|
||||
struct mbuf *n;
|
||||
|
||||
@ -370,14 +366,12 @@ 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_cred)) {
|
||||
if (prison_get_ip4(inp->inp_cred, &ip->ip_src) != 0) {
|
||||
INP_RUNLOCK(inp);
|
||||
m_freem(m);
|
||||
return (EPERM);
|
||||
}
|
||||
} else {
|
||||
ip->ip_src = inp->inp_laddr;
|
||||
ip->ip_src = inp->inp_laddr;
|
||||
error = prison_get_ip4(inp->inp_cred, &ip->ip_src);
|
||||
if (error != 0) {
|
||||
INP_RUNLOCK(inp);
|
||||
m_freem(m);
|
||||
return (error);
|
||||
}
|
||||
ip->ip_dst.s_addr = dst;
|
||||
ip->ip_ttl = inp->inp_ip_ttl;
|
||||
@ -388,10 +382,11 @@ rip_output(struct mbuf *m, struct socket *so, u_long dst)
|
||||
}
|
||||
INP_RLOCK(inp);
|
||||
ip = mtod(m, struct ip *);
|
||||
if (!prison_check_ip4(inp->inp_cred, &ip->ip_src)) {
|
||||
error = prison_check_ip4(inp->inp_cred, &ip->ip_src);
|
||||
if (error != 0) {
|
||||
INP_RUNLOCK(inp);
|
||||
m_freem(m);
|
||||
return (EPERM);
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -803,12 +798,14 @@ rip_bind(struct socket *so, struct sockaddr *nam, struct thread *td)
|
||||
INIT_VNET_INET(so->so_vnet);
|
||||
struct sockaddr_in *addr = (struct sockaddr_in *)nam;
|
||||
struct inpcb *inp;
|
||||
int error;
|
||||
|
||||
if (nam->sa_len != sizeof(*addr))
|
||||
return (EINVAL);
|
||||
|
||||
if (!prison_check_ip4(td->td_ucred, &addr->sin_addr))
|
||||
return (EADDRNOTAVAIL);
|
||||
error = prison_check_ip4(td->td_ucred, &addr->sin_addr);
|
||||
if (error != 0)
|
||||
return (error);
|
||||
|
||||
if (TAILQ_EMPTY(&V_ifnet) ||
|
||||
(addr->sin_family != AF_INET && addr->sin_family != AF_IMPLINK) ||
|
||||
|
@ -441,8 +441,8 @@ tcp_usr_connect(struct socket *so, struct sockaddr *nam, struct thread *td)
|
||||
if (sinp->sin_family == AF_INET
|
||||
&& IN_MULTICAST(ntohl(sinp->sin_addr.s_addr)))
|
||||
return (EAFNOSUPPORT);
|
||||
if (prison_remote_ip4(td->td_ucred, &sinp->sin_addr) != 0)
|
||||
return (EINVAL);
|
||||
if ((error = prison_remote_ip4(td->td_ucred, &sinp->sin_addr)) != 0)
|
||||
return (error);
|
||||
|
||||
TCPDEBUG0;
|
||||
INP_INFO_WLOCK(&V_tcbinfo);
|
||||
@ -508,10 +508,9 @@ tcp6_usr_connect(struct socket *so, struct sockaddr *nam, struct thread *td)
|
||||
in6_sin6_2_sin(&sin, sin6p);
|
||||
inp->inp_vflag |= INP_IPV4;
|
||||
inp->inp_vflag &= ~INP_IPV6;
|
||||
if (prison_remote_ip4(td->td_ucred, &sin.sin_addr) != 0) {
|
||||
error = EINVAL;
|
||||
if ((error = prison_remote_ip4(td->td_ucred,
|
||||
&sin.sin_addr)) != 0)
|
||||
goto out;
|
||||
}
|
||||
if ((error = tcp_connect(tp, (struct sockaddr *)&sin, td)) != 0)
|
||||
goto out;
|
||||
error = tcp_output_connect(so, nam);
|
||||
@ -520,10 +519,8 @@ tcp6_usr_connect(struct socket *so, struct sockaddr *nam, struct thread *td)
|
||||
inp->inp_vflag &= ~INP_IPV4;
|
||||
inp->inp_vflag |= INP_IPV6;
|
||||
inp->inp_inc.inc_flags |= INC_ISIPV6;
|
||||
if (prison_remote_ip6(td->td_ucred, &sin6p->sin6_addr) != 0) {
|
||||
error = EINVAL;
|
||||
if ((error = prison_remote_ip6(td->td_ucred, &sin6p->sin6_addr)) != 0)
|
||||
goto out;
|
||||
}
|
||||
if ((error = tcp6_connect(tp, nam, td)) != 0)
|
||||
goto out;
|
||||
error = tcp_output_connect(so, nam);
|
||||
|
@ -982,10 +982,9 @@ udp_output(struct inpcb *inp, struct mbuf *m, struct sockaddr *addr,
|
||||
* Jail may rewrite the destination address, so let it do
|
||||
* that before we use it.
|
||||
*/
|
||||
if (prison_remote_ip4(td->td_ucred, &sin->sin_addr) != 0) {
|
||||
error = EINVAL;
|
||||
error = prison_remote_ip4(td->td_ucred, &sin->sin_addr);
|
||||
if (error)
|
||||
goto release;
|
||||
}
|
||||
|
||||
/*
|
||||
* If a local address or port hasn't yet been selected, or if
|
||||
@ -1271,10 +1270,11 @@ udp_connect(struct socket *so, struct sockaddr *nam, struct thread *td)
|
||||
return (EISCONN);
|
||||
}
|
||||
sin = (struct sockaddr_in *)nam;
|
||||
if (prison_remote_ip4(td->td_ucred, &sin->sin_addr) != 0) {
|
||||
error = prison_remote_ip4(td->td_ucred, &sin->sin_addr);
|
||||
if (error != 0) {
|
||||
INP_WUNLOCK(inp);
|
||||
INP_INFO_WUNLOCK(&V_udbinfo);
|
||||
return (EAFNOSUPPORT);
|
||||
return (error);
|
||||
}
|
||||
error = in_pcbconnect(inp, nam, td->td_ucred);
|
||||
if (error == 0)
|
||||
|
@ -330,9 +330,9 @@ in6_control(struct socket *so, u_long cmd, caddr_t data,
|
||||
error = in6_setscope(&sa6->sin6_addr, ifp, NULL);
|
||||
if (error != 0)
|
||||
return (error);
|
||||
if (td != NULL && !prison_check_ip6(td->td_ucred,
|
||||
&sa6->sin6_addr))
|
||||
return (EADDRNOTAVAIL);
|
||||
if (td != NULL && (error = prison_check_ip6(td->td_ucred,
|
||||
&sa6->sin6_addr)) != 0)
|
||||
return (error);
|
||||
ia = in6ifa_ifpwithaddr(ifp, &sa6->sin6_addr);
|
||||
} else
|
||||
ia = NULL;
|
||||
@ -2241,8 +2241,7 @@ in6_lltable_dump(struct lltable *llt, struct sysctl_req *wr)
|
||||
if ((lle->la_flags & (LLE_DELETED|LLE_VALID)) != LLE_VALID)
|
||||
continue;
|
||||
/* Skip if jailed and not a valid IP of the prison. */
|
||||
if (jailed(wr->td->td_ucred) &&
|
||||
!prison_if(wr->td->td_ucred, L3_ADDR(lle)))
|
||||
if (prison_if(wr->td->td_ucred, L3_ADDR(lle)) != 0)
|
||||
continue;
|
||||
/*
|
||||
* produce a msg made of:
|
||||
|
@ -119,7 +119,7 @@ in6_pcbbind(register struct inpcb *inp, struct sockaddr *nam,
|
||||
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)NULL;
|
||||
struct inpcbinfo *pcbinfo = inp->inp_pcbinfo;
|
||||
u_short lport = 0;
|
||||
int wild = 0, reuseport = (so->so_options & SO_REUSEPORT);
|
||||
int error, wild = 0, reuseport = (so->so_options & SO_REUSEPORT);
|
||||
|
||||
INP_INFO_WLOCK_ASSERT(pcbinfo);
|
||||
INP_WLOCK_ASSERT(inp);
|
||||
@ -131,8 +131,6 @@ in6_pcbbind(register struct inpcb *inp, struct sockaddr *nam,
|
||||
if ((so->so_options & (SO_REUSEADDR|SO_REUSEPORT)) == 0)
|
||||
wild = INPLOOKUP_WILDCARD;
|
||||
if (nam) {
|
||||
int error;
|
||||
|
||||
sin6 = (struct sockaddr_in6 *)nam;
|
||||
if (nam->sa_len != sizeof(*sin6))
|
||||
return (EINVAL);
|
||||
@ -145,9 +143,9 @@ in6_pcbbind(register struct inpcb *inp, struct sockaddr *nam,
|
||||
if ((error = sa6_embedscope(sin6, V_ip6_use_defzone)) != 0)
|
||||
return(error);
|
||||
|
||||
if (prison_local_ip6(cred, &sin6->sin6_addr,
|
||||
((inp->inp_flags & IN6P_IPV6_V6ONLY) != 0)) != 0)
|
||||
return (EINVAL);
|
||||
if ((error = prison_local_ip6(cred, &sin6->sin6_addr,
|
||||
((inp->inp_flags & IN6P_IPV6_V6ONLY) != 0))) != 0)
|
||||
return (error);
|
||||
|
||||
lport = sin6->sin6_port;
|
||||
if (IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr)) {
|
||||
@ -223,9 +221,9 @@ in6_pcbbind(register struct inpcb *inp, struct sockaddr *nam,
|
||||
return (EADDRINUSE);
|
||||
}
|
||||
}
|
||||
if (prison_local_ip6(cred, &sin6->sin6_addr,
|
||||
((inp->inp_flags & IN6P_IPV6_V6ONLY) != 0)) != 0)
|
||||
return (EADDRNOTAVAIL);
|
||||
if ((error = prison_local_ip6(cred, &sin6->sin6_addr,
|
||||
((inp->inp_flags & IN6P_IPV6_V6ONLY) != 0))) != 0)
|
||||
return (error);
|
||||
t = in6_pcblookup_local(pcbinfo, &sin6->sin6_addr,
|
||||
lport, wild, cred);
|
||||
if (t && (reuseport & ((t->inp_vflag & INP_TIMEWAIT) ?
|
||||
@ -258,13 +256,12 @@ in6_pcbbind(register struct inpcb *inp, struct sockaddr *nam,
|
||||
}
|
||||
inp->in6p_laddr = sin6->sin6_addr;
|
||||
}
|
||||
if (prison_local_ip6(cred, &inp->in6p_laddr,
|
||||
((inp->inp_flags & IN6P_IPV6_V6ONLY) != 0)) != 0)
|
||||
return (EINVAL);
|
||||
if ((error = prison_local_ip6(cred, &inp->in6p_laddr,
|
||||
((inp->inp_flags & IN6P_IPV6_V6ONLY) != 0))) != 0)
|
||||
return (error);
|
||||
if (lport == 0) {
|
||||
int e;
|
||||
if ((e = in6_pcbsetport(&inp->in6p_laddr, inp, cred)) != 0)
|
||||
return (e);
|
||||
if ((error = in6_pcbsetport(&inp->in6p_laddr, inp, cred)) != 0)
|
||||
return (error);
|
||||
} else {
|
||||
inp->inp_lport = lport;
|
||||
if (in_pcbinshash(inp) != 0) {
|
||||
@ -320,8 +317,8 @@ in6_pcbladdr(register struct inpcb *inp, struct sockaddr *nam,
|
||||
if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr))
|
||||
sin6->sin6_addr = in6addr_loopback;
|
||||
}
|
||||
if (prison_remote_ip6(inp->inp_cred, &sin6->sin6_addr) != 0)
|
||||
return (EADDRNOTAVAIL);
|
||||
if ((error = prison_remote_ip6(inp->inp_cred, &sin6->sin6_addr)) != 0)
|
||||
return (error);
|
||||
|
||||
/*
|
||||
* XXX: in6_selectsrc might replace the bound local address
|
||||
@ -885,7 +882,8 @@ in6_pcblookup_hash(struct inpcbinfo *pcbinfo, struct in6_addr *faddr,
|
||||
|
||||
injail = jailed(inp->inp_cred);
|
||||
if (injail) {
|
||||
if (!prison_check_ip6(inp->inp_cred, laddr))
|
||||
if (prison_check_ip6(inp->inp_cred,
|
||||
laddr) != 0)
|
||||
continue;
|
||||
} else {
|
||||
if (local_exact != NULL)
|
||||
|
@ -240,11 +240,10 @@ in6_selectsrc(struct sockaddr_in6 *dstsock, struct ip6_pktopts *opts,
|
||||
if (*errorp != 0)
|
||||
return (NULL);
|
||||
}
|
||||
if (cred != NULL && prison_local_ip6(cred, &srcsock.sin6_addr,
|
||||
(inp != NULL && (inp->inp_flags & IN6P_IPV6_V6ONLY) != 0)) != 0) {
|
||||
*errorp = EADDRNOTAVAIL;
|
||||
if (cred != NULL && (*errorp = prison_local_ip6(cred,
|
||||
&srcsock.sin6_addr, (inp != NULL &&
|
||||
(inp->inp_flags & IN6P_IPV6_V6ONLY) != 0))) != 0)
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
ia6 = (struct in6_ifaddr *)ifa_ifwithaddr((struct sockaddr *)(&srcsock));
|
||||
if (ia6 == NULL ||
|
||||
@ -262,11 +261,10 @@ in6_selectsrc(struct sockaddr_in6 *dstsock, struct ip6_pktopts *opts,
|
||||
* Otherwise, if the socket has already bound the source, just use it.
|
||||
*/
|
||||
if (inp != NULL && !IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_laddr)) {
|
||||
if (cred != NULL && prison_local_ip6(cred, &inp->in6p_laddr,
|
||||
((inp->inp_flags & IN6P_IPV6_V6ONLY) != 0)) != 0) {
|
||||
*errorp = EADDRNOTAVAIL;
|
||||
if (cred != NULL &&
|
||||
(*errorp = prison_local_ip6(cred, &inp->in6p_laddr,
|
||||
((inp->inp_flags & IN6P_IPV6_V6ONLY) != 0))) != 0)
|
||||
return (NULL);
|
||||
}
|
||||
return (&inp->in6p_laddr);
|
||||
}
|
||||
|
||||
@ -823,15 +821,16 @@ in6_pcbsetport(struct in6_addr *laddr, struct inpcb *inp, struct ucred *cred)
|
||||
INIT_VNET_INET(curvnet);
|
||||
struct socket *so = inp->inp_socket;
|
||||
u_int16_t lport = 0, first, last, *lastport;
|
||||
int count, error = 0, wild = 0, dorandom;
|
||||
int count, error, wild = 0, dorandom;
|
||||
struct inpcbinfo *pcbinfo = inp->inp_pcbinfo;
|
||||
|
||||
INP_INFO_WLOCK_ASSERT(pcbinfo);
|
||||
INP_WLOCK_ASSERT(inp);
|
||||
|
||||
if (prison_local_ip6(cred, laddr,
|
||||
((inp->inp_flags & IN6P_IPV6_V6ONLY) != 0)) != 0)
|
||||
return(EINVAL);
|
||||
error = prison_local_ip6(cred, laddr,
|
||||
((inp->inp_flags & IN6P_IPV6_V6ONLY) != 0));
|
||||
if (error)
|
||||
return(error);
|
||||
|
||||
/* XXX: this is redundant when called from in6_pcbbind */
|
||||
if ((so->so_options & (SO_REUSEADDR|SO_REUSEPORT)) == 0)
|
||||
|
@ -179,10 +179,8 @@ rip6_input(struct mbuf **mp, int *offp, int proto)
|
||||
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 (!prison_check_ip6(in6p->inp_cred, &ip6->ip6_dst))
|
||||
continue;
|
||||
}
|
||||
if (prison_check_ip6(in6p->inp_cred, &ip6->ip6_dst) != 0)
|
||||
continue;
|
||||
INP_RLOCK(in6p);
|
||||
if (in6p->in6p_cksum != -1) {
|
||||
V_rip6stat.rip6s_isum++;
|
||||
@ -411,11 +409,9 @@ rip6_output(m, va_alist)
|
||||
error = EADDRNOTAVAIL;
|
||||
goto bad;
|
||||
}
|
||||
if (jailed(in6p->inp_cred))
|
||||
if (prison_get_ip6(in6p->inp_cred, in6a) != 0) {
|
||||
error = EPERM;
|
||||
goto bad;
|
||||
}
|
||||
error = prison_get_ip6(in6p->inp_cred, in6a);
|
||||
if (error != 0)
|
||||
goto bad;
|
||||
ip6->ip6_src = *in6a;
|
||||
|
||||
if (oifp && scope_ambiguous) {
|
||||
@ -678,8 +674,8 @@ rip6_bind(struct socket *so, struct sockaddr *nam, struct thread *td)
|
||||
|
||||
if (nam->sa_len != sizeof(*addr))
|
||||
return (EINVAL);
|
||||
if (!prison_check_ip6(td->td_ucred, &addr->sin6_addr))
|
||||
return (EADDRNOTAVAIL);
|
||||
if ((error = prison_check_ip6(td->td_ucred, &addr->sin6_addr)) != 0)
|
||||
return (error);
|
||||
if (TAILQ_EMPTY(&V_ifnet) || addr->sin6_family != AF_INET6)
|
||||
return (EADDRNOTAVAIL);
|
||||
if ((error = sa6_embedscope(addr, V_ip6_use_defzone)) != 0)
|
||||
|
@ -902,12 +902,9 @@ udp6_connect(struct socket *so, struct sockaddr *nam, struct thread *td)
|
||||
goto out;
|
||||
}
|
||||
in6_sin6_2_sin(&sin, sin6_p);
|
||||
if (td && jailed(td->td_ucred))
|
||||
if (prison_remote_ip4(td->td_ucred,
|
||||
&sin.sin_addr) != 0) {
|
||||
error = EAFNOSUPPORT;
|
||||
goto out;
|
||||
}
|
||||
if (td && (error = prison_remote_ip4(td->td_ucred,
|
||||
&sin.sin_addr)) != 0)
|
||||
goto out;
|
||||
error = in_pcbconnect(inp, (struct sockaddr *)&sin,
|
||||
td->td_ucred);
|
||||
if (error == 0) {
|
||||
@ -922,12 +919,11 @@ udp6_connect(struct socket *so, struct sockaddr *nam, struct thread *td)
|
||||
error = EISCONN;
|
||||
goto out;
|
||||
}
|
||||
if (td && jailed(td->td_ucred)) {
|
||||
if (td) {
|
||||
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)nam;
|
||||
if (prison_remote_ip6(td->td_ucred, &sin6->sin6_addr) != 0) {
|
||||
error = EAFNOSUPPORT;
|
||||
if ((error = prison_remote_ip6(td->td_ucred,
|
||||
&sin6->sin6_addr)) != 0)
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
error = in6_pcbconnect(inp, nam, td->td_ucred);
|
||||
if (error == 0) {
|
||||
|
Loading…
Reference in New Issue
Block a user