Re: [patch] Raw sockets in jails

From: Christian S.J. Peron (cperon-list_at_seccuris.com)
Date: 04/22/04

  • Next message: Roman Neuhauser: "Re: panic: random.ko"
    Date: Thu, 22 Apr 2004 18:35:24 +0000
    To: Poul-Henning Kamp <phk@phk.freebsd.dk>
    
    

    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) ||
    _______________________________________________
    freebsd-hackers@freebsd.org mailing list
    http://lists.freebsd.org/mailman/listinfo/freebsd-hackers
    To unsubscribe, send any mail to "freebsd-hackers-unsubscribe@freebsd.org"


  • Next message: Roman Neuhauser: "Re: panic: random.ko"

    Relevant Pages

    • Re: [patch] Raw sockets in jails
      ... I discovered the reason why traceroute breaks without -s with the most ... generates a RTM_GET routing request through a routing socket and ... I have created a new set of patches, the only real difference is I modified ... "Prison root can create raw sockets"); ...
      (FreeBSD-Security)
    • Re: combining internet connections
      ... > I was wondering if I can use both connections... ... Julian Anastasov's routing patches found here: ... If you are patching your kernel, you may also want to add some functionality ...
      (Fedora)
    • Re: Load balancing with multiple ADSL connections?
      ... Yes thats the same set of patches i used. ... about source routing and being able to route off multiple routing ... cable and adsl and do load balancing based on weather my caps have been ... To UNSUBSCRIBE, email to debian-user-REQUEST@xxxxxxxxxxxxxxxx ...
      (Debian-User)