Index: etc/mtree/BSD.var.dist =================================================================== --- etc/mtree/BSD.var.dist +++ etc/mtree/BSD.var.dist @@ -74,6 +74,8 @@ preserve .. run + dhclient + .. ppp gname=network mode=0770 .. wpa_supplicant Index: sbin/dhclient/dhclient.8 =================================================================== --- sbin/dhclient/dhclient.8 +++ sbin/dhclient/dhclient.8 @@ -38,7 +38,7 @@ .\" .\" $FreeBSD$ .\" -.Dd October 13, 2011 +.Dd August 4, 2018 .Dt DHCLIENT 8 .Os .Sh NAME @@ -87,7 +87,7 @@ .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 @@ .Pp The current implementation was reworked by .An Henning Brauer Aq Mt henning@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. Index: sbin/dhclient/dhclient.c =================================================================== --- sbin/dhclient/dhclient.c +++ sbin/dhclient/dhclient.c @@ -371,6 +371,7 @@ 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 @@ 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 @@ 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)) @@ -544,6 +540,17 @@ if (caph_enter_casper() < 0) error("can't enter capability mode: %m"); + if (cap_getmode(&capmode) < 0 || capmode == 0) { + /* + * Try to restrict filesystem access. This will fail + * if kern.chroot_allow_open_directories is 0 or the + * process is jailed. + */ + if (chroot(_PATH_VAREMPTY) == -1) + error("chroot"); + if (chdir("/") == -1) + error("chdir(\"/\")"); + } if (immediate_daemon) go_daemon(); @@ -2449,13 +2456,8 @@ 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); Index: sbin/init/rc.d/dhclient =================================================================== --- sbin/init/rc.d/dhclient +++ sbin/init/rc.d/dhclient @@ -14,7 +14,7 @@ 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"