diff --git a/sys/netinet/raw_ip.c b/sys/netinet/raw_ip.c index 1db37746c83a..0b77b5b84960 100644 --- a/sys/netinet/raw_ip.c +++ b/sys/netinet/raw_ip.c @@ -427,11 +427,24 @@ rip_output(struct mbuf *m, struct socket *so, u_long dst) ip->ip_p = inp->inp_ip_p; ip->ip_len = m->m_pkthdr.len; 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); + if (jailed(inp->inp_cred)) { + /* + * prison_local_ip4() would be good enough but would + * let a source of INADDR_ANY pass, which we do not + * want to see from jails. We do not go through the + * pain of in_pcbladdr() for raw sockets. + */ + if (ip->ip_src.s_addr == INADDR_ANY) + error = prison_get_ip4(inp->inp_cred, + &ip->ip_src); + else + error = prison_local_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; diff --git a/sys/netinet6/raw_ip6.c b/sys/netinet6/raw_ip6.c index 9f1236ab1bdb..6052b24e4705 100644 --- a/sys/netinet6/raw_ip6.c +++ b/sys/netinet6/raw_ip6.c @@ -465,7 +465,7 @@ rip6_output(m, va_alist) &oifp, &in6a); if (error) goto bad; - error = prison_get_ip6(in6p->inp_cred, &in6a); + error = prison_check_ip6(in6p->inp_cred, &in6a); if (error != 0) goto bad; ip6->ip6_src = in6a;