Module Name: src Committed By: roy Date: Mon Dec 18 15:51:28 UTC 2023
Modified Files: src/external/bsd/dhcpcd/dist/src: bpf.c dhcp.c dhcp6.c dhcpcd.c if-options.c privsep.c Log Message: Sync with dhcpcd-10.0.6 To generate a diff of this commit: cvs rdiff -u -r1.20 -r1.21 src/external/bsd/dhcpcd/dist/src/bpf.c cvs rdiff -u -r1.49 -r1.50 src/external/bsd/dhcpcd/dist/src/dhcp.c cvs rdiff -u -r1.31 -r1.32 src/external/bsd/dhcpcd/dist/src/dhcp6.c cvs rdiff -u -r1.53 -r1.54 src/external/bsd/dhcpcd/dist/src/dhcpcd.c cvs rdiff -u -r1.35 -r1.36 src/external/bsd/dhcpcd/dist/src/if-options.c cvs rdiff -u -r1.17 -r1.18 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/bpf.c diff -u src/external/bsd/dhcpcd/dist/src/bpf.c:1.20 src/external/bsd/dhcpcd/dist/src/bpf.c:1.21 --- src/external/bsd/dhcpcd/dist/src/bpf.c:1.20 Wed Jul 19 13:53:03 2023 +++ src/external/bsd/dhcpcd/dist/src/bpf.c Mon Dec 18 15:51:28 2023 @@ -41,6 +41,7 @@ #define bpf_insn sock_filter #else #include <net/bpf.h> +#include <net/if_vlanvar.h> #endif #include <errno.h> @@ -315,17 +316,34 @@ ssize_t bpf_send(const struct bpf *bpf, uint16_t protocol, const void *data, size_t len) { - struct iovec iov[2]; + struct iovec iov[3]; struct ether_header eh; + struct ether_vlan_header evh; + const struct interface *ifp = bpf->bpf_ifp; - switch(bpf->bpf_ifp->hwtype) { + switch(ifp->hwtype) { case ARPHRD_ETHER: - memset(&eh.ether_dhost, 0xff, sizeof(eh.ether_dhost)); - memcpy(&eh.ether_shost, bpf->bpf_ifp->hwaddr, - sizeof(eh.ether_shost)); - eh.ether_type = htons(protocol); - iov[0].iov_base = &eh; - iov[0].iov_len = sizeof(eh); +#ifdef BSD + loginfox("%d", ifp->vlanid); + if (ifp->vlanid) { + memset(&evh.evl_dhost, 0xff, sizeof(evh.evl_dhost)); + memcpy(&evh.evl_shost, ifp->hwaddr, + sizeof(evh.evl_shost)); + evh.evl_proto = htons(protocol); + evh.evl_encap_proto = htons(ETHERTYPE_VLAN); + evh.evl_tag = htons(ifp->vlanid); + iov[0].iov_base = &evh; + iov[0].iov_len = sizeof(evh); + } else +#endif + { + memset(&eh.ether_dhost, 0xff, sizeof(eh.ether_dhost)); + memcpy(&eh.ether_shost, ifp->hwaddr, + sizeof(eh.ether_shost)); + eh.ether_type = htons(protocol); + iov[0].iov_base = &eh; + iov[0].iov_len = sizeof(eh); + } break; default: iov[0].iov_base = NULL; @@ -694,7 +712,7 @@ int bpf_bootp(const struct bpf *bpf, __unused const struct in_addr *ia) { -#ifdef BIOCSETWF +#ifdef BIOCSETWFx if (bpf_bootp_rw(bpf, true) == -1 || bpf_bootp_rw(bpf, false) == -1 || ioctl(bpf->bpf_fd, BIOCLOCK) == -1) Index: src/external/bsd/dhcpcd/dist/src/dhcp.c diff -u src/external/bsd/dhcpcd/dist/src/dhcp.c:1.49 src/external/bsd/dhcpcd/dist/src/dhcp.c:1.50 --- src/external/bsd/dhcpcd/dist/src/dhcp.c:1.49 Fri Oct 6 08:49:42 2023 +++ src/external/bsd/dhcpcd/dist/src/dhcp.c Mon Dec 18 15:51:28 2023 @@ -1896,12 +1896,29 @@ dhcp_discover(void *arg) } static void +dhcp_requestfailed(void *arg) +{ + struct interface *ifp = arg; + struct dhcp_state *state = D_STATE(ifp); + + logwarnx("%s: failed to request the lease", ifp->name); + free(state->offer); + state->offer = NULL; + state->offer_len = 0; + state->interval = 0; + dhcp_discover(ifp); +} + +static void dhcp_request(void *arg) { struct interface *ifp = arg; struct dhcp_state *state = D_STATE(ifp); state->state = DHS_REQUEST; + // Handle the server being silent to our request. + eloop_timeout_add_sec(ifp->ctx->eloop, ifp->options->reboot, + dhcp_requestfailed, ifp); send_request(ifp); } Index: src/external/bsd/dhcpcd/dist/src/dhcp6.c diff -u src/external/bsd/dhcpcd/dist/src/dhcp6.c:1.31 src/external/bsd/dhcpcd/dist/src/dhcp6.c:1.32 --- src/external/bsd/dhcpcd/dist/src/dhcp6.c:1.31 Fri Oct 6 08:49:42 2023 +++ src/external/bsd/dhcpcd/dist/src/dhcp6.c Mon Dec 18 15:51:28 2023 @@ -2589,21 +2589,17 @@ dhcp6_validatelease(struct interface *if } state->has_no_binding = false; nia = dhcp6_findia(ifp, m, len, sfrom, acquired); - if (nia == 0) { - if (state->state != DH6S_CONFIRM && ok_errno != 0) { - logerrx("%s: no useable IA found in lease", ifp->name); - return -1; - } - - /* We are confirming and have an OK, - * so look for ia's in our old lease. - * IA's must have existed here otherwise we would - * have rejected it earlier. */ - assert(state->new != NULL && state->new_len != 0); + if (nia == 0 && state->state == DH6S_CONFIRM && ok_errno == 0 && + state->new && state->new_len) + { state->has_no_binding = false; nia = dhcp6_findia(ifp, state->new, state->new_len, sfrom, acquired); } + if (nia == 0) { + logerrx("%s: no useable IA found in lease", ifp->name); + return -1; + } return nia; } @@ -2657,8 +2653,10 @@ dhcp6_readlease(struct interface *ifp, i /* Check to see if the lease is still valid */ fd = dhcp6_validatelease(ifp, &buf.dhcp6, (size_t)bytes, NULL, &state->acquired); - if (fd == -1) + if (fd == -1) { + bytes = 0; /* We have already reported the error */ goto ex; + } if (state->expire != ND6_INFINITE_LIFETIME && (time_t)state->expire < now - mtime && @@ -3873,8 +3871,9 @@ dhcp6_activateinterfaces(struct interfac sla = &ia->sla[j]; ifd = if_find(ifp->ctx->ifaces, sla->ifname); if (ifd == NULL) { - logwarn("%s: cannot delegate to %s", - ifp->name, sla->ifname); + if (*sla->ifname != '-') + logwarn("%s: cannot delegate to %s", + ifp->name, sla->ifname); continue; } if (!ifd->active) { Index: src/external/bsd/dhcpcd/dist/src/dhcpcd.c diff -u src/external/bsd/dhcpcd/dist/src/dhcpcd.c:1.53 src/external/bsd/dhcpcd/dist/src/dhcpcd.c:1.54 --- src/external/bsd/dhcpcd/dist/src/dhcpcd.c:1.53 Thu Oct 19 11:26:52 2023 +++ src/external/bsd/dhcpcd/dist/src/dhcpcd.c Mon Dec 18 15:51:28 2023 @@ -339,18 +339,14 @@ dhcpcd_daemonised(struct dhcpcd_ctx *ctx * Stop writing to stderr. * On the happy path, only the manager process writes to stderr, * so this just stops wasting fprintf calls to nowhere. - * All other calls - ie errors in privsep processes or script output, - * will error when printing. - * If we *really* want to fix that, then we need to suck - * stderr/stdout in the manager process and either discard it or pass - * it to the launcher process and then to stderr. */ logopts &= ~LOGERR_ERR; logsetopts(logopts); /* - * We need to do something with stdout/stderr to avoid SIGPIPE - * We know that stdin is already mapped to /dev/null + * We need to do something with stdout/stderr to avoid SIGPIPE. + * We know that stdin is already mapped to /dev/null. + * TODO: Capture script output and log it to the logfile and/or syslog. */ dup2(STDIN_FILENO, STDOUT_FILENO); dup2(STDIN_FILENO, STDERR_FILENO); @@ -368,8 +364,7 @@ dhcpcd_daemonise(struct dhcpcd_ctx *ctx) errno = ENOSYS; return; #else - int i; - unsigned int logopts = loggetopts(); + int exit_code; if (ctx->options & DHCPCD_DAEMONISE && !(ctx->options & (DHCPCD_DAEMONISED | DHCPCD_NOWAITIP))) @@ -389,22 +384,17 @@ dhcpcd_daemonise(struct dhcpcd_ctx *ctx) !(ctx->options & DHCPCD_DAEMONISE)) return; - /* Don't use loginfo because this makes no sense in a log. */ - if (!(logopts & LOGERR_QUIET) && ctx->stderr_valid) - (void)fprintf(stderr, - "forked to background, child pid %d\n", getpid()); - #ifdef PRIVSEP - ps_daemonised(ctx); -#else - dhcpcd_daemonised(ctx); + if (IN_PRIVSEP(ctx)) + ps_daemonised(ctx); + else #endif + dhcpcd_daemonised(ctx); - i = EXIT_SUCCESS; - if (write(ctx->fork_fd, &i, sizeof(i)) == -1) - logerr("write"); - ctx->options |= DHCPCD_DAEMONISED; eloop_event_delete(ctx->eloop, ctx->fork_fd); + exit_code = EXIT_SUCCESS; + if (write(ctx->fork_fd, &exit_code, sizeof(exit_code)) == -1) + logerr(__func__); close(ctx->fork_fd); ctx->fork_fd = -1; #endif @@ -667,20 +657,17 @@ configure_interface(struct interface *if } static void -dhcpcd_initstate2(struct interface *ifp, unsigned long long options) +dhcpcd_initstate1(struct interface *ifp, int argc, char **argv, + unsigned long long options) { struct if_options *ifo; - if (options) { - if ((ifo = default_config(ifp->ctx)) == NULL) { - logerr(__func__); - return; - } - ifo->options |= options; - free(ifp->options); - ifp->options = ifo; - } else - ifo = ifp->options; + configure_interface(ifp, argc, argv, options); + if (!ifp->active) + return; + + ifo = ifp->options; + ifo->options |= options; #ifdef INET6 if (ifo->options & DHCPCD_IPV6 && ipv6_init(ifp->ctx) == -1) { @@ -691,16 +678,6 @@ dhcpcd_initstate2(struct interface *ifp, } static void -dhcpcd_initstate1(struct interface *ifp, int argc, char **argv, - unsigned long long options) -{ - - configure_interface(ifp, argc, argv, options); - if (ifp->active) - dhcpcd_initstate2(ifp, 0); -} - -static void dhcpcd_initstate(struct interface *ifp, unsigned long long options) { @@ -1043,15 +1020,17 @@ dhcpcd_activateinterface(struct interfac if (ifp->active) return; + /* IF_ACTIVE_USER will start protocols when the interface is started. + * IF_ACTIVE will ask the protocols for setup, + * such as any delegated prefixes. */ ifp->active = IF_ACTIVE; - dhcpcd_initstate2(ifp, options); + dhcpcd_initstate(ifp, options); /* It's possible we might not have been able to load * a config. */ if (!ifp->active) return; - configure_interface1(ifp); run_preinit(ifp); dhcpcd_prestartinterface(ifp); } @@ -1839,40 +1818,34 @@ dhcpcd_fork_cb(void *arg, unsigned short len = read(ctx->fork_fd, &exit_code, sizeof(exit_code)); if (len == -1) { logerr(__func__); - exit_code = EXIT_FAILURE; - } else if ((size_t)len < sizeof(exit_code)) { - logerrx("%s: truncated read %zd (expected %zu)", - __func__, len, sizeof(exit_code)); - exit_code = EXIT_FAILURE; + eloop_exit(ctx->eloop, EXIT_FAILURE); + return; } - if (ctx->options & DHCPCD_FORKED) - eloop_exit(ctx->eloop, exit_code); - else - dhcpcd_signal_cb(exit_code, ctx); -} - -static void -dhcpcd_stderr_cb(void *arg, unsigned short events) -{ - struct dhcpcd_ctx *ctx = arg; - char log[BUFSIZ]; - ssize_t len; - - if (events & ELE_HANGUP) - eloop_exit(ctx->eloop, EXIT_SUCCESS); - - if (!(events & ELE_READ)) + if (len == 0) { + if (ctx->options & DHCPCD_FORKED) { + logerrx("%s: dhcpcd manager hungup", __func__); + eloop_exit(ctx->eloop, EXIT_FAILURE); + } else { + // Launcher exited + eloop_event_delete(ctx->eloop, ctx->fork_fd); + close(ctx->fork_fd); + ctx->fork_fd = -1; + } return; - - len = read(ctx->stderr_fd, log, sizeof(log) - 1); - if (len == -1) { - if (errno != ECONNRESET) - logerr(__func__); + } + if ((size_t)len < sizeof(exit_code)) { + logerrx("%s: truncated read %zd (expected %zu)", + __func__, len, sizeof(exit_code)); + eloop_exit(ctx->eloop, EXIT_FAILURE); return; } - log[len] = '\0'; - fprintf(stderr, "%s", log); + if (ctx->options & DHCPCD_FORKED) { + if (exit_code == EXIT_SUCCESS) + logdebugx("forked to background"); + eloop_exit(ctx->eloop, exit_code); + } else + dhcpcd_signal_cb(exit_code, ctx); } static void @@ -1922,7 +1895,7 @@ main(int argc, char **argv, char **envp) ssize_t len; #if defined(USE_SIGNALS) || !defined(THERE_IS_NO_FORK) pid_t pid; - int fork_fd[2], stderr_fd[2]; + int fork_fd[2]; #endif #ifdef USE_SIGNALS int sig = 0; @@ -2007,22 +1980,17 @@ main(int argc, char **argv, char **envp) TAILQ_INIT(&ctx.ps_processes); #endif - /* 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; - - /* Even we if we don't have input/outputs, we need to - * ensure they are setup for shells. */ - if (!ctx.stdin_valid) + logopts = LOGERR_LOG | LOGERR_LOG_DATE | LOGERR_LOG_PID; + + /* Ensure we have stdin, stdout and stderr file descriptors. + * This is important as we do run scripts which expect these. */ + if (fcntl(STDIN_FILENO, F_GETFD) == -1) dup_null(STDIN_FILENO); - if (!ctx.stdout_valid) + if (fcntl(STDOUT_FILENO, F_GETFD) == -1) dup_null(STDOUT_FILENO); - if (!ctx.stderr_valid) + if (fcntl(STDERR_FILENO, F_GETFD) == -1) dup_null(STDERR_FILENO); - - logopts = LOGERR_LOG | LOGERR_LOG_DATE | LOGERR_LOG_PID; - if (ctx.stderr_valid) + else logopts |= LOGERR_ERR; i = 0; @@ -2392,17 +2360,13 @@ printpidfile: loginfox(PACKAGE "-" VERSION " starting"); // We don't need stdin past this point - if (ctx.stdin_valid) - dup_null(STDIN_FILENO); + dup_null(STDIN_FILENO); #if defined(USE_SIGNALS) && !defined(THERE_IS_NO_FORK) if (!(ctx.options & DHCPCD_DAEMONISE)) goto start_manager; - if (xsocketpair(AF_UNIX, SOCK_SEQPACKET|SOCK_CXNB, 0, fork_fd) == -1 || - (ctx.stderr_valid && - xsocketpair(AF_UNIX, SOCK_SEQPACKET|SOCK_CXNB, 0, stderr_fd) == -1)) - { + if (xsocketpair(AF_UNIX, SOCK_SEQPACKET|SOCK_CXNB, 0, fork_fd) == -1) { logerr("socketpair"); goto exit_failure; } @@ -2423,22 +2387,6 @@ printpidfile: dhcpcd_fork_cb, &ctx) == -1) logerr("%s: eloop_event_add", __func__); - /* - * Redirect stderr to the stderr socketpair. - * Redirect stdout as well. - * dhcpcd doesn't output via stdout, but something in - * a called script might. - */ - 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) - dup_null(STDOUT_FILENO); - if (setsid() == -1) { logerr("%s: setsid", __func__); goto exit_failure; @@ -2472,19 +2420,6 @@ printpidfile: dhcpcd_fork_cb, &ctx) == -1) logerr("%s: eloop_event_add", __func__); - if (ctx.stderr_valid) { - ctx.stderr_fd = stderr_fd[0]; - close(stderr_fd[1]); -#ifdef PRIVSEP_RIGHTS - if (ps_rights_limit_fd(ctx.stderr_fd) == 1) { - logerr("ps_rights_limit_fd"); - goto exit_failure; - } -#endif - if (eloop_event_add(ctx.eloop, ctx.stderr_fd, ELE_READ, - dhcpcd_stderr_cb, &ctx) == -1) - logerr("%s: eloop_event_add", __func__); - } #ifdef PRIVSEP if (IN_PRIVSEP(&ctx) && ps_managersandbox(&ctx, NULL) == -1) goto exit_failure; @@ -2596,6 +2531,7 @@ start_manager: if (ifp->active == IF_ACTIVE_USER) break; } + if (ifp == NULL) { if (ctx.ifc == 0) { int loglevel; @@ -2736,6 +2672,15 @@ exit1: i = EXIT_FAILURE; eloop_free(ctx.ps_eloop); #endif + +#ifdef USE_SIGNALS + /* If still attached, detach from the launcher */ + if (ctx.options & DHCPCD_STARTED && ctx.fork_fd != -1) { + if (write(ctx.fork_fd, &i, sizeof(i)) == -1) + logerr("%s: write", __func__); + } +#endif + eloop_free(ctx.eloop); logclose(); free(ctx.logfile); @@ -2743,13 +2688,8 @@ exit1: #ifdef SETPROCTITLE_H setproctitle_fini(); #endif + #ifdef USE_SIGNALS - 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 | DHCPCD_PRIVSEP)) _exit(i); /* so atexit won't remove our pidfile */ #endif Index: src/external/bsd/dhcpcd/dist/src/if-options.c diff -u src/external/bsd/dhcpcd/dist/src/if-options.c:1.35 src/external/bsd/dhcpcd/dist/src/if-options.c:1.36 --- src/external/bsd/dhcpcd/dist/src/if-options.c:1.35 Fri Oct 6 08:49:42 2023 +++ src/external/bsd/dhcpcd/dist/src/if-options.c Mon Dec 18 15:51:28 2023 @@ -2407,7 +2407,7 @@ finish_config(struct if_options *ifo) ~(DHCPCD_IPV6RA_AUTOCONF | DHCPCD_IPV6RA_REQRDNSS); } -struct if_options * +static struct if_options * default_config(struct dhcpcd_ctx *ctx) { struct if_options *ifo; Index: src/external/bsd/dhcpcd/dist/src/privsep.c diff -u src/external/bsd/dhcpcd/dist/src/privsep.c:1.17 src/external/bsd/dhcpcd/dist/src/privsep.c:1.18 --- src/external/bsd/dhcpcd/dist/src/privsep.c:1.17 Thu Oct 19 11:26:52 2023 +++ src/external/bsd/dhcpcd/dist/src/privsep.c Mon Dec 18 15:51:28 2023 @@ -172,8 +172,7 @@ ps_dropprivs(struct dhcpcd_ctx *ctx) * Obviously this won't work if we are using a logfile * or redirecting stderr to a file. */ if ((ctx->options & DHC_NOCHKIO) == DHC_NOCHKIO || - (ctx->logfile == NULL && - (!ctx->stderr_valid || isatty(STDERR_FILENO) == 1))) + (ctx->logfile == NULL && isatty(STDERR_FILENO) == 1)) { if (setrlimit(RLIMIT_FSIZE, &rzero) == -1) logerr("setrlimit RLIMIT_FSIZE"); @@ -300,19 +299,16 @@ ps_rights_limit_fdpair(int fd[]) } static int -ps_rights_limit_stdio(struct dhcpcd_ctx *ctx) +ps_rights_limit_stdio() { const int iebadf = CAPH_IGNORE_EBADF; int error = 0; - if (ctx->stdin_valid && - caph_limit_stream(STDIN_FILENO, CAPH_READ | iebadf) == -1) + if (caph_limit_stream(STDIN_FILENO, CAPH_READ | iebadf) == -1) error = -1; - if (ctx->stdout_valid && - caph_limit_stream(STDOUT_FILENO, CAPH_WRITE | iebadf) == -1) + if (caph_limit_stream(STDOUT_FILENO, CAPH_WRITE | iebadf) == -1) error = -1; - if (ctx->stderr_valid && - caph_limit_stream(STDERR_FILENO, CAPH_WRITE | iebadf) == -1) + if (caph_limit_stream(STDERR_FILENO, CAPH_WRITE | iebadf) == -1) error = -1; return error; @@ -456,7 +452,7 @@ ps_startprocess(struct ps_process *psp, ctx->ps_log_root_fd = -1; } #ifdef PRIVSEP_RIGHTS - if (ps_rights_limit_stdio(ctx) == -1) { + if (ps_rights_limit_stdio() == -1) { logerr("ps_rights_limit_stdio"); goto errexit; } @@ -622,6 +618,9 @@ ps_entersandbox(const char *_pledge, con #elif defined(HAVE_PLEDGE) if (sandbox != NULL) *sandbox = "pledge"; + // There is no need to use unveil(2) because we are in an empty chroot + // This is encouraged by Theo de Raadt himself: + // https://www.mail-archive.com/misc@openbsd.org/msg171655.html return pledge(_pledge, NULL); #elif defined(HAVE_SECCOMP) if (sandbox != NULL) @@ -667,7 +666,7 @@ ps_managersandbox(struct dhcpcd_ctx *ctx #ifdef PRIVSEP_RIGHTS if ((ctx->pf_inet_fd != -1 && ps_rights_limit_ioctl(ctx->pf_inet_fd) == -1) || - ps_rights_limit_stdio(ctx) == -1) + ps_rights_limit_stdio() == -1) { logerr("%s: cap_rights_limit", __func__); return -1;