Module Name:    src
Committed By:   roy
Date:           Sun Nov  1 14:24:01 UTC 2020

Modified Files:
        src/external/bsd/dhcpcd/dist/src: dhcp.c dhcpcd.8.in dhcpcd.c logerr.c
            privsep.c

Log Message:
Sync with dhcpcd-9.3.2


To generate a diff of this commit:
cvs rdiff -u -r1.41 -r1.42 src/external/bsd/dhcpcd/dist/src/dhcp.c
cvs rdiff -u -r1.8 -r1.9 src/external/bsd/dhcpcd/dist/src/dhcpcd.8.in
cvs rdiff -u -r1.44 -r1.45 src/external/bsd/dhcpcd/dist/src/dhcpcd.c
cvs rdiff -u -r1.10 -r1.11 src/external/bsd/dhcpcd/dist/src/logerr.c
cvs rdiff -u -r1.9 -r1.10 src/external/bsd/dhcpcd/dist/src/privsep.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/dhcp.c
diff -u src/external/bsd/dhcpcd/dist/src/dhcp.c:1.41 src/external/bsd/dhcpcd/dist/src/dhcp.c:1.42
--- src/external/bsd/dhcpcd/dist/src/dhcp.c:1.41	Mon Oct 12 14:09:03 2020
+++ src/external/bsd/dhcpcd/dist/src/dhcp.c	Sun Nov  1 14:24:01 2020
@@ -1520,21 +1520,15 @@ again:
 #endif
 }
 
-void
-dhcp_close(struct interface *ifp)
+static void
+dhcp_closebpf(struct interface *ifp)
 {
 	struct dhcpcd_ctx *ctx = ifp->ctx;
 	struct dhcp_state *state = D_STATE(ifp);
 
-	if (state == NULL)
-		return;
-
 #ifdef PRIVSEP
-	if (IN_PRIVSEP_SE(ctx)) {
+	if (IN_PRIVSEP_SE(ctx))
 		ps_bpf_closebootp(ifp);
-		if (state->addr != NULL)
-			ps_inet_closebootp(state->addr);
-	}
 #endif
 
 	if (state->bpf != NULL) {
@@ -1542,11 +1536,38 @@ dhcp_close(struct interface *ifp)
 		bpf_close(state->bpf);
 		state->bpf = NULL;
 	}
+}
+
+static void
+dhcp_closeinet(struct interface *ifp)
+{
+	struct dhcpcd_ctx *ctx = ifp->ctx;
+	struct dhcp_state *state = D_STATE(ifp);
+
+#ifdef PRIVSEP
+	if (IN_PRIVSEP_SE(ctx)) {
+		if (state->addr != NULL)
+			ps_inet_closebootp(state->addr);
+	}
+#endif
+
 	if (state->udp_rfd != -1) {
 		eloop_event_delete(ctx->eloop, state->udp_rfd);
 		close(state->udp_rfd);
 		state->udp_rfd = -1;
 	}
+}
+
+void
+dhcp_close(struct interface *ifp)
+{
+	struct dhcp_state *state = D_STATE(ifp);
+
+	if (state == NULL)
+		return;
+
+	dhcp_closebpf(ifp);
+	dhcp_closeinet(ifp);
 
 	state->interval = 0;
 }
@@ -2061,12 +2082,14 @@ dhcp_addr_duplicated(struct interface *i
 
 #ifdef ARP
 #ifdef KERNEL_RFC5227
+#ifdef ARPING
 static void
 dhcp_arp_announced(struct arp_state *state)
 {
 
 	arp_free(state);
 }
+#endif
 #else
 static void
 dhcp_arp_defend_failed(struct arp_state *astate)
@@ -2321,23 +2344,24 @@ dhcp_bind(struct interface *ifp)
 			logerr("dhcp_writefile: %s", state->leasefile);
 	}
 
+	old_state = state->added;
+
 	/* Close the BPF filter as we can now receive DHCP messages
 	 * on a UDP socket. */
