summaryrefslogtreecommitdiffstats
path: root/sys/netinet
diff options
context:
space:
mode:
authorphk <phk@FreeBSD.org>2000-09-17 13:35:42 +0000
committerphk <phk@FreeBSD.org>2000-09-17 13:35:42 +0000
commitcb69a028ad335ceefa94bfe8665549f0b3c02c06 (patch)
tree5e1d61a92e21ddc557c23e545f547b431c7e02fb /sys/netinet
parent1d9c0d533ed967bcd9dae861e179bc2a9c474733 (diff)
downloadFreeBSD-src-cb69a028ad335ceefa94bfe8665549f0b3c02c06.zip
FreeBSD-src-cb69a028ad335ceefa94bfe8665549f0b3c02c06.tar.gz
Properly jail UDP sockets. This is quite a bit more tricky than TCP.
This fixes a !root userland panic, and some cases where the wrong interface was chosen for a jailed UDP socket. PR: 20167, 19839, 20946
Diffstat (limited to 'sys/netinet')
-rw-r--r--sys/netinet/in_pcb.c24
1 files changed, 19 insertions, 5 deletions
diff --git a/sys/netinet/in_pcb.c b/sys/netinet/in_pcb.c
index 3204aa8..4fc9b92 100644
--- a/sys/netinet/in_pcb.c
+++ b/sys/netinet/in_pcb.c
@@ -196,8 +196,9 @@ in_pcbbind(inp, nam, p)
if (sin->sin_family != AF_INET)
return (EAFNOSUPPORT);
#endif
- if (prison_ip(p, 0, &sin->sin_addr.s_addr))
- return(EINVAL);
+ if (sin->sin_addr.s_addr != INADDR_ANY)
+ if (prison_ip(p, 0, &sin->sin_addr.s_addr))
+ return(EINVAL);
lport = sin->sin_port;
if (IN_MULTICAST(ntohl(sin->sin_addr.s_addr))) {
/*
@@ -270,8 +271,9 @@ in_pcbbind(inp, nam, p)
ushort first, last;
int count;
- if (prison_ip(p, 0, &inp->inp_laddr.s_addr ))
- return (EINVAL);
+ if (inp->inp_laddr.s_addr != INADDR_ANY)
+ if (prison_ip(p, 0, &inp->inp_laddr.s_addr ))
+ return (EINVAL);
inp->inp_flags |= INP_ANONPORT;
if (inp->inp_flags & INP_HIGHPORT) {
@@ -341,6 +343,8 @@ in_pcbbind(inp, nam, p)
}
}
inp->inp_lport = lport;
+ if (prison_ip(p, 0, &inp->inp_laddr.s_addr))
+ return(EINVAL);
if (in_pcbinshash(inp) != 0) {
inp->inp_laddr.s_addr = INADDR_ANY;
inp->inp_lport = 0;
@@ -485,9 +489,19 @@ in_pcbconnect(inp, nam, p)
struct proc *p;
{
struct sockaddr_in *ifaddr;
- register struct sockaddr_in *sin = (struct sockaddr_in *)nam;
+ struct sockaddr_in *sin = (struct sockaddr_in *)nam;
+ struct sockaddr_in sa;
int error;
+ if (inp->inp_laddr.s_addr == INADDR_ANY && p->p_prison != NULL) {
+ bzero(&sa, sizeof (sa));
+ sa.sin_addr.s_addr = htonl(p->p_prison->pr_ip);
+ sa.sin_len=sizeof (sa);
+ sa.sin_family = AF_INET;
+ error = in_pcbbind(inp, (struct sockaddr *)&sa, p);
+ if (error)
+ return (error);
+ }
/*
* Call inner routine, to assign local interface address.
*/
OpenPOWER on IntegriCloud