summaryrefslogtreecommitdiffstats
path: root/sys/netinet6
diff options
context:
space:
mode:
authorjamie <jamie@FreeBSD.org>2009-02-05 14:06:09 +0000
committerjamie <jamie@FreeBSD.org>2009-02-05 14:06:09 +0000
commit12bbe1869f5926ca7e3457f5424afdca31a1189b (patch)
tree71fe0b10296684e7094a545ca78ed6f72789d82d /sys/netinet6
parent2926f8fa435de3f0b595eb5309b2a0c364703371 (diff)
downloadFreeBSD-src-12bbe1869f5926ca7e3457f5424afdca31a1189b.zip
FreeBSD-src-12bbe1869f5926ca7e3457f5424afdca31a1189b.tar.gz
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)
Diffstat (limited to 'sys/netinet6')
-rw-r--r--sys/netinet6/in6.c9
-rw-r--r--sys/netinet6/in6_pcb.c34
-rw-r--r--sys/netinet6/in6_src.c23
-rw-r--r--sys/netinet6/raw_ip6.c18
-rw-r--r--sys/netinet6/udp6_usrreq.c16
5 files changed, 44 insertions, 56 deletions
diff --git a/sys/netinet6/in6.c b/sys/netinet6/in6.c
index 693a2f9..81a37f8 100644
--- a/sys/netinet6/in6.c
+++ b/sys/netinet6/in6.c
@@ -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:
diff --git a/sys/netinet6/in6_pcb.c b/sys/netinet6/in6_pcb.c
index 753f45d..13c55cd 100644
--- a/sys/netinet6/in6_pcb.c
+++ b/sys/netinet6/in6_pcb.c
@@ -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)
diff --git a/sys/netinet6/in6_src.c b/sys/netinet6/in6_src.c
index ca65bc9..8030416 100644
--- a/sys/netinet6/in6_src.c
+++ b/sys/netinet6/in6_src.c
@@ -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)
diff --git a/sys/netinet6/raw_ip6.c b/sys/netinet6/raw_ip6.c
index 18b8131..da781a0 100644
--- a/sys/netinet6/raw_ip6.c
+++ b/sys/netinet6/raw_ip6.c
@@ -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)
diff --git a/sys/netinet6/udp6_usrreq.c b/sys/netinet6/udp6_usrreq.c
index dea8ed2..d0bcfc0 100644
--- a/sys/netinet6/udp6_usrreq.c
+++ b/sys/netinet6/udp6_usrreq.c
@@ -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) {
OpenPOWER on IntegriCloud