mirror of
https://github.com/freebsd/freebsd-src
synced 2024-09-06 09:10:28 +00:00
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
This commit is contained in:
parent
7db2360401
commit
976e100378
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=337382
|
@ -74,6 +74,8 @@
|
||||||
preserve
|
preserve
|
||||||
..
|
..
|
||||||
run
|
run
|
||||||
|
dhclient
|
||||||
|
..
|
||||||
ppp gname=network mode=0770
|
ppp gname=network mode=0770
|
||||||
..
|
..
|
||||||
wpa_supplicant
|
wpa_supplicant
|
||||||
|
|
|
@ -38,7 +38,7 @@
|
||||||
.\"
|
.\"
|
||||||
.\" $FreeBSD$
|
.\" $FreeBSD$
|
||||||
.\"
|
.\"
|
||||||
.Dd October 13, 2011
|
.Dd August 4, 2018
|
||||||
.Dt DHCLIENT 8
|
.Dt DHCLIENT 8
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
|
@ -87,7 +87,7 @@ for the leases file.
|
||||||
.It Fl p Ar file
|
.It Fl p Ar file
|
||||||
Specify an alternate location for the PID file.
|
Specify an alternate location for the PID file.
|
||||||
The default is
|
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
|
.It Fl q
|
||||||
Forces
|
Forces
|
||||||
.Nm
|
.Nm
|
||||||
|
@ -194,3 +194,16 @@ and
|
||||||
.Pp
|
.Pp
|
||||||
The current implementation was reworked by
|
The current implementation was reworked by
|
||||||
.An Henning Brauer Aq Mt henning@openbsd.org .
|
.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.
|
||||||
|
|
|
@ -371,6 +371,7 @@ init_casper(void)
|
||||||
int
|
int
|
||||||
main(int argc, char *argv[])
|
main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
|
u_int capmode;
|
||||||
int ch, fd, quiet = 0, i = 0;
|
int ch, fd, quiet = 0, i = 0;
|
||||||
int pipe_fd[2];
|
int pipe_fd[2];
|
||||||
int immediate_daemon = 0;
|
int immediate_daemon = 0;
|
||||||
|
@ -419,7 +420,7 @@ main(int argc, char *argv[])
|
||||||
|
|
||||||
if (path_dhclient_pidfile == NULL) {
|
if (path_dhclient_pidfile == NULL) {
|
||||||
asprintf(&path_dhclient_pidfile,
|
asprintf(&path_dhclient_pidfile,
|
||||||
"%sdhclient.%s.pid", _PATH_VARRUN, *argv);
|
"%s/dhclient/dhclient.%s.pid", _PATH_VARRUN, *argv);
|
||||||
if (path_dhclient_pidfile == NULL)
|
if (path_dhclient_pidfile == NULL)
|
||||||
error("asprintf");
|
error("asprintf");
|
||||||
}
|
}
|
||||||
|
@ -528,11 +529,6 @@ main(int argc, char *argv[])
|
||||||
if (cap_rights_limit(routefd, &rights) < 0 && errno != ENOSYS)
|
if (cap_rights_limit(routefd, &rights) < 0 && errno != ENOSYS)
|
||||||
error("can't limit route socket: %m");
|
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) ||
|
if (setgroups(1, &pw->pw_gid) ||
|
||||||
setegid(pw->pw_gid) || setgid(pw->pw_gid) ||
|
setegid(pw->pw_gid) || setgid(pw->pw_gid) ||
|
||||||
seteuid(pw->pw_uid) || setuid(pw->pw_uid))
|
seteuid(pw->pw_uid) || setuid(pw->pw_uid))
|
||||||
|
@ -545,6 +541,19 @@ main(int argc, char *argv[])
|
||||||
if (caph_enter_casper() < 0)
|
if (caph_enter_casper() < 0)
|
||||||
error("can't enter capability mode: %m");
|
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)
|
if (immediate_daemon)
|
||||||
go_daemon();
|
go_daemon();
|
||||||
|
|
||||||
|
@ -2449,13 +2458,8 @@ go_daemon(void)
|
||||||
|
|
||||||
cap_rights_init(&rights);
|
cap_rights_init(&rights);
|
||||||
|
|
||||||
if (pidfile != NULL) {
|
if (pidfile != NULL)
|
||||||
pidfile_write(pidfile);
|
pidfile_write(pidfile);
|
||||||
if (cap_rights_limit(pidfile_fileno(pidfile), &rights) < 0 &&
|
|
||||||
errno != ENOSYS) {
|
|
||||||
error("can't limit pidfile descriptor: %m");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nullfd != -1) {
|
if (nullfd != -1) {
|
||||||
close(nullfd);
|
close(nullfd);
|
||||||
|
|
|
@ -14,7 +14,7 @@ ifn="$2"
|
||||||
name="dhclient"
|
name="dhclient"
|
||||||
desc="Dynamic Host Configuration Protocol (DHCP) client"
|
desc="Dynamic Host Configuration Protocol (DHCP) client"
|
||||||
rcvar=
|
rcvar=
|
||||||
pidfile="/var/run/${name}.${ifn}.pid"
|
pidfile="/var/run/dhclient/${name}.${ifn}.pid"
|
||||||
start_precmd="dhclient_prestart"
|
start_precmd="dhclient_prestart"
|
||||||
stop_precmd="dhclient_pre_check"
|
stop_precmd="dhclient_pre_check"
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue