Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 22 Apr 2004 18:35:24 +0000
From:      "Christian S.J. Peron" <cperon-list@seccuris.com>
To:        Poul-Henning Kamp <phk@phk.freebsd.dk>
Cc:        freebsd-security@freebsd.org
Subject:   Re: [patch] Raw sockets in jails
Message-ID:  <20040422183523.A22252@staff.seccuris.com>
In-Reply-To: <23453.1082492678@critter.freebsd.dk>; from phk@phk.freebsd.dk on Tue, Apr 20, 2004 at 10:24:38PM %2B0200
References:  <20040420200027.A51891@staff.seccuris.com> <23453.1082492678@critter.freebsd.dk>

next in thread | previous in thread | raw e-mail | index | archive | help

I discovered the reason why traceroute breaks without -s with the most
recent patches I posted to the list.

When traceroute can not figure out what its source IP address is, it
generates a RTM_GET routing request through a routing socket and
extracts the source address of the route given the destination.

I have created a new set of patches, the only real difference is I modified
the routing code so that when it receives a RTM_GET request from a jailed
process, it re-defines the source address of the route so that it corresponds with
the prisons IP.

I have tested these patches and they appear to work, however
I ask for people to test and scrutinize these patches.
Feedback/comments are welcome.

Regards
Christian S.J. Peron

--------> new and improved patch <-----------


--- sys/kern/kern_jail.c.bak	Mon Apr 19 16:55:40 2004
+++ sys/kern/kern_jail.c	Mon Apr 19 17:56:03 2004
@@ -53,6 +53,11 @@
     &jail_sysvipc_allowed, 0,
     "Processes in jail can use System V IPC primitives");
 
+int	jail_allow_raw_sockets = 0;
+SYSCTL_INT(_security_jail, OID_AUTO, allow_raw_sockets, CTLFLAG_RW,
+    &jail_allow_raw_sockets, 0,
+    "Prison root can create raw sockets");
+
 /* allprison, lastprid, and prisoncount are protected by allprison_mtx. */
 struct	prisonlist allprison;
 struct	mtx allprison_mtx;
--- sys/net/rtsock.c.bak	Wed Apr 21 03:09:41 2004
+++ sys/net/rtsock.c	Thu Apr 22 17:37:42 2004
@@ -52,6 +52,8 @@
 #include <net/raw_cb.h>
 #include <net/route.h>
 
+#include <netinet/in.h>
+
 MALLOC_DEFINE(M_RTABLE, "routetbl", "routing tables");
 
 /* NB: these are not modified */
@@ -289,6 +291,7 @@
 	int len, error = 0;
 	struct ifnet *ifp = 0;
 	struct ifaddr *ifa = 0;
+	struct sockaddr_in jail;
 
 #define senderr(e) { error = e; goto flush;}
 	if (m == 0 || ((m->m_len < sizeof(long)) &&
@@ -400,8 +403,14 @@
 				ifp = rt->rt_ifp;
 				if (ifp) {
 					info.rti_info[RTAX_IFP] = TAILQ_FIRST(&ifp->if_addrhead)->ifa_addr;
-					info.rti_info[RTAX_IFA] =
-						rt->rt_ifa->ifa_addr;
+					if (so->so_cred->cr_prison) {
+						jail.sin_family = PF_INET;
+						jail.sin_len = sizeof(jail);
+						jail.sin_addr.s_addr = htonl(so->so_cred->cr_prison->pr_ip);
+						info.rti_info[RTAX_IFA] = (struct sockaddr *)&jail;
+					} else
+						info.rti_info[RTAX_IFA] =
+							rt->rt_ifa->ifa_addr;
 					if (ifp->if_flags & IFF_POINTOPOINT)
 						 info.rti_info[RTAX_BRD] =
 							rt->rt_ifa->ifa_dstaddr;
--- sys/netinet/raw_ip.c.b	Mon Apr 19 16:23:57 2004
+++ sys/netinet/raw_ip.c	Thu Apr 22 18:30:42 2004
@@ -40,6 +40,7 @@
 #include "opt_random_ip_id.h"
 
 #include <sys/param.h>
+#include <sys/jail.h>
 #include <sys/kernel.h>
 #include <sys/lock.h>
 #include <sys/mac.h>
@@ -215,6 +216,10 @@
 		if (inp->inp_faddr.s_addr &&
                     inp->inp_faddr.s_addr != ip->ip_src.s_addr)
 			goto docontinue;
+		if (inp->inp_socket->so_cred->cr_prison)
+			if (htonl(inp->inp_socket->so_cred->cr_prison->pr_ip)
+				!= ip->ip_dst.s_addr)
+				goto docontinue;
 		if (last) {
 			struct mbuf *n;
 
@@ -270,7 +275,11 @@
 		ip->ip_off = 0;
 		ip->ip_p = inp->inp_ip_p;
 		ip->ip_len = m->m_pkthdr.len;
-		ip->ip_src = inp->inp_laddr;
+		if (inp->inp_socket->so_cred->cr_prison) 
+			ip->ip_src.s_addr =
+			htonl(inp->inp_socket->so_cred->cr_prison->pr_ip);
+		else
+			ip->ip_src = inp->inp_laddr;
 		ip->ip_dst.s_addr = dst;
 		ip->ip_ttl = inp->inp_ip_ttl;
 	} else {
@@ -279,6 +288,13 @@
 			return(EMSGSIZE);
 		}
 		ip = mtod(m, struct ip *);
+		if (inp->inp_socket->so_cred->cr_prison) {
+			if (ip->ip_src.s_addr !=
+			htonl(inp->inp_socket->so_cred->cr_prison->pr_ip)) {
+				m_freem(m);
+				return (EPERM);
+			}
+		}
 		/* don't allow both user specified and setsockopt options,
 		   and don't allow packet length sizes that will crash */
 		if (((ip->ip_hl != (sizeof (*ip) >> 2))
@@ -505,6 +521,7 @@
 	}
 }
 
+extern int jail_allow_raw_sockets;
 u_long	rip_sendspace = RIPSNDQ;
 u_long	rip_recvspace = RIPRCVQ;
 
@@ -527,7 +544,11 @@
 		INP_INFO_WUNLOCK(&ripcbinfo);
 		return EINVAL;
 	}
-	if (td && (error = suser(td)) != 0) {
+	if (td && jailed(td->td_ucred) && !jail_allow_raw_sockets) {
+		INP_INFO_WUNLOCK(&ripcbinfo);
+		return (EPERM);
+	}
+	if (td && (error = suser_cred(td->td_ucred, PRISON_ROOT)) != 0) {
 		INP_INFO_WUNLOCK(&ripcbinfo);
 		return error;
 	}
@@ -626,6 +647,15 @@
 
 	if (nam->sa_len != sizeof(*addr))
 		return EINVAL;
+
+	if (td->td_ucred->cr_prison) {
+		if (addr->sin_addr.s_addr == INADDR_ANY) 
+			addr->sin_addr.s_addr =
+			htonl(td->td_ucred->cr_prison->pr_ip);
+		if (htonl(td->td_ucred->cr_prison->pr_ip)
+			!= addr->sin_addr.s_addr) 
+			return (EADDRNOTAVAIL);
+	}
 
 	if (TAILQ_EMPTY(&ifnet) ||
 	    (addr->sin_family != AF_INET && addr->sin_family != AF_IMPLINK) ||



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20040422183523.A22252>