Module Name:    src
Committed By:   roy
Date:           Mon Oct  5 16:02:15 UTC 2020

Modified Files:
        src/external/bsd/dhcpcd/dist/src: bpf.c dhcp.c dhcp6.c dhcpcd.c
            if-bsd.c if-options.c ipv6nd.c logerr.c privsep.c script.c

Log Message:
Sync with dhcpcd-9.3.0


To generate a diff of this commit:
cvs rdiff -u -r1.16 -r1.17 src/external/bsd/dhcpcd/dist/src/bpf.c
cvs rdiff -u -r1.39 -r1.40 src/external/bsd/dhcpcd/dist/src/dhcp.c
cvs rdiff -u -r1.22 -r1.23 src/external/bsd/dhcpcd/dist/src/dhcp6.c
cvs rdiff -u -r1.42 -r1.43 src/external/bsd/dhcpcd/dist/src/dhcpcd.c
cvs rdiff -u -r1.23 -r1.24 src/external/bsd/dhcpcd/dist/src/if-bsd.c \
    src/external/bsd/dhcpcd/dist/src/ipv6nd.c
cvs rdiff -u -r1.27 -r1.28 src/external/bsd/dhcpcd/dist/src/if-options.c
cvs rdiff -u -r1.8 -r1.9 src/external/bsd/dhcpcd/dist/src/logerr.c
cvs rdiff -u -r1.7 -r1.8 src/external/bsd/dhcpcd/dist/src/privsep.c
cvs rdiff -u -r1.9 -r1.10 src/external/bsd/dhcpcd/dist/src/script.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/external/bsd/dhcpcd/dist/src/bpf.c
diff -u src/external/bsd/dhcpcd/dist/src/bpf.c:1.16 src/external/bsd/dhcpcd/dist/src/bpf.c:1.17
--- src/external/bsd/dhcpcd/dist/src/bpf.c:1.16	Mon Jun 15 16:59:05 2020
+++ src/external/bsd/dhcpcd/dist/src/bpf.c	Mon Oct  5 16:02:15 2020
@@ -70,14 +70,14 @@
 	(insn)->jt = 0;						\
 	(insn)->jf = 0;						\
 	(insn)->k = (uint32_t)(v);				\
-};
+}
 
 #define	BPF_SET_JUMP(insn, c, v, t, f) {			\
 	(insn)->code = (c);					\
 	(insn)->jt = (t);					\
 	(insn)->jf = (f);					\
 	(insn)->k = (uint32_t)(v);				\
-};
+}
 
 size_t
 bpf_frame_header_len(const struct interface *ifp)
@@ -585,9 +585,6 @@ static const struct bpf_insn bpf_bootp_e
 };
 #define BPF_BOOTP_ETHER_LEN	__arraycount(bpf_bootp_ether)
 