-	old_state = state->added;
-	if (ctx->options & DHCPCD_MASTER ||
-	    state->old == NULL ||
-	    state->old->yiaddr != state->new->yiaddr || old_state & STATE_FAKE)
-		dhcp_close(ifp);
+	dhcp_closebpf(ifp);
 
+	/* Add the address */
 	ipv4_applyaddr(ifp);
 
 	/* If not in master mode, open an address specific socket. */
 	if (ctx->options & DHCPCD_MASTER ||
 	    (state->old != NULL &&
-	    state->old->yiaddr == state->new->yiaddr &&
-	    old_state & STATE_ADDED && !(old_state & STATE_FAKE)))
+	     state->old->yiaddr == state->new->yiaddr &&
+	     old_state & STATE_ADDED && !(old_state & STATE_FAKE)))
 		return;
 
+	dhcp_closeinet(ifp);
+
 #ifdef PRIVSEP
 	if (IN_PRIVSEP_SE(ctx)) {
 		if (ps_inet_openbootp(state->addr) == -1)
@@ -2926,6 +2950,8 @@ dhcp_handledhcp(struct interface *ifp, s
 	unsigned int i;
 	char *msg;
 	bool bootp_copied;
+	uint32_t v6only_time = 0;
+	bool use_v6only = false;
 #ifdef AUTH
 	const uint8_t *auth;
 	size_t auth_len;
@@ -3143,6 +3169,23 @@ dhcp_handledhcp(struct interface *ifp, s
 		}
 	}
 
+	if (has_option_mask(ifo->requestmask, DHO_IPV6_PREFERRED_ONLY)) {
+		if (get_option_uint32(ifp->ctx, &v6only_time, bootp, bootp_len,
+		    DHO_IPV6_PREFERRED_ONLY) == 0 &&
+		    (state->state == DHS_DISCOVER || state->state == DHS_REBOOT))
+		{
+			char v6msg[128];
+
+			use_v6only = true;
+			if (v6only_time < MIN_V6ONLY_WAIT)
+				v6only_time = MIN_V6ONLY_WAIT;
+			snprintf(v6msg, sizeof(v6msg),
+			    "IPv6-Only Preferred received (%u seconds)",
+			    v6only_time);
+			LOGDHCP(LOG_INFO, v6msg);
+		}
+	}
+
 	/* DHCP Auto-Configure, RFC 2563 */
 	if (type == DHCP_OFFER && bootp->yiaddr == 0) {
 		LOGDHCP(LOG_WARNING, "no address given");
@@ -3177,12 +3220,22 @@ dhcp_handledhcp(struct interface *ifp, s
 			}
 			eloop_timeout_delete(ifp->ctx->eloop, NULL, ifp);
 			eloop_timeout_add_sec(ifp->ctx->eloop,
-			    DHCP_MAX, dhcp_discover, ifp);
+			    use_v6only ? v6only_time : DHCP_MAX,
+			    dhcp_discover, ifp);
 		}
 #endif
 		return;
 	}
 
