Author: markj
Date: Mon Aug  6 16:22:01 2018
New Revision: 337382
URL: https://svnweb.freebsd.org/changeset/base/337382

Log:
  dhclient: Don't chroot if we are in capability mode.
  
  The main dhclient process is Capsicumized but also chroots to
  restrict filesystem access.  With r322369, pidfile(3) maintains a
  directory descriptor for the pidfile, which can cause the chroot
  to fail in certain cases.  To minimize the problem, only chroot
  if we fail to enter capability mode, and store dhclient pidfiles
  in a subdirectory of /var/run, thus restricting access via
  pidfile(3)'s directory descriptor.
  
  PR:           223327
  Reviewed by:  cem, oshogbo
  Sponsored by: The FreeBSD Foundation
  Differential Revision:        https://reviews.freebsd.org/D16584

Modified:
  head/etc/mtree/BSD.var.dist
  head/sbin/dhclient/dhclient.8
  head/sbin/dhclient/dhclient.c
  head/sbin/init/rc.d/dhclient

Modified: head/etc/mtree/BSD.var.dist
==============================================================================
--- head/etc/mtree/BSD.var.dist Mon Aug  6 15:55:58 2018        (r337381)
+++ head/etc/mtree/BSD.var.dist Mon Aug  6 16:22:01 2018        (r337382)
@@ -74,6 +74,8 @@
     preserve
     ..
     run
+        dhclient
+        ..
         ppp             gname=network mode=0770
         ..
         wpa_supplicant

Modified: head/sbin/dhclient/dhclient.8
==============================================================================
--- head/sbin/dhclient/dhclient.8       Mon Aug  6 15:55:58 2018        
(r337381)
+++ head/sbin/dhclient/dhclient.8       Mon Aug  6 16:22:01 2018        
(r337382)
@@ -38,7 +38,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd October 13, 2011
+.Dd August 4, 2018
 .Dt DHCLIENT 8
 .Os
 .Sh NAME
@@ -87,7 +87,7 @@ for the leases file.
 .It Fl p Ar file
 Specify an alternate location for the PID file.
 The default is
-.Pa /var/run/dhclient. Ns Ar interface Ns Pa .pid .
+.Pa /var/run/dhclient/dhclient. Ns Ar interface Ns Pa .pid .
 .It Fl q
 Forces
 .Nm
@@ -194,3 +194,16 @@ and
 .Pp
 The current implementation was reworked by
 .An Henning Brauer Aq Mt henn...@openbsd.org .
+.Sh BUGS
+The
+.Nm
+utility uses
+.Xr capsicum 4
+to sandbox the main process.
+If the requisite kernel support is not available, the main process will
+attempt to run in a
+.Xr chroot 2
+sandbox instead.
+This will fail if the process is jailed or the
+.Va kern.chroot_allow_open_directories
+sysctl is set to 0.

Modified: head/sbin/dhclient/dhclient.c
==============================================================================
--- head/sbin/dhclient/dhclient.c       Mon Aug  6 15:55:58 2018        
(r337381)
+++ head/sbin/dhclient/dhclient.c       Mon Aug  6 16:22:01 2018        
(r337382)
@@ -371,6 +371,7 @@ init_casper(void)
 int
 main(int argc, char *argv[])
 {
+       u_int                    capmode;
        int                      ch, fd, quiet = 0, i = 0;
        int                      pipe_fd[2];
        int                      immediate_daemon = 0;
@@ -419,7 +420,7 @@ main(int argc, char *argv[])
 
        if (path_dhclient_pidfile == NULL) {
                asprintf(&path_dhclient_pidfile,
-                   "%sdhclient.%s.pid", _PATH_VARRUN, *argv);
+                   "%s/dhclient/dhclient.%s.pid", _PATH_VARRUN, *argv);
                if (path_dhclient_pidfile == NULL)
                        error("asprintf");
        }
@@ -528,11 +529,6 @@ main(int argc, char *argv[])
        if (cap_rights_limit(routefd, &rights) < 0 && errno != ENOSYS)
                error("can't limit route socket: %m");
 
-       if (chroot(_PATH_VAREMPTY) == -1)
-               error("chroot");
-       if (chdir("/") == -1)
-               error("chdir(\"/\")");
-
        if (setgroups(1, &pw->pw_gid) ||
            setegid(pw->pw_gid) || setgid(pw->pw_gid) ||
            seteuid(pw->pw_uid) || setuid(pw->pw_uid))
@@ -545,6 +541,19 @@ main(int argc, char *argv[])
        if (caph_enter_casper() < 0)
                error("can't enter capability mode: %m");
 
+       /*
+        * If we are not in capability mode (i.e., because Capsicum or
+        * libcasper is disabled), try to restrict filesystem access.  This
+        * will fail if kern.chroot_allow_open_directories is 0 or the process
+        * is jailed.
+        */
+       if (cap_getmode(&capmode) < 0 || capmode == 0) {
+               if (chroot(_PATH_VAREMPTY) == -1)
+                       error("chroot");
+               if (chdir("/") == -1)
+                       error("chdir(\"/\")");
+       }
+
        if (immediate_daemon)
                go_daemon();
 
@@ -2449,13 +2458,8 @@ go_daemon(void)
 
        cap_rights_init(&rights);
 
-       if (pidfile != NULL) {
+       if (pidfile != NULL)
                pidfile_write(pidfile);
-               if (cap_rights_limit(pidfile_fileno(pidfile), &rights) < 0 &&
-                   errno != ENOSYS) {
-                       error("can't limit pidfile descriptor: %m");
-               }
-       }
 
        if (nullfd != -1) {
                close(nullfd);

Modified: head/sbin/init/rc.d/dhclient
==============================================================================
--- head/sbin/init/rc.d/dhclient        Mon Aug  6 15:55:58 2018        
(r337381)
+++ head/sbin/init/rc.d/dhclient        Mon Aug  6 16:22:01 2018        
(r337382)
@@ -14,7 +14,7 @@ ifn="$2"
 name="dhclient"
 desc="Dynamic Host Configuration Protocol (DHCP) client"
 rcvar=
-pidfile="/var/run/${name}.${ifn}.pid"
+pidfile="/var/run/dhclient/${name}.${ifn}.pid"
 start_precmd="dhclient_prestart"
 stop_precmd="dhclient_pre_check"
 
_______________________________________________
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