-#define BOOTP_MIN_SIZE		sizeof(struct ip) + sizeof(struct udphdr) + \
-				sizeof(struct bootp)
-
 static const struct bpf_insn bpf_bootp_base[] = {
 	/* Make sure it's an IPv4 packet. */
 	BPF_STMT(BPF_LD + BPF_B + BPF_IND, 0),

Index: src/external/bsd/dhcpcd/dist/src/dhcp.c
diff -u src/external/bsd/dhcpcd/dist/src/dhcp.c:1.39 src/external/bsd/dhcpcd/dist/src/dhcp.c:1.40
--- src/external/bsd/dhcpcd/dist/src/dhcp.c:1.39	Sun Sep  6 14:55:34 2020
+++ src/external/bsd/dhcpcd/dist/src/dhcp.c	Mon Oct  5 16:02:15 2020
@@ -1164,7 +1164,7 @@ read_lease(struct interface *ifp, struct
 		logdebugx("reading standard input");
 		sbytes = read(fileno(stdin), buf.buf, sizeof(buf.buf));
 	} else {
-		logdebugx("%s: reading lease `%s'",
+		logdebugx("%s: reading lease: %s",
 		    ifp->name, state->leasefile);
 		sbytes = dhcp_readfile(ifp->ctx, state->leasefile,
 		    buf.buf, sizeof(buf.buf));
@@ -2314,7 +2314,7 @@ dhcp_bind(struct interface *ifp)
 	state->state = DHS_BOUND;
 	if (!state->lease.frominfo &&
 	    !(ifo->options & (DHCPCD_INFORM | DHCPCD_STATIC))) {
-		logdebugx("%s: writing lease `%s'",
+		logdebugx("%s: writing lease: %s",
 		    ifp->name, state->leasefile);
 		if (dhcp_writefile(ifp->ctx, state->leasefile, 0640,
 		    state->new, state->new_len) == -1)
@@ -2865,10 +2865,10 @@ log_dhcp(int loglevel, const char *msg,
 		print_string(sname, sizeof(sname), OT_STRING | OT_DOMAIN,
 		    bootp->sname, sizeof(bootp->sname));
 		if (a == NULL)
-			logmessage(loglevel, "%s: %s %s %s `%s'",
+			logmessage(loglevel, "%s: %s %s %s %s",
 			    ifp->name, msg, tfrom, inet_ntoa(addr), sname);
 		else
-			logmessage(loglevel, "%s: %s %s %s %s `%s'",
+			logmessage(loglevel, "%s: %s %s %s %s %s",
 			    ifp->name, msg, a, tfrom, inet_ntoa(addr), sname);
 	} else {
 		if (r != 0) {
@@ -3477,6 +3477,16 @@ dhcp_packet(struct interface *ifp, uint8
 #ifdef PRIVSEP
 	const struct dhcp_state *state = D_CSTATE(ifp);
 
+	/* It's possible that an interface departs and arrives in short
+	 * order to receive a BPF frame out of order.
+	 * There is a similar check in ARP, but much lower down the stack.
+	 * It's not needed for other inet protocols because we send the
+	 * message as a whole and select the interface off that and then
+	 * check state. BPF on the other hand is very interface
+	 * specific and we do need this check. */
+	if (state == NULL)
+		return;
+
 	/* Ignore double reads */
 	if (IN_PRIVSEP(ifp->ctx)) {
 		switch (state->state) {

Index: src/external/bsd/dhcpcd/dist/src/dhcp6.c
diff -u src/external/bsd/dhcpcd/dist/src/dhcp6.c:1.22 src/external/bsd/dhcpcd/dist/src/dhcp6.c:1.23
--- src/external/bsd/dhcpcd/dist/src/dhcp6.c:1.22	Thu Jul  2 13:59:19 2020
+++ src/external/bsd/dhcpcd/dist/src/dhcp6.c	Mon Oct  5 16:02:15 2020
@@ -147,7 +147,7 @@ struct dhcp_compat {
 	uint16_t dhcp6_opt;
 };
 
-const struct dhcp_compat dhcp_compats[] = {
+static const struct dhcp_compat dhcp_compats[] = {
 	{ DHO_DNSSERVER,	D6_OPTION_DNS_SERVERS },
 	{ DHO_HOSTNAME,		D6_OPTION_FQDN },
 	{ DHO_DNSDOMAIN,	D6_OPTION_FQDN },
@@ -2588,7 +2588,7 @@ dhcp6_readlease(struct interface *ifp, i
 		logdebugx("reading standard input");
 		bytes = read(fileno(stdin), buf.buf, sizeof(buf.buf));
 	} else {
-		logdebugx("%s: reading lease `%s'",
+		logdebugx("%s: reading lease: %s",
 		    ifp->name, state->leasefile);
 		bytes = dhcp_readfile(ifp->ctx, state->leasefile,
 		    buf.buf, sizeof(buf.buf));
@@ -3218,7 +3218,7 @@ dhcp6_bind(struct interface *ifp, const 
 			    ifp->name, state->expire);
 		rt_build(ifp->ctx, AF_INET6);
 		if (!confirmed && !timedout) {
-			logdebugx("%s: writing lease `%s'",
+			logdebugx("%s: writing lease: %s",
 			    ifp->name, state->leasefile);
 			if (dhcp_writefile(ifp->ctx, state->leasefile, 0640,
 			    state->new, state->new_len) == -1)
@@ -3657,12 +3657,12 @@ dhcp6_recvmsg(struct dhcpcd_ctx *ctx, st
 	    "/tmp/dhcp6.reply%d.raw", replyn++);
 	fd = open(fname, O_RDONLY, 0);
 	if (fd == -1) {
-		logerr("%s: open `%s'", __func__, fname);
+		logerr("%s: open: %s", __func__, fname);
 		return;
 	}
 	tlen = read(fd, tbuf, sizeof(tbuf));
 	if (tlen == -1)
-		logerr("%s: read `%s'", __func__, fname);
+		logerr("%s: read: %s", __func__, fname);
 	close(fd);
 
 	/* Copy across ServerID so we can work with our own server. */

Index: src/external/bsd/dhcpcd/dist/src/dhcpcd.c
diff -u src/external/bsd/dhcpcd/dist/src/dhcpcd.c:1.42 src/external/bsd/dhcpcd/dist/src/dhcpcd.c:1.43
--- src/external/bsd/dhcpcd/dist/src/dhcpcd.c:1.42	Sun Sep  6 14:55:34 2020
+++ src/external/bsd/dhcpcd/dist/src/dhcpcd.c	Mon Oct  5 16:02:15 2020
@@ -26,7 +26,7 @@
  * SUCH DAMAGE.
  */
 
-const char dhcpcd_copyright[] = "Copyright (c) 2006-2020 Roy Marples";
+static const char dhcpcd_copyright[] = "Copyright (c) 2006-2020 Roy Marples";
 
 #include <sys/file.h>
 #include <sys/ioctl.h>
@@ -360,7 +360,7 @@ dhcpcd_daemonise(struct dhcpcd_ctx *ctx)
 		return;
 
 	/* Don't use loginfo because this makes no sense in a log. */
-	if (!(logopts & LOGERR_QUIET))
+	if (!(logopts & LOGERR_QUIET) && ctx->stderr_valid)
 		(void)fprintf(stderr,
 		    "forked to background, child pid %d\n", getpid());
 	i = EXIT_SUCCESS;
@@ -432,8 +432,6 @@ stop_interface(struct interface *ifp)
 	/* De-activate the interface */
 	ifp->active = IF_INACTIVE;
 	ifp->options->options &= ~DHCPCD_STOPPING;
-	/* Set the link state to unknown as we're no longer tracking it. */
-	ifp->carrier = LINK_UNKNOWN;
 
 	if (!(ctx->options & (DHCPCD_MASTER | DHCPCD_TEST)))
 		eloop_exit(ctx->eloop, EXIT_FAILURE);
@@ -700,43 +698,36 @@ dhcpcd_reportssid(struct interface *ifp)
 		return;
 	}
 
-	loginfox("%s: connected to Access Point `%s'", ifp->name, pssid);
+	loginfox("%s: connected to Access Point: %s", ifp->name, pssid);
 }
 
 void
-dhcpcd_handlecarrier(struct dhcpcd_ctx *ctx, int carrier, unsigned int flags,
-    const char *ifname)
+dhcpcd_handlecarrier(struct interface *ifp, int carrier, unsigned int flags)
 {
-	struct interface *ifp;
-
-	ifp = if_find(ctx->ifaces, ifname);
-	if (ifp == NULL ||
-	    ifp->options == NULL || !(ifp->options->options & DHCPCD_LINK) ||
-	    !ifp->active)
-		return;
+	bool nolink = ifp->options == NULL ||
+	    !(ifp->options->options & DHCPCD_LINK);
 
+	ifp->flags = flags;
 	if (carrier == LINK_UNKNOWN) {
-		if (ifp->wireless) {
+		if (ifp->wireless)
 			carrier = LINK_DOWN;
-			ifp->flags = flags;
-		} else
-			carrier = if_carrier(ifp);
-	} else
-		ifp->flags = flags;
-	if (carrier == LINK_UNKNOWN)
-		carrier = IF_UPANDRUNNING(ifp) ? LINK_UP : LINK_DOWN;
+		else
+			carrier = IF_UPANDRUNNING(ifp) ? LINK_UP : LINK_DOWN;
+	}
 
 	if (carrier == LINK_DOWN || (ifp->flags & IFF_UP) == 0) {
 		if (ifp->carrier != LINK_DOWN) {
-			if (ifp->carrier == LINK_UP)
-				loginfox("%s: carrier lost", ifp->name);
 #ifdef NOCARRIER_PRESERVE_IP
 			if (ifp->flags & IFF_UP &&
-			    !(ifp->options->options & DHCPCD_ANONYMOUS))
+			    (ifp->options == NULL ||
+			    !(ifp->options->options & DHCPCD_ANONYMOUS)))
 				ifp->carrier = LINK_DOWN_IFFUP;
 			else
 #endif
 				ifp->carrier = LINK_DOWN;
+			if (!ifp->active || nolink)
+				return;
+			loginfox("%s: carrier lost", ifp->name);
 			script_runreason(ifp, "NOCARRIER");
 #ifdef NOCARRIER_PRESERVE_IP
 			if (ifp->flags & IFF_UP &&
@@ -767,13 +758,14 @@ dhcpcd_handlecarrier(struct dhcpcd_ctx *
 		}
 	} else if (carrier == LINK_UP && ifp->flags & IFF_UP) {
 		if (ifp->carrier != LINK_UP) {
-			loginfox("%s: carrier acquired", ifp->name);
 			ifp->carrier = LINK_UP;
+			if (ifp->active)
+				loginfox("%s: carrier acquired", ifp->name);
 #if !defined(__linux__) && !defined(__NetBSD__)
 			/* BSD does not emit RTM_NEWADDR or RTM_CHGADDR when the
 			 * hardware address changes so we have to go
 			 * through the disovery process to work it out. */
-			dhcpcd_handleinterface(ctx, 0, ifp->name);
+			dhcpcd_handleinterface(ifp->ctx, 0, ifp->name);
 #endif
 			if (ifp->wireless) {
 				uint8_t ossid[IF_SSIDLEN];
@@ -784,8 +776,9 @@ dhcpcd_handlecarrier(struct dhcpcd_ctx *
 				if_getssid(ifp);
 
 				/* If we changed SSID network, drop leases */
-				if (ifp->ssid_len != olen ||
-				    memcmp(ifp->ssid, ossid, ifp->ssid_len))
+				if ((ifp->ssid_len != olen ||
+				    memcmp(ifp->ssid, ossid, ifp->ssid_len)) &&
+				    ifp->active)
 				{
 					dhcpcd_reportssid(ifp);
 #ifdef NOCARRIER_PRESERVE_IP
@@ -796,6 +789,8 @@ dhcpcd_handlecarrier(struct dhcpcd_ctx *
 #endif
 				}
 			}
+			if (!ifp->active || nolink)
+				return;
 			dhcpcd_initstate(ifp, 0);
 			script_runreason(ifp, "CARRIER");
 #ifdef INET6
@@ -871,20 +866,11 @@ dhcpcd_startinterface(void *arg)
 	struct interface *ifp = arg;
 	struct if_options *ifo = ifp->options;
 
-	if (ifo->options & DHCPCD_LINK) {
-		switch (ifp->carrier) {
-		case LINK_UP:
-			break;
-		case LINK_DOWN:
-			loginfox("%s: waiting for carrier", ifp->name);
-			return;
-		case LINK_UNKNOWN:
-			/* No media state available.
-			 * Loop until both IFF_UP and IFF_RUNNING are set */
-			if (ifo->poll == 0)
-				if_pollinit(ifp);
-			return;
-		}
+	if (ifo->options & DHCPCD_LINK && (ifp->carrier == LINK_DOWN ||
+	    (ifp->carrier == LINK_UNKNOWN && !IF_UPANDRUNNING(ifp))))
+	{
+		loginfox("%s: waiting for carrier", ifp->name);
+		return;
 	}
 
 	if (ifo->options & (DHCPCD_DUID | DHCPCD_IPV6) &&
@@ -993,9 +979,6 @@ dhcpcd_prestartinterface(void *arg)
 			logerr(__func__);
 	}
 
-	if (ifp->options->poll != 0)
-		if_pollinit(ifp);
-
 	dhcpcd_startinterface(ifp);
 }
 
@@ -1034,14 +1017,13 @@ dhcpcd_activateinterface(struct interfac
 int
 dhcpcd_handleinterface(void *arg, int action, const char *ifname)
 {
-	struct dhcpcd_ctx *ctx;
+	struct dhcpcd_ctx *ctx = arg;
 	struct ifaddrs *ifaddrs;
 	struct if_head *ifs;
 	struct interface *ifp, *iff;
 	const char * const argv[] = { ifname };
 	int e;
 
-	ctx = arg;
 	if (action == -1) {
 		ifp = if_find(ctx->ifaces, ifname);
 		if (ifp == NULL) {
@@ -1131,14 +1113,14 @@ dhcpcd_handlelink(void *arg)
 static void
 dhcpcd_checkcarrier(void *arg)
 {
-	struct interface *ifp = arg;
-	int carrier;
+	struct interface *ifp0 = arg, *ifp;
+
+	ifp = if_find(ifp0->ctx->ifaces, ifp0->name);
+	if (ifp == NULL || ifp->carrier == ifp0->carrier)
+		return;
 
-	/* Check carrier here rather than setting LINK_UNKNOWN.
-	 * This is because we force LINK_UNKNOWN as down for wireless which
-	 * we do not want when dealing with a route socket overflow. */
-	carrier = if_carrier(ifp);
-	dhcpcd_handlecarrier(ifp->ctx, carrier, ifp->flags, ifp->name);
+	dhcpcd_handlecarrier(ifp, ifp0->carrier, ifp0->flags);
+	if_free(ifp0);
 }
 
 #ifndef SMALL
@@ -1224,10 +1206,10 @@ dhcpcd_linkoverflow(struct dhcpcd_ctx *c
 		ifp1 = if_find(ctx->ifaces, ifp->name);
 		if (ifp1 != NULL) {
 			/* If the interface already exists,
-			 * check carrier state. */
+			 * check carrier state.
+			 * dhcpcd_checkcarrier will free ifp. */
 			eloop_timeout_add_sec(ctx->eloop, 0,
-			    dhcpcd_checkcarrier, ifp1);
-			if_free(ifp);
+			    dhcpcd_checkcarrier, ifp);
 			continue;
 		}
 		TAILQ_INSERT_TAIL(ctx->ifaces, ifp, next);
@@ -1417,17 +1399,9 @@ dhcpcd_signal_cb(int sig, void *arg)
 	}
 
 	if (sig != SIGCHLD && ctx->options & DHCPCD_FORKED) {
-		if (sig == SIGHUP)
-			return;
-
-		pid_t pid = pidfile_read(ctx->pidfile);
-		if (pid == -1) {
-			if (errno != ENOENT)
-				logerr("%s: pidfile_read",__func__);
-		} else if (pid == 0)
-			logerr("%s: pid cannot be zero", __func__);
-		else if (kill(pid, sig) == -1)
-			logerr("%s: kill", __func__);
+		if (sig != SIGHUP &&
+		    write(ctx->fork_fd, &sig, sizeof(sig)) == -1)
+			logerr("%s: write", __func__);
 		return;
 	}
 
@@ -1780,7 +1754,10 @@ dhcpcd_fork_cb(void *arg)
 		    __func__, len, sizeof(exit_code));
 		exit_code = EXIT_FAILURE;
 	}
-	eloop_exit(ctx->eloop, exit_code);
+	if (ctx->options & DHCPCD_FORKED)
+		eloop_exit(ctx->eloop, exit_code);
+	else
+		dhcpcd_signal_cb(exit_code, ctx);
 }
 
 static void
@@ -1893,9 +1870,16 @@ main(int argc, char **argv)
 	ctx.ps_inet_fd = ctx.ps_control_fd = -1;
 	TAILQ_INIT(&ctx.ps_processes);
 #endif
-	rt_init(&ctx);
 
-	logopts = LOGERR_ERR|LOGERR_LOG|LOGERR_LOG_DATE|LOGERR_LOG_PID;
+	/* Check our streams for validity */
+	ctx.stdin_valid =  fcntl(STDIN_FILENO,  F_GETFD) != -1;
+	ctx.stdout_valid = fcntl(STDOUT_FILENO, F_GETFD) != -1;
+	ctx.stderr_valid = fcntl(STDERR_FILENO, F_GETFD) != -1;
+
+	logopts = LOGERR_LOG | LOGERR_LOG_DATE | LOGERR_LOG_PID;
+	if (ctx.stderr_valid)
+		logopts |= LOGERR_ERR;
+
 	i = 0;
 	while ((opt = getopt_long(argc, argv,
 	    ctx.options & DHCPCD_PRINT_PIDFILE ? NOERR_IF_OPTS : IF_OPTS,
@@ -1979,6 +1963,8 @@ main(int argc, char **argv)
 	ctx.ifc = argc - optind;
 	ctx.ifv = argv + optind;
 
+	rt_init(&ctx);
+
 	ifo = read_config(&ctx, NULL, NULL, NULL);
 	if (ifo == NULL) {
 		if (ctx.options & DHCPCD_PRINT_PIDFILE)
@@ -2080,7 +2066,7 @@ printpidfile:
 	}
 
 	if (chdir("/") == -1)
-		logerr("%s: chdir `/'", __func__);
+		logerr("%s: chdir: /", __func__);
 
 	/* Freeing allocated addresses from dumping leases can trigger
 	 * eloop removals as well, so init here. */
@@ -2147,7 +2133,7 @@ printpidfile:
 	{
 		ctx.options |= DHCPCD_FORKED; /* pretend child process */
 #ifdef PRIVSEP
-		if (IN_PRIVSEP(&ctx) && ps_mastersandbox(&ctx) == -1)
+		if (IN_PRIVSEP(&ctx) && ps_mastersandbox(&ctx, NULL) == -1)
 			goto exit_failure;
 #endif
 		ifp = calloc(1, sizeof(*ifp));
@@ -2199,12 +2185,9 @@ printpidfile:
 			    ctx.options & DHCPCD_DUMPLEASE);
 		if (ctx.control_fd != -1) {
 #ifdef PRIVSEP
-			ctx.options &= ~DHCPCD_FORKED;
-			if (IN_PRIVSEP(&ctx) && ps_mastersandbox(&ctx) == -1) {
-				ctx.options |= DHCPCD_FORKED;
+			if (IN_PRIVSEP(&ctx) &&
+			    ps_mastersandbox(&ctx, NULL) == -1)
 				goto exit_failure;
-			}
-			ctx.options |= DHCPCD_FORKED;
 #endif
 			if (!(ctx.options & DHCPCD_DUMPLEASE))
 				loginfox("sending commands to dhcpcd process");
@@ -2240,9 +2223,9 @@ printpidfile:
 	if (!(ctx.options & DHCPCD_TEST)) {
 		/* Ensure we have the needed directories */
 		if (mkdir(DBDIR, 0750) == -1 && errno != EEXIST)
-			logerr("%s: mkdir `%s'", __func__, DBDIR);
+			logerr("%s: mkdir: %s", __func__, DBDIR);
 		if (mkdir(RUNDIR, 0755) == -1 && errno != EEXIST)
-			logerr("%s: mkdir `%s'", __func__, RUNDIR);
+			logerr("%s: mkdir: %s", __func__, RUNDIR);
 		if ((pid = pidfile_lock(ctx.pidfile)) != 0) {
 			if (pid == -1)
 				logerr("%s: pidfile_lock: %s",
@@ -2256,12 +2239,13 @@ printpidfile:
 	}
 
 	loginfox(PACKAGE "-" VERSION " starting");
-	if (freopen(_PATH_DEVNULL, "r", stdin) == NULL)
-		logerr("%s: freopen stdin", __func__);
+	if (ctx.stdin_valid && freopen(_PATH_DEVNULL, "w", stdin) == NULL)
+		logwarn("freopen stdin");
 
 #if defined(USE_SIGNALS) && !defined(THERE_IS_NO_FORK)
 	if (xsocketpair(AF_UNIX, SOCK_DGRAM | SOCK_CXNB, 0, fork_fd) == -1 ||
-	    xsocketpair(AF_UNIX, SOCK_DGRAM | SOCK_CXNB, 0, stderr_fd) == -1)
+	    (ctx.stderr_valid &&
+	    xsocketpair(AF_UNIX, SOCK_DGRAM | SOCK_CXNB, 0, stderr_fd) == -1))
 	{
 		logerr("socketpair");
 		goto exit_failure;
@@ -2279,20 +2263,25 @@ printpidfile:
 			goto exit_failure;
 		}
 #endif
+		eloop_event_add(ctx.eloop, ctx.fork_fd, dhcpcd_fork_cb, &ctx);
+
 		/*
 		 * Redirect stderr to the stderr socketpair.
 		 * Redirect stdout as well.
 		 * dhcpcd doesn't output via stdout, but something in
 		 * a called script might.
-		 *
-		 * Do NOT rights limit this fd as it will affect scripts.
-		 * For example, cmp reports insufficient caps on FreeBSD.
 		 */
-		if (dup2(stderr_fd[1], STDERR_FILENO) == -1 ||
-		    dup2(stderr_fd[1], STDOUT_FILENO) == -1)
-			logerr("dup2");
-		close(stderr_fd[0]);
-		close(stderr_fd[1]);
+		if (ctx.stderr_valid) {
+			if (dup2(stderr_fd[1], STDERR_FILENO) == -1 ||
+			    (ctx.stdout_valid &&
+			    dup2(stderr_fd[1], STDOUT_FILENO) == -1))
+				logerr("dup2");
+			close(stderr_fd[0]);
+			close(stderr_fd[1]);
+		} else if (ctx.stdout_valid) {
+			if (freopen(_PATH_DEVNULL, "w", stdout) == NULL)
+				logerr("freopen stdout");
+		}
 		if (setsid() == -1) {
 			logerr("%s: setsid", __func__);
 			goto exit_failure;
@@ -2311,11 +2300,10 @@ printpidfile:
 		}
 		break;
 	default:
-		ctx.options |= DHCPCD_FORKED; /* A lie */
+		setproctitle("[launcher]");
+		ctx.options |= DHCPCD_FORKED;
 		ctx.fork_fd = fork_fd[0];
 		close(fork_fd[1]);
-		ctx.stderr_fd = stderr_fd[0];
-		close(stderr_fd[1]);
 #ifdef PRIVSEP_RIGHTS
 		if (ps_rights_limit_fd(fork_fd[0]) == -1 ||
 		    ps_rights_limit_fd(stderr_fd[0]) == 1)
@@ -2324,10 +2312,25 @@ printpidfile:
 			goto exit_failure;
 		}
 #endif
-		setproctitle("[launcher]");
 		eloop_event_add(ctx.eloop, ctx.fork_fd, dhcpcd_fork_cb, &ctx);
-		eloop_event_add(ctx.eloop, ctx.stderr_fd, dhcpcd_stderr_cb,
-		    &ctx);
+
+		if (ctx.stderr_valid) {
+			ctx.stderr_fd = stderr_fd[0];
+			close(stderr_fd[1]);
+#ifdef PRIVSEP_RIGHTS
+			if (ps_rights_limit_fd(stderr_fd[0]) == 1) {
+				logerr("ps_rights_limit_fdpair");
+				goto exit_failure;
+			}
+#endif
+			if (ctx.stderr_valid)
+				eloop_event_add(ctx.eloop, ctx.stderr_fd,
+				    dhcpcd_stderr_cb, &ctx);
+		}
+#ifdef PRIVSEP
+		if (IN_PRIVSEP(&ctx) && ps_mastersandbox(&ctx, NULL) == -1)
+			goto exit_failure;
+#endif
 		goto run_loop;
 	}
 
@@ -2336,10 +2339,16 @@ printpidfile:
 	ctx.options |= DHCPCD_STARTED;
 	if ((pid = pidfile_lock(ctx.pidfile)) != 0) {
 		logerr("%s: pidfile_lock %d", __func__, pid);
+#ifdef PRIVSEP
+		/* privsep has not started ... */
+		ctx.options &= ~DHCPCD_PRIVSEP;
+#endif
 		goto exit_failure;
 	}
 #endif
 
+	os_init();
+
 #if defined(BSD) && defined(INET6)
 	/* Disable the kernel RTADV sysctl as early as possible. */
 	if (ctx.options & DHCPCD_IPV6 && ctx.options & DHCPCD_IPV6RS)
@@ -2399,7 +2408,7 @@ printpidfile:
 	eloop_event_add(ctx.eloop, ctx.link_fd, dhcpcd_handlelink, &ctx);
 
 #ifdef PRIVSEP
-	if (IN_PRIVSEP(&ctx) && ps_mastersandbox(&ctx) == -1)
+	if (IN_PRIVSEP(&ctx) && ps_mastersandbox(&ctx, "stdio route") == -1)
 		goto exit_failure;
 #endif
 
@@ -2525,6 +2534,9 @@ exit1:
 #endif
 			freeifaddrs(ifaddrs);
 	}
+	/* ps_stop will clear DHCPCD_PRIVSEP but we need to
+	 * remember it to avoid attemping to remove the pidfile */
+	oi = ctx.options & DHCPCD_PRIVSEP ? 1 : 0;
 #ifdef PRIVSEP
 	ps_stop(&ctx);
 #endif
@@ -2573,14 +2585,14 @@ exit1:
 	setproctitle_free();
 #endif
 #ifdef USE_SIGNALS
-	if (ctx.options & DHCPCD_FORKED)
-		_exit(i); /* so atexit won't remove our pidfile */
-	else if (ctx.options & DHCPCD_STARTED) {
+	if (ctx.options & DHCPCD_STARTED) {
 		/* Try to detach from the launch process. */
 		if (ctx.fork_fd != -1 &&
 		    write(ctx.fork_fd, &i, sizeof(i)) == -1)
 			logerr("%s: write", __func__);
 	}
+	if (ctx.options & DHCPCD_FORKED || oi != 0)
+		_exit(i); /* so atexit won't remove our pidfile */
 #endif
 	return i;
 }

Index: src/external/bsd/dhcpcd/dist/src/if-bsd.c
diff -u src/external/bsd/dhcpcd/dist/src/if-bsd.c:1.23 src/external/bsd/dhcpcd/dist/src/if-bsd.c:1.24
--- src/external/bsd/dhcpcd/dist/src/if-bsd.c:1.23	Thu Jul  2 13:59:19 2020
+++ src/external/bsd/dhcpcd/dist/src/if-bsd.c	Mon Oct  5 16:02:15 2020
@@ -107,6 +107,7 @@ static const char * const ifnames_ignore
 	"fwe",		/* Firewire */
 	"fwip",		/* Firewire */
 	"tap",
+	"vether",
 	"xvif",		/* XEN DOM0 -> guest interface */
 	NULL
 };
@@ -122,6 +123,12 @@ struct rtm
 };
 
 int
+os_init(void)
+{
+	return 0;
+}
+
+int
 if_init(__unused struct interface *iface)
 {
 	/* BSD promotes secondary address by default */
@@ -208,6 +215,13 @@ if_opensockets_os(struct dhcpcd_ctx *ctx
 #warning kernel does not support route message filtering
 #endif
 
+#ifdef PRIVSEP_RIGHTS
+	/* We need to getsockopt for SO_RCVBUF and
+	 * setsockopt for RO_MISSFILTER. */
+	if (IN_PRIVSEP(ctx))
+		ps_rights_limit_fd_sockopt(ctx->link_fd);
+#endif
+
 	return 0;
 }
 
@@ -353,21 +367,40 @@ if_ignore(struct dhcpcd_ctx *ctx, const 
 #endif
 }
 
+static int if_indirect_ioctl(struct dhcpcd_ctx *ctx,
+    const char *ifname, unsigned long cmd, void *data, size_t len)
+{
+	struct ifreq ifr = { .ifr_flags = 0 };
+
+#if defined(PRIVSEP) && (defined(HAVE_CAPSICUM) || defined(HAVE_PLEDGE))
+	if (IN_PRIVSEP(ctx))
+		return (int)ps_root_indirectioctl(ctx, cmd, ifname, data, len);
+#else
+	UNUSED(len);
+#endif
+
+	strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);
+	ifr.ifr_data = data;
+	return ioctl(ctx->pf_inet_fd, cmd, &ifr);
+}
+
 int
-if_carrier(struct interface *ifp)
+if_carrier(__unused struct interface *ifp, const void *ifadata)
 {
-	struct ifmediareq ifmr = { .ifm_status = 0 };
+	const struct if_data *ifi = ifadata;
 
-	/* Not really needed, but the other OS update flags here also */
-	if (if_getflags(ifp) == -1)
-		return LINK_UNKNOWN;
+	/*
+	 * Every BSD returns this and it is the sole source of truth.
+	 * Not all BSD's support SIOCGIFDATA and not all interfaces
+	 * support SIOCGIFMEDIA.
+	 */
+	assert(ifadata != NULL);
 
-	strlcpy(ifmr.ifm_name, ifp->name, sizeof(ifmr.ifm_name));
-	if (ioctl(ifp->ctx->pf_inet_fd, SIOCGIFMEDIA, &ifmr) == -1 ||
-	    !(ifmr.ifm_status & IFM_AVALID))
+	if (ifi->ifi_link_state >= LINK_STATE_UP)
+		return LINK_UP;
+	if (ifi->ifi_link_state == LINK_STATE_UNKNOWN)
 		return LINK_UNKNOWN;
-
-	return (ifmr.ifm_status & IFM_ACTIVE) ? LINK_UP : LINK_DOWN;
+	return LINK_DOWN;
 }
 
 static void
@@ -381,25 +414,6 @@ if_linkaddr(struct sockaddr_dl *sdl, con
 	sdl->sdl_index = (unsigned short)ifp->index;
 }
 
-#if defined(SIOCG80211NWID) || defined(SIOCGETVLAN)
-static int if_indirect_ioctl(struct dhcpcd_ctx *ctx,
-    const char *ifname, unsigned long cmd, void *data, size_t len)
-{
-	struct ifreq ifr = { .ifr_flags = 0 };
-
-#if defined(PRIVSEP) && defined(HAVE_PLEDGE)
-	if (IN_PRIVSEP(ctx))
-		return (int)ps_root_indirectioctl(ctx, cmd, ifname, data, len);
-#else
-	UNUSED(len);
-#endif
-
-	strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);
-	ifr.ifr_data = data;
-	return ioctl(ctx->pf_inet_fd, cmd, &ifr);
-}
-#endif
-
 static int
 if_getssid1(struct dhcpcd_ctx *ctx, const char *ifname, void *ssid)
 {
@@ -1186,24 +1200,8 @@ if_ifinfo(struct dhcpcd_ctx *ctx, const 
 	if ((ifp = if_findindex(ctx->ifaces, ifm->ifm_index)) == NULL)
 		return 0;
 
-	switch (ifm->ifm_data.ifi_link_state) {
-	case LINK_STATE_UNKNOWN:
-		link_state = LINK_UNKNOWN;
-		break;
-#ifdef LINK_STATE_FULL_DUPLEX
-	case LINK_STATE_HALF_DUPLEX:	/* FALLTHROUGH */
-	case LINK_STATE_FULL_DUPLEX:	/* FALLTHROUGH */
-#endif
-	case LINK_STATE_UP:
-		link_state = LINK_UP;
-		break;
-	default:
-		link_state = LINK_DOWN;
-		break;
-	}
-
-	dhcpcd_handlecarrier(ctx, link_state,
-	    (unsigned int)ifm->ifm_flags, ifp->name);
+	link_state = if_carrier(ifp, &ifm->ifm_data);
+	dhcpcd_handlecarrier(ifp, link_state, (unsigned int)ifm->ifm_flags);
 	return 0;
 }
 
Index: src/external/bsd/dhcpcd/dist/src/ipv6nd.c
diff -u src/external/bsd/dhcpcd/dist/src/ipv6nd.c:1.23 src/external/bsd/dhcpcd/dist/src/ipv6nd.c:1.24
--- src/external/bsd/dhcpcd/dist/src/ipv6nd.c:1.23	Sun Sep  6 14:55:34 2020
+++ src/external/bsd/dhcpcd/dist/src/ipv6nd.c	Mon Oct  5 16:02:15 2020
@@ -1223,7 +1223,7 @@ ipv6nd_handlera(struct dhcpcd_ctx *ctx,
 	if (rap->willexpire)
 		new_data = true;
 	loglevel = new_rap || rap->willexpire || !rap->isreachable ?
-	    LOG_INFO : LOG_DEBUG,
+	    LOG_INFO : LOG_DEBUG;
 	logmessage(loglevel, "%s: Router Advertisement from %s",
 	    ifp->name, rap->sfrom);
 

Index: src/external/bsd/dhcpcd/dist/src/if-options.c
diff -u src/external/bsd/dhcpcd/dist/src/if-options.c:1.27 src/external/bsd/dhcpcd/dist/src/if-options.c:1.28
--- src/external/bsd/dhcpcd/dist/src/if-options.c:1.27	Sun Sep  6 14:55:34 2020
+++ src/external/bsd/dhcpcd/dist/src/if-options.c	Mon Oct  5 16:02:15 2020
@@ -49,6 +49,7 @@
 #include "dhcp.h"
 #include "dhcp6.h"
 #include "dhcpcd-embedded.h"
+#include "duid.h"
 #include "if.h"
 #include "if-options.h"
 #include "ipv4.h"
@@ -94,7 +95,7 @@ const struct option cf_options[] = {
 	{"noarp",           no_argument,       NULL, 'A'},
 	{"nobackground",    no_argument,       NULL, 'B'},
 	{"nohook",          required_argument, NULL, 'C'},
-	{"duid",            no_argument,       NULL, 'D'},
+	{"duid",            optional_argument, NULL, 'D'},
 	{"lastlease",       no_argument,       NULL, 'E'},
 	{"fqdn",            optional_argument, NULL, 'F'},
 	{"nogateway",       no_argument,       NULL, 'G'},
@@ -164,7 +165,6 @@ const struct option cf_options[] = {
 	{"inactive",        no_argument,       NULL, O_INACTIVE},
 	{"mudurl",          required_argument, NULL, O_MUDURL},
 	{"link_rcvbuf",     required_argument, NULL, O_LINK_RCVBUF},
-	{"poll",            optional_argument, NULL, O_POLL},
 	{NULL,              0,                 NULL, '\0'}
 };
 
@@ -460,13 +460,13 @@ parse_addr(struct in_addr *addr, struct 
 		if (e != 0 ||
 		    (net != NULL && inet_cidrtoaddr((int)i, net) != 0))
 		{
-			logerrx("`%s' is not a valid CIDR", p);
+			logerrx("invalid CIDR: %s", p);
 			return -1;
 		}
 	}
 
 	if (addr != NULL && inet_aton(arg, addr) == 0) {
-		logerrx("`%s' is not a valid IP address", arg);
+		logerrx("invalid IP address: %s", arg);
 		return -1;
 	}
 	if (p != NULL)
@@ -788,7 +788,7 @@ parse_option(struct dhcpcd_ctx *ctx, con
 		    make_option_mask(d, dl, od, odl, no, arg, -1) != 0 ||
 		    make_option_mask(d, dl, od, odl, reject, arg, -1) != 0)
 		{
-			logerrx("unknown option `%s'", arg);
+			logerrx("unknown option: %s", arg);
 			return -1;
 		}
 		break;
@@ -800,7 +800,7 @@ parse_option(struct dhcpcd_ctx *ctx, con
 		    make_option_mask(d, dl, od, odl, request, arg, -1) != 0 ||
 		    make_option_mask(d, dl, od, odl, require, arg, -1) != 0)
 		{
-			logerrx("unknown option `%s'", arg);
+			logerrx("unknown option: %s", arg);
 			return -1;
 		}
 		break;
@@ -985,6 +985,20 @@ parse_option(struct dhcpcd_ctx *ctx, con
 		break;
 	case 'D':
 		ifo->options |= DHCPCD_CLIENTID | DHCPCD_DUID;
+		if (ifname != NULL) /* duid type only a global option */
+			break;
+		if (arg == NULL)
+			ctx->duid_type = DUID_DEFAULT;
+		else if (strcmp(arg, "ll") == 0)
+			ctx->duid_type = DUID_LL;
+		else if (strcmp(arg, "llt") == 0)
+			ctx->duid_type = DUID_LLT;
+		else if (strcmp(arg, "uuid") == 0)
+			ctx->duid_type = DUID_UUID;
+		else {
+			logwarnx("%s: invalid duid type", arg);
+			ctx->duid_type = DUID_DEFAULT;
+		}
 		break;
 	case 'E':
 		ifo->options |= DHCPCD_LASTLEASE;
@@ -1003,7 +1017,7 @@ parse_option(struct dhcpcd_ctx *ctx, con
 		else if (strcmp(arg, "disable") == 0)
 			ifo->fqdn = FQDN_DISABLE;
 		else {
-			logerrx("invalid value `%s' for FQDN", arg);
+			logerrx("invalid FQDN value: %s", arg);
 			return -1;
 		}
 		break;
@@ -1049,7 +1063,7 @@ parse_option(struct dhcpcd_ctx *ctx, con
 		    make_option_mask(d, dl, od, odl, require, arg, -1) != 0 ||
 		    make_option_mask(d, dl, od, odl, no, arg, 1) != 0)
 		{
-			logerrx("unknown option `%s'", arg);
+			logerrx("unknown option: %s", arg);
 			return -1;
 		}
 		break;
@@ -1062,7 +1076,7 @@ parse_option(struct dhcpcd_ctx *ctx, con
 		    make_option_mask(d, dl, od, odl, no, arg, -1) != 0 ||
 		    make_option_mask(d, dl, od, odl, reject, arg, -1) != 0)
 		{
-			logerrx("unknown option `%s'", arg);
+			logerrx("unknown option: %s", arg);
 			return -1;
 		}
 		break;
@@ -1299,10 +1313,10 @@ parse_option(struct dhcpcd_ctx *ctx, con
 		    ifo->dstmask, arg, 2) != 0)
 		{
 			if (errno == EINVAL)
-				logerrx("option `%s' does not take"
-				    " an IPv4 address", arg);
+				logerrx("option does not take"
+				    " an IPv4 address: %s", arg);
 			else
-				logerrx("unknown option `%s'", arg);
+				logerrx("unknown option: %s", arg);
 			return -1;
 		}
 		break;
@@ -1785,7 +1799,7 @@ err_sla:
 			return -1;
 		}
 		if (l && !(t & (OT_STRING | OT_BINHEX))) {
-			logwarnx("ignoring length for type `%s'", arg);
+			logwarnx("ignoring length for type: %s", arg);
 			l = 0;
 		}
 		if (t & OT_ARRAY && t & (OT_STRING | OT_BINHEX) &&
@@ -2220,18 +2234,6 @@ invalid_token:
 		}
 #endif
 		break;
-	case O_POLL:
-		if (arg == NULL) {
-			ifo->poll = IF_POLL_UP;
-			break;
-		}
-		ifo->poll = (unsigned long)
-		    strtou(arg, NULL, 0, 0, ULONG_MAX, &e);
-		if (e) {
-			logerrx("failed to convert poll %s", arg);
-			return -1;
-		}
-		break;
 	default:
 		return 0;
 	}

Index: src/external/bsd/dhcpcd/dist/src/logerr.c
diff -u src/external/bsd/dhcpcd/dist/src/logerr.c:1.8 src/external/bsd/dhcpcd/dist/src/logerr.c:1.9
--- src/external/bsd/dhcpcd/dist/src/logerr.c:1.8	Sun Sep  6 14:55:34 2020
+++ src/external/bsd/dhcpcd/dist/src/logerr.c	Mon Oct  5 16:02:15 2020
@@ -382,7 +382,7 @@ logopen(const char *path)
 	}
 
 #ifndef SMALL
-	if ((ctx->log_file = fopen(path, "a")) == NULL)
+	if ((ctx->log_file = fopen(path, "ae")) == NULL)
 		return -1;
 	setlinebuf(ctx->log_file);
 	return fileno(ctx->log_file);

Index: src/external/bsd/dhcpcd/dist/src/privsep.c
diff -u src/external/bsd/dhcpcd/dist/src/privsep.c:1.7 src/external/bsd/dhcpcd/dist/src/privsep.c:1.8
--- src/external/bsd/dhcpcd/dist/src/privsep.c:1.7	Sun Sep  6 14:55:34 2020
+++ src/external/bsd/dhcpcd/dist/src/privsep.c	Mon Oct  5 16:02:15 2020
@@ -76,7 +76,6 @@
 #ifdef HAVE_CAPSICUM
 #include <sys/capsicum.h>
 #include <capsicum_helpers.h>
-#define ps_rights_limit_stdio caph_limit_stdio
 #endif
 #ifdef HAVE_UTIL_H
 #include <util.h>
@@ -118,11 +117,12 @@ ps_dropprivs(struct dhcpcd_ctx *ctx)
 	struct passwd *pw = ctx->ps_user;
 
 	if (!(ctx->options & DHCPCD_FORKED))
-		logdebugx("chrooting to `%s' as %s", pw->pw_dir, pw->pw_name);
-	if (chroot(pw->pw_dir) == -1)
-		logerr("%s: chroot `%s'", __func__, pw->pw_dir);
+		logdebugx("chrooting as %s to %s", pw->pw_name, pw->pw_dir);
+	if (chroot(pw->pw_dir) == -1 &&
+	    (errno != EPERM || ctx->options & DHCPCD_FORKED))
+		logerr("%s: chroot: %s", __func__, pw->pw_dir);
 	if (chdir("/") == -1)
-		logerr("%s: chdir `/'", __func__);
+		logerr("%s: chdir: /", __func__);
 
 	if ((setgroups(1, &pw->pw_gid) == -1 ||
 	     setgid(pw->pw_gid) == -1 ||
@@ -260,6 +260,18 @@ ps_rights_limit_fd(int fd)
 }
 
 int
+ps_rights_limit_fd_sockopt(int fd)
+{
+	cap_rights_t rights;
+
+	cap_rights_init(&rights, CAP_READ, CAP_WRITE, CAP_EVENT,
+	    CAP_GETSOCKOPT, CAP_SETSOCKOPT);
+	if (cap_rights_limit(fd, &rights) == -1 && errno != ENOSYS)
+		return -1;
+	return 0;
+}
+
+int
 ps_rights_limit_fd_rdonly(int fd)
 {
 	cap_rights_t rights;
@@ -278,6 +290,25 @@ ps_rights_limit_fdpair(int fd[])
 		return -1;
 	return 0;
 }
+
+static int
+ps_rights_limit_stdio(struct dhcpcd_ctx *ctx)
+{
+	const int iebadf = CAPH_IGNORE_EBADF;
+	int error = 0;
+
+	if (ctx->stdin_valid &&
+	    caph_limit_stream(STDIN_FILENO, CAPH_READ | iebadf) == -1)
+		error = -1;
+	if (ctx->stdout_valid &&
+	    caph_limit_stream(STDOUT_FILENO, CAPH_WRITE | iebadf) == -1)
+		error = -1;
+	if (ctx->stderr_valid &&
+	    caph_limit_stream(STDERR_FILENO, CAPH_WRITE | iebadf) == -1)
+		error = -1;
+
+	return error;
+}
 #endif
 
 pid_t
@@ -346,7 +377,7 @@ ps_dostart(struct dhcpcd_ctx *ctx,
 
 #ifdef PRIVSEP_RIGHTS
 		/* We cannot limit the root process in any way. */
-		if (ps_rights_limit_stdio() == -1) {
+		if (ps_rights_limit_stdio(ctx) == -1) {
 			logerr("ps_rights_limit_stdio");
 			goto errexit;
 		}
@@ -472,10 +503,45 @@ started_net:
 }
 
 int
-ps_mastersandbox(struct dhcpcd_ctx *ctx)
+ps_entersandbox(const char *_pledge, const char **sandbox)
 {
 
-	if (ps_dropprivs(ctx) == -1) {
+#if !defined(HAVE_PLEDGE)
+	UNUSED(_pledge);
+#endif
+
+#if defined(HAVE_CAPSICUM)
+	if (sandbox != NULL)
+		*sandbox = "capsicum";
+	return cap_enter();
+#elif defined(HAVE_PLEDGE)
+	if (sandbox != NULL)
+		*sandbox = "pledge";
+	return pledge(_pledge, NULL);
+#elif defined(HAVE_SECCOMP)
+	if (sandbox != NULL)
+		*sandbox = "seccomp";
+	return ps_seccomp_enter();
+#else
+	if (sandbox != NULL)
+		*sandbox = "posix resource limited";
+	return 0;
+#endif
+}
+
+int
+ps_mastersandbox(struct dhcpcd_ctx *ctx, const char *_pledge)
+{
+	const char *sandbox = NULL;
+	bool forked;
+	int dropped;
+
+	forked = ctx->options & DHCPCD_FORKED;
+	ctx->options &= ~DHCPCD_FORKED;
+	dropped = ps_dropprivs(ctx);
+	if (forked)
+		ctx->options |= DHCPCD_FORKED;
+	if (dropped == -1) {
 		logerr("%s: ps_dropprivs", __func__);
 		return -1;
 	}
@@ -483,26 +549,25 @@ ps_mastersandbox(struct dhcpcd_ctx *ctx)
 #ifdef PRIVSEP_RIGHTS
 	if ((ctx->pf_inet_fd != -1 &&
 	    ps_rights_limit_ioctl(ctx->pf_inet_fd) == -1) ||
-	    (ctx->link_fd != -1 && ps_rights_limit_fd(ctx->link_fd) == -1) ||
-	     ps_rights_limit_stdio() == -1)
+	     ps_rights_limit_stdio(ctx) == -1)
 	{
 		logerr("%s: cap_rights_limit", __func__);
 		return -1;
 	}
 #endif
-#ifdef HAVE_CAPSICUM
-	if (cap_enter() == -1 && errno != ENOSYS) {
-		logerr("%s: cap_enter", __func__);
-		return -1;
-	}
-#endif
-#ifdef HAVE_PLEDGE
-	if (pledge("stdio route", NULL) == -1) {
-		logerr("%s: pledge", __func__);
-		return -1;
-	}
-#endif
 
+	if (_pledge == NULL)
+		_pledge = "stdio";
+	if (ps_entersandbox(_pledge, &sandbox) == -1) {
+		if (errno == ENOSYS) {
+			if (sandbox != NULL)
+				logwarnx("sandbox unavailable: %s", sandbox);
+			return 0;
+		}
+		logerr("%s: %s", __func__, sandbox);
+		return -1;
+	} else if (!forked)
+		logdebugx("sandbox: %s", sandbox);
 	return 0;
 }
 

Index: src/external/bsd/dhcpcd/dist/src/script.c
diff -u src/external/bsd/dhcpcd/dist/src/script.c:1.9 src/external/bsd/dhcpcd/dist/src/script.c:1.10
--- src/external/bsd/dhcpcd/dist/src/script.c:1.9	Thu Jul  2 13:59:19 2020
+++ src/external/bsd/dhcpcd/dist/src/script.c	Mon Oct  5 16:02:15 2020
@@ -736,7 +736,7 @@ script_runreason(const struct interface 
 
 	argv[0] = ctx->script;
 	argv[1] = NULL;
-	logdebugx("%s: executing `%s' %s", ifp->name, argv[0], reason);
+	logdebugx("%s: executing: %s %s", ifp->name, argv[0], reason);
 
 #ifdef PRIVSEP
 	if (ctx->options & DHCPCD_PRIVSEP) {

Reply via email to