+	if (use_v6only) {
+		dhcp_drop(ifp, "EXPIRE");
+		dhcp_unlink(ifp->ctx, state->leasefile);
+		eloop_timeout_delete(ifp->ctx->eloop, NULL, ifp);
+		eloop_timeout_add_sec(ifp->ctx->eloop, v6only_time,
+		    dhcp_discover, ifp);
+		return;
+	}
+
 	/* Ensure that the address offered is valid */
 	if ((type == 0 || type == DHCP_OFFER || type == DHCP_ACK) &&
 	    (bootp->ciaddr == INADDR_ANY || bootp->ciaddr == INADDR_BROADCAST)

Index: src/external/bsd/dhcpcd/dist/src/dhcpcd.8.in
diff -u src/external/bsd/dhcpcd/dist/src/dhcpcd.8.in:1.8 src/external/bsd/dhcpcd/dist/src/dhcpcd.8.in:1.9
--- src/external/bsd/dhcpcd/dist/src/dhcpcd.8.in:1.8	Sun Sep  6 14:55:34 2020
+++ src/external/bsd/dhcpcd/dist/src/dhcpcd.8.in	Sun Nov  1 14:24:01 2020
@@ -24,7 +24,7 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.Dd September 2, 2020
+.Dd October 30, 2020
 .Dt DHCPCD 8
 .Os
 .Sh NAME
@@ -846,13 +846,5 @@ RFC\ 6603, RFC\ 6704, RFC\ 7217, RFC\ 75
 .Sh AUTHORS
 .An Roy Marples Aq Mt r...@marples.name
 .Sh BUGS
-If
-.Nm
-is running in a
-.Xr chroot 2
-then re-opening the
-.Fl Fl logfile
-from SIGUSR2 may not work.
-.Pp
 Please report them to
 .Lk http://roy.marples.name/projects/dhcpcd

Index: src/external/bsd/dhcpcd/dist/src/dhcpcd.c
diff -u src/external/bsd/dhcpcd/dist/src/dhcpcd.c:1.44 src/external/bsd/dhcpcd/dist/src/dhcpcd.c:1.45
--- src/external/bsd/dhcpcd/dist/src/dhcpcd.c:1.44	Mon Oct 12 14:09:03 2020
+++ src/external/bsd/dhcpcd/dist/src/dhcpcd.c	Sun Nov  1 14:24:01 2020
@@ -1422,10 +1422,15 @@ dhcpcd_signal_cb(int sig, void *arg)
 		return;
 	case SIGUSR2:
 		loginfox(sigmsg, "SIGUSR2", "reopening log");
-		/* XXX This may not work that well in a chroot */
-		logclose();
+#ifdef PRIVSEP
+		if (IN_PRIVSEP(ctx)) {
+			if (ps_root_logreopen(ctx) == -1)
+				logerr("ps_root_logreopen");
+			return;
+		}
+#endif
 		if (logopen(ctx->logfile) == -1)
-			logerr(__func__);
+			logerr("logopen");
 		return;
 	case SIGCHLD:
 		while (waitpid(-1, NULL, WNOHANG) > 0)
@@ -1860,7 +1865,7 @@ main(int argc, char **argv, char **envp)
 	ctx.dhcp6_wfd = -1;
 #endif
 #ifdef PRIVSEP
-	ctx.ps_root_fd = ctx.ps_data_fd = -1;
+	ctx.ps_root_fd = ctx.ps_log_fd = ctx.ps_data_fd = -1;
 	ctx.ps_inet_fd = ctx.ps_control_fd = -1;
 	TAILQ_INIT(&ctx.ps_processes);
 #endif
@@ -2328,6 +2333,7 @@ printpidfile:
 	/* We have now forked, setsid, forked once more.
 	 * From this point on, we are the controlling daemon. */
 	ctx.options |= DHCPCD_STARTED;
+	logdebugx("spawned master process on PID %d", getpid());
 	if ((pid = pidfile_lock(ctx.pidfile)) != 0) {
 		logerr("%s: pidfile_lock %d", __func__, pid);
 #ifdef PRIVSEP

Index: src/external/bsd/dhcpcd/dist/src/logerr.c
diff -u src/external/bsd/dhcpcd/dist/src/logerr.c:1.10 src/external/bsd/dhcpcd/dist/src/logerr.c:1.11
--- src/external/bsd/dhcpcd/dist/src/logerr.c:1.10	Mon Oct 12 14:09:03 2020
+++ src/external/bsd/dhcpcd/dist/src/logerr.c	Sun Nov  1 14:24:01 2020
@@ -47,11 +47,16 @@
 #undef LOGERR_TAG
 #endif
 
+/* syslog protocol is 1k message max, RFC 3164 section 4.1 */
+#define LOGERR_SYSLOGBUF	1024 + sizeof(int) + sizeof(pid_t)
+
 #define UNUSED(a)		(void)(a)
 
 struct logctx {
 	char		 log_buf[BUFSIZ];
 	unsigned int	 log_opts;
+	int		 log_fd;
+	pid_t		 log_pid;
 #ifndef SMALL
 	FILE		*log_file;
 #ifdef LOGERR_TAG
@@ -63,9 +68,11 @@ struct logctx {
 static struct logctx _logctx = {
 	/* syslog style, but without the hostname or tag. */
 	.log_opts = LOGERR_LOG | LOGERR_LOG_DATE | LOGERR_LOG_PID,
+	.log_fd = -1,
+	.log_pid = 0,
 };
 
-#if defined(LOGERR_TAG) && defined(__linux__)
+#if defined(__linux__)
 /* Poor man's getprogname(3). */
 static char *_logprog;
 static const char *
@@ -79,9 +86,12 @@ getprogname(void)
 		 * so zero the buffer. */
 		if ((_logprog = calloc(1, PATH_MAX + 1)) == NULL)
 			return NULL;
+		if (readlink("/proc/self/exe", _logprog, PATH_MAX + 1) == -1) {
+			free(_logprog);
+			_logprog = NULL;
+			return NULL;
+		}
 	}
-	if (readlink("/proc/self/exe", _logprog, PATH_MAX + 1) == -1)
-		return NULL;
 	if (_logprog[0] == '[')
 		return NULL;
 	p = strrchr(_logprog, '/');
@@ -147,7 +157,13 @@ vlogprintf_r(struct logctx *ctx, FILE *s
 	log_pid = ((stream == stderr && ctx->log_opts & LOGERR_ERR_PID) ||
 	    (stream != stderr && ctx->log_opts & LOGERR_LOG_PID));
 	if (log_pid) {
-		if ((e = fprintf(stream, "[%d]", getpid())) == -1)
+		pid_t pid;
+
+		if (ctx->log_pid == 0)
+			pid = getpid();
+		else
+			pid = ctx->log_pid;
+		if ((e = fprintf(stream, "[%d]", pid)) == -1)
 			return -1;
 		len += e;
 	}
@@ -198,22 +214,37 @@ vlogmessage(int pri, const char *fmt, va
 	struct logctx *ctx = &_logctx;
 	int len = 0;
 
+	if (ctx->log_fd != -1) {
+		char buf[LOGERR_SYSLOGBUF];
+		pid_t pid;
+
+		memcpy(buf, &pri, sizeof(pri));
+		pid = getpid();
+		memcpy(buf + sizeof(pri), &pid, sizeof(pid));
+		len = vsnprintf(buf + sizeof(pri) + sizeof(pid),
+		    sizeof(buf) - sizeof(pri) - sizeof(pid),
+		    fmt, args);
+		if (len != -1)
+			len = (int)write(ctx->log_fd, buf,
+			    ((size_t)++len) + sizeof(pri) + sizeof(pid));
+		return len;
+	}
+
 	if (ctx->log_opts & LOGERR_ERR &&
 	    (pri <= LOG_ERR ||
 	    (!(ctx->log_opts & LOGERR_QUIET) && pri <= LOG_INFO) ||
 	    (ctx->log_opts & LOGERR_DEBUG && pri <= LOG_DEBUG)))
 		len = vlogprintf_r(ctx, stderr, fmt, args);
 
-	if (!(ctx->log_opts & LOGERR_LOG))
-		return len;
-
 #ifndef SMALL
 	if (ctx->log_file != NULL &&
 	    (pri != LOG_DEBUG || (ctx->log_opts & LOGERR_DEBUG)))
 		len = vlogprintf_r(ctx, ctx->log_file, fmt, args);
 #endif
 
-	vsyslog(pri, fmt, args);
+	if (ctx->log_opts & LOGERR_LOG)
+		vsyslog(pri, fmt, args);
+
 	return len;
 }
 #if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 5))
@@ -331,6 +362,54 @@ log_errx(const char *fmt, ...)
 	va_end(args);
 }
 
+int
+loggetfd(void)
+{
+	struct logctx *ctx = &_logctx;
+
+	return ctx->log_fd;
+}
+
+void
+logsetfd(int fd)
+{
+	struct logctx *ctx = &_logctx;
+
+	ctx->log_fd = fd;
+#ifndef SMALL
+	if (fd != -1 && ctx->log_file != NULL) {
+		fclose(ctx->log_file);
+		ctx->log_file = NULL;
+	}
+#endif
+}
+
+int
+logreadfd(int fd)
+{
+	struct logctx *ctx = &_logctx;
+	char buf[LOGERR_SYSLOGBUF];
+	int len, pri;
+
+	len = (int)read(fd, buf, sizeof(buf));
+	if (len == -1)
+		return -1;
+
+	/* Ensure we have pri, pid and a terminator */
+	if (len < (int)(sizeof(pri) + sizeof(pid_t) + 1) ||
+	    buf[len - 1] != '\0')
+	{
+		errno = EINVAL;
+		return -1;
+	}
+
+	memcpy(&pri, buf, sizeof(pri));
+	memcpy(&ctx->log_pid, buf + sizeof(pri), sizeof(ctx->log_pid));
+	logmessage(pri, "%s", buf + sizeof(pri) + sizeof(ctx->log_pid));
+	ctx->log_pid = 0;
+	return len;
+}
+
 unsigned int
 loggetopts(void)
 {
@@ -373,15 +452,16 @@ logopen(const char *path)
 
 	(void)setvbuf(stderr, ctx->log_buf, _IOLBF, sizeof(ctx->log_buf));
 
-	if (!(ctx->log_opts & LOGERR_LOG))
-		return 1;
-
-#ifdef LOG_NDELAY
-	opts |= LOG_NDELAY;
+#ifndef SMALL
+	if (ctx->log_file != NULL) {
+		fclose(ctx->log_file);
+		ctx->log_file = NULL;
+	}
 #endif
+
 	if (ctx->log_opts & LOGERR_LOG_PID)
 		opts |= LOG_PID;
-	openlog(NULL, opts, LOGERR_SYSLOG_FACILITY);
+	openlog(getprogname(), opts, LOGERR_SYSLOG_FACILITY);
 	if (path == NULL)
 		return 1;
 
@@ -410,7 +490,7 @@ logclose(void)
 	fclose(ctx->log_file);
 	ctx->log_file = NULL;
 #endif
-#if defined(LOGERR_TAG) && defined(__linux__)
+#if defined(__linux__)
 	free(_logprog);
 #endif
 }

Index: src/external/bsd/dhcpcd/dist/src/privsep.c
diff -u src/external/bsd/dhcpcd/dist/src/privsep.c:1.9 src/external/bsd/dhcpcd/dist/src/privsep.c:1.10
--- src/external/bsd/dhcpcd/dist/src/privsep.c:1.9	Mon Oct 12 14:09:03 2020
+++ src/external/bsd/dhcpcd/dist/src/privsep.c	Sun Nov  1 14:24:01 2020
@@ -542,6 +542,19 @@ ps_mastersandbox(struct dhcpcd_ctx *ctx,
 	dropped = ps_dropprivs(ctx);
 	if (forked)
 		ctx->options |= DHCPCD_FORKED;
+
+	/*
+	 * If we don't have a root process, we cannot use syslog.
+	 * If it cannot be opened before chrooting then syslog(3) will fail.
+	 * openlog(3) does not return an error which doubly sucks.
+	 */
+	if (ctx->ps_root_fd == -1) {
+		unsigned int logopts = loggetopts();
+
+		logopts &= ~LOGERR_LOG;
+		logsetopts(logopts);
+	}
+
 	if (dropped == -1) {
 		logerr("%s: ps_dropprivs", __func__);
 		return -1;

Reply via email to