summaryrefslogtreecommitdiffstats
path: root/sys/netinet
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/netinet
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/netinet')
-rw-r--r--sys/netinet/in.c9
-rw-r--r--sys/netinet/in_pcb.c57
-rw-r--r--sys/netinet/raw_ip.c37
-rw-r--r--sys/netinet/tcp_usrreq.c13
-rw-r--r--sys/netinet/udp_usrreq.c10
5 files changed, 59 insertions, 67 deletions
diff --git a/sys/netinet/in.c b/sys/netinet/in.c
index 03c7269..bf1ebae 100644
--- a/sys/netinet/in.c
+++ b/sys/netinet/in.c
@@ -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:
diff --git a/sys/netinet/in_pcb.c b/sys/netinet/in_pcb.c
index 4a7e4f9..25494cf 100644
--- a/sys/netinet/in_pcb.c
+++ b/sys/netinet/in_pcb.c
@@ -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)
diff --git a/sys/netinet/raw_ip.c b/sys/netinet/raw_ip.c
index 8f6d8ec..27f4b9c 100644
--- a/sys/netinet/raw_ip.c
+++ b/sys/netinet/raw_ip.c
@@ -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) ||
diff --git a/sys/netinet/tcp_usrreq.c b/sys/netinet/tcp_usrreq.c
index f6dcae1..89987c4 100644
--- a/sys/netinet/tcp_usrreq.c
+++ b/sys/netinet/tcp_usrreq.c
@@ -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);
diff --git a/sys/netinet/udp_usrreq.c b/sys/netinet/udp_usrreq.c
index 7eaa0e3..804f5fe 100644
--- a/sys/netinet/udp_usrreq.c
+++ b/sys/netinet/udp_usrreq.c
@@ -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)
OpenPOWER on IntegriCloud