Author: oshogbo
Date: Wed Sep  5 20:13:28 2018
New Revision: 338475
URL: https://svnweb.freebsd.org/changeset/base/338475

Log:
  MFC r314000:
  
    Capsicumize traceroute.
  
    PR:          193973
    Submitted by:        Mikhail <mp39...@gmail.com>
    Reviewed by:         pjd, bapt, emaste, AllanJude
    Differential Revision:      https://reviews.freebsd.org/D9303

Modified:
  stable/11/contrib/traceroute/traceroute.c
  stable/11/usr.sbin/traceroute/Makefile
Directory Properties:
  stable/11/   (props changed)

Modified: stable/11/contrib/traceroute/traceroute.c
==============================================================================
--- stable/11/contrib/traceroute/traceroute.c   Wed Sep  5 20:02:23 2018        
(r338474)
+++ stable/11/contrib/traceroute/traceroute.c   Wed Sep  5 20:13:28 2018        
(r338475)
@@ -203,6 +203,7 @@ static const char rcsid[] =
  */
 
 #include <sys/param.h>
+#include <sys/capsicum.h>
 #include <sys/file.h>
 #include <sys/ioctl.h>
 #ifdef HAVE_SYS_SELECT_H
@@ -227,6 +228,11 @@ static const char rcsid[] =
 
 #include <arpa/inet.h>
 
+#ifdef HAVE_LIBCASPER
+#include <libcasper.h>
+#include <casper/cap_dns.h>
+#endif
+
 #ifdef IPSEC
 #include <net/route.h>
 #include <netipsec/ipsec.h>    /* XXX */
@@ -363,6 +369,10 @@ extern int optind;
 extern int opterr;
 extern char *optarg;
 
+#ifdef HAVE_LIBCASPER
+static cap_channel_t *capdns;
+#endif
+
 /* Forwards */
 double deltaT(struct timeval *, struct timeval *);
 void   freehostinfo(struct hostinfo *);
@@ -511,6 +521,13 @@ main(int argc, char **argv)
        int requestPort = -1;
        int sump = 0;
        int sockerrno;
+#ifdef HAVE_LIBCASPER
+       const char *types[] = { "NAME", "ADDR" };
+       int families[1];
+       cap_channel_t *casper;
+#endif
+       cap_rights_t rights;
+       bool cansandbox;
 
        /* Insure the socket fds won't be 0, 1 or 2 */
        if (open(devnull, O_RDONLY) < 0 ||
@@ -539,6 +556,20 @@ main(int argc, char **argv)
                exit(1);
        }
 
+#ifdef HAVE_LIBCASPER
+       casper = cap_init();
+       if (casper == NULL)
+               errx(1, "unable to create casper process");
+       capdns = cap_service_open(casper, "system.dns");
+       if (capdns == NULL)
+               errx(1, "unable to open system.dns service");
+       if (cap_dns_type_limit(capdns, types, 2) < 0)
+               errx(1, "unable to limit access to system.dns service");
+       families[0] = AF_INET;
+       if (cap_dns_family_limit(capdns, families, 1) < 0)
+               errx(1, "unable to limit access to system.dns service");
+#endif /* HAVE_LIBCASPER */
+
 #ifdef IPCTL_DEFTTL
        {
                int mib[4] = { CTL_NET, PF_INET, IPPROTO_IP, IPCTL_DEFTTL };
@@ -549,10 +580,14 @@ main(int argc, char **argv)
                        exit(1);
                }
        }
-#else
+#else /* !IPCTL_DEFTTL */
        max_ttl = 30;
 #endif
 
+#ifdef HAVE_LIBCASPER
+       cap_close(casper);
+#endif
+
        if (argv[0] == NULL)
                prog = "traceroute";
        else if ((cp = strrchr(argv[0], '/')) != NULL)
@@ -965,6 +1000,45 @@ main(int argc, char **argv)
                }
        }
 
+       if (connect(sndsock, (struct sockaddr *)&whereto,
+           sizeof(whereto)) != 0) {
+               Fprintf(stderr, "%s: connect: %s\n", prog, strerror(errno));
+               exit(1);
+       }
+
+#ifdef HAVE_LIBCASPER
+       cansandbox = true;
+#else
+       if (nflag)
+               cansandbox = true;
+       else
+               cansandbox = false;
+#endif
+
+       /*
+        * Here we enter capability mode. Further down access to global
+        * namespaces (e.g filesystem) is restricted (see capsicum(4)).
+        * We must connect(2) our socket before this point.
+        */
+       if (cansandbox && cap_enter() < 0) {
+               Fprintf(stderr, "%s: cap_enter: %s\n", prog, strerror(errno));
+               exit(1);
+       }
+
+       cap_rights_init(&rights, CAP_SEND, CAP_SETSOCKOPT);
+       if (cansandbox && cap_rights_limit(sndsock, &rights) < 0) {
+               Fprintf(stderr, "%s: cap_rights_limit sndsock: %s\n", prog,
+                   strerror(errno));
+               exit(1);
+       }
+
+       cap_rights_init(&rights, CAP_RECV, CAP_EVENT);
+       if (cansandbox && cap_rights_limit(s, &rights) < 0) {
+               Fprintf(stderr, "%s: cap_rights_limit s: %s\n", prog,
+                   strerror(errno));
+               exit(1);
+       }
+
 #if    defined(IPSEC) && defined(IPSEC_POLICY_IPSEC)
        if (setpolicy(sndsock, "in bypass") < 0)
                errx(1, "%s", ipsec_strerror());
@@ -1252,8 +1326,7 @@ send_probe(int seq, int ttl)
        }
 #endif
 
-       cc = sendto(sndsock, (char *)outip,
-           packlen, 0, &whereto, sizeof(whereto));
+       cc = send(sndsock, (char *)outip, packlen, 0);
        if (cc < 0 || cc != packlen)  {
                if (cc < 0)
                        Fprintf(stderr, "%s: sendto: %s\n",
@@ -1826,7 +1899,12 @@ inetname(struct in_addr in)
                else {
                        cp = strchr(domain, '.');
                        if (cp == NULL) {
-                               hp = gethostbyname(domain);
+#ifdef HAVE_LIBCASPER
+                               if (capdns != NULL)
+                                       hp = cap_gethostbyname(capdns, domain);
+                               else
+#endif
+                                       hp = gethostbyname(domain);
                                if (hp != NULL)
                                        cp = strchr(hp->h_name, '.');
                        }
@@ -1840,7 +1918,13 @@ inetname(struct in_addr in)
                }
        }
        if (!nflag && in.s_addr != INADDR_ANY) {
-               hp = gethostbyaddr((char *)&in, sizeof(in), AF_INET);
+#ifdef HAVE_LIBCASPER
+               if (capdns != NULL)
+                       hp = cap_gethostbyaddr(capdns, (char *)&in, sizeof(in),
+                           AF_INET);
+               else
+#endif
+                       hp = gethostbyaddr((char *)&in, sizeof(in), AF_INET);
                if (hp != NULL) {
                        if ((cp = strchr(hp->h_name, '.')) != NULL &&
                            strcmp(cp + 1, domain) == 0)
@@ -1886,7 +1970,12 @@ gethostinfo(register char *hostname)
                return (hi);
        }
 
-       hp = gethostbyname(hostname);
+#ifdef HAVE_LIBCASPER
+       if (capdns != NULL)
+               hp = cap_gethostbyname(capdns, hostname);
+       else
+#endif
+               hp = gethostbyname(hostname);
        if (hp == NULL) {
                Fprintf(stderr, "%s: unknown host %s\n", prog, hostname);
                exit(1);

Modified: stable/11/usr.sbin/traceroute/Makefile
==============================================================================
--- stable/11/usr.sbin/traceroute/Makefile      Wed Sep  5 20:02:23 2018        
(r338474)
+++ stable/11/usr.sbin/traceroute/Makefile      Wed Sep  5 20:13:28 2018        
(r338475)
@@ -1,5 +1,7 @@
 # $FreeBSD$
 
+.include <src.opts.mk>
+
 TRACEROUTE_DISTDIR?= ${SRCTOP}/contrib/traceroute
 .PATH: ${TRACEROUTE_DISTDIR}
 
@@ -26,6 +28,12 @@ CFLAGS+= -DIPSEC
 
 .if !defined(TRACEROUTE_NO_IPSEC)
 LIBADD+=       ipsec
+.endif
+
+.if ${MK_CASPER} != "no"
+LIBADD+=       casper
+LIBADD+=       cap_dns
+CFLAGS+=-DHAVE_LIBCASPER
 .endif
 
 CFLAGS+= -I${TRACEROUTE_DISTDIR}
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to