Module Name: src
Committed By: roy
Date: Sun Sep 6 14:55:34 UTC 2020
Modified Files:
src/external/bsd/dhcpcd/dist/src: dhcp.c dhcpcd.8.in dhcpcd.c
if-options.c ipv6.c ipv6nd.c logerr.c privsep.c
Log Message:
Sync
To generate a diff of this commit:
cvs rdiff -u -r1.38 -r1.39 src/external/bsd/dhcpcd/dist/src/dhcp.c
cvs rdiff -u -r1.7 -r1.8 src/external/bsd/dhcpcd/dist/src/dhcpcd.8.in \
src/external/bsd/dhcpcd/dist/src/logerr.c
cvs rdiff -u -r1.41 -r1.42 src/external/bsd/dhcpcd/dist/src/dhcpcd.c
cvs rdiff -u -r1.26 -r1.27 src/external/bsd/dhcpcd/dist/src/if-options.c
cvs rdiff -u -r1.13 -r1.14 src/external/bsd/dhcpcd/dist/src/ipv6.c
cvs rdiff -u -r1.22 -r1.23 src/external/bsd/dhcpcd/dist/src/ipv6nd.c
cvs rdiff -u -r1.6 -r1.7 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.38 src/external/bsd/dhcpcd/dist/src/dhcp.c:1.39
--- src/external/bsd/dhcpcd/dist/src/dhcp.c:1.38 Thu Jun 4 13:08:13 2020
+++ src/external/bsd/dhcpcd/dist/src/dhcp.c Sun Sep 6 14:55:34 2020
@@ -777,7 +777,7 @@ make_message(struct bootp **bootpm, cons
(type == DHCP_REQUEST &&
state->addr->mask.s_addr == lease->mask.s_addr &&
(state->new == NULL || IS_DHCP(state->new)) &&
- !(state->added & STATE_FAKE))))
+ !(state->added & (STATE_FAKE | STATE_EXPIRED)))))
bootp->ciaddr = state->addr->addr.s_addr;
bootp->op = BOOTREQUEST;
@@ -836,7 +836,7 @@ make_message(struct bootp **bootpm, cons
if (type == DHCP_DECLINE ||
(type == DHCP_REQUEST &&
(state->addr == NULL ||
- state->added & STATE_FAKE ||
+ state->added & (STATE_FAKE | STATE_EXPIRED) ||
lease->addr.s_addr != state->addr->addr.s_addr)))
{
putip = true;
@@ -1745,7 +1745,7 @@ send_message(struct interface *ifp, uint
goto fail;
len = (size_t)r;
- if (!(state->added & STATE_FAKE) &&
+ if (!(state->added & (STATE_FAKE | STATE_EXPIRED)) &&
state->addr != NULL &&
ipv4_iffindaddr(ifp, &state->lease.addr, NULL) != NULL)
from.s_addr = state->lease.addr.s_addr;
@@ -1869,14 +1869,16 @@ dhcp_discover(void *arg)
state->state = DHS_DISCOVER;
dhcp_new_xid(ifp);
eloop_timeout_delete(ifp->ctx->eloop, NULL, ifp);
- if (ifo->fallback)
- eloop_timeout_add_sec(ifp->ctx->eloop,
- ifo->reboot, dhcp_fallback, ifp);
+ if (!(state->added & STATE_EXPIRED)) {
+ if (ifo->fallback)
+ eloop_timeout_add_sec(ifp->ctx->eloop,
+ ifo->reboot, dhcp_fallback, ifp);
#ifdef IPV4LL
- else if (ifo->options & DHCPCD_IPV4LL)
- eloop_timeout_add_sec(ifp->ctx->eloop,
- ifo->reboot, ipv4ll_start, ifp);
+ else if (ifo->options & DHCPCD_IPV4LL)
+ eloop_timeout_add_sec(ifp->ctx->eloop,
+ ifo->reboot, ipv4ll_start, ifp);
#endif
+ }
if (ifo->options & DHCPCD_REQUEST)
loginfox("%s: soliciting a DHCP lease (requesting %s)",
ifp->name, inet_ntoa(ifo->req_addr));
@@ -1897,30 +1899,21 @@ dhcp_request(void *arg)
}
static void
-dhcp_expire1(struct interface *ifp)
-{
- struct dhcp_state *state = D_STATE(ifp);
-
- eloop_timeout_delete(ifp->ctx->eloop, NULL, ifp);
- dhcp_drop(ifp, "EXPIRE");
- dhcp_unlink(ifp->ctx, state->leasefile);
- state->interval = 0;
- if (!(ifp->options->options & DHCPCD_LINK) || ifp->carrier > LINK_DOWN)
- dhcp_discover(ifp);
-}
-
-static void
dhcp_expire(void *arg)
{
struct interface *ifp = arg;
+ struct dhcp_state *state = D_STATE(ifp);
if (ifp->options->options & DHCPCD_LASTLEASE_EXTEND) {
logwarnx("%s: DHCP lease expired, extending lease", ifp->name);
- return;
+ state->added |= STATE_EXPIRED;
+ } else {
+ logerrx("%s: DHCP lease expired", ifp->name);
+ dhcp_drop(ifp, "EXPIRE");
+ dhcp_unlink(ifp->ctx, state->leasefile);
}
-
- logerrx("%s: DHCP lease expired", ifp->name);
- dhcp_expire1(ifp);
+ state->interval = 0;
+ dhcp_discover(ifp);
}
#if defined(ARP) || defined(IN_IFF_DUPLICATED)
@@ -2291,7 +2284,9 @@ dhcp_bind(struct interface *ifp)
return;
}
if (state->reason == NULL) {
- if (state->old && !(state->added & STATE_FAKE)) {
+ if (state->old &&
+ !(state->added & (STATE_FAKE | STATE_EXPIRED)))
+ {
if (state->old->yiaddr == state->new->yiaddr &&
lease->server.s_addr &&
state->state != DHS_REBIND)
@@ -2364,19 +2359,6 @@ dhcp_bind(struct interface *ifp)
eloop_event_add(ctx->eloop, state->udp_rfd, dhcp_handleifudp, ifp);
}
-static void
-dhcp_lastlease(void *arg)
-{
- struct interface *ifp = arg;
- struct dhcp_state *state = D_STATE(ifp);
-
- loginfox("%s: timed out contacting a DHCP server, using last lease",
- ifp->name);
- dhcp_bind(ifp);
- state->interval = 0;
- dhcp_discover(ifp);
-}
-
static size_t
dhcp_message_new(struct bootp **bootp,
const struct in_addr *addr, const struct in_addr *mask)
@@ -2476,6 +2458,26 @@ dhcp_arp_bind(struct interface *ifp)
#endif
static void
+dhcp_lastlease(void *arg)
+{
+ struct interface *ifp = arg;
+ struct dhcp_state *state = D_STATE(ifp);
+
+ loginfox("%s: timed out contacting a DHCP server, using last lease",
+ ifp->name);
+#if defined(ARP) || defined(KERNEL_RFC5227)
+ dhcp_arp_bind(ifp);
+#else
+ dhcp_bind(ifp);
+#endif
+ /* Set expired here because dhcp_bind() -> ipv4_addaddr() will reset
+ * state */
+ state->added |= STATE_EXPIRED;
+ state->interval = 0;
+ dhcp_discover(ifp);
+}
+
+static void
dhcp_static(struct interface *ifp)
{
struct if_options *ifo;
Index: src/external/bsd/dhcpcd/dist/src/dhcpcd.8.in
diff -u src/external/bsd/dhcpcd/dist/src/dhcpcd.8.in:1.7 src/external/bsd/dhcpcd/dist/src/dhcpcd.8.in:1.8
--- src/external/bsd/dhcpcd/dist/src/dhcpcd.8.in:1.7 Thu Jun 4 13:08:13 2020
+++ src/external/bsd/dhcpcd/dist/src/dhcpcd.8.in Sun Sep 6 14:55:34 2020
@@ -24,7 +24,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd May 31, 2020
+.Dd September 2, 2020
.Dt DHCPCD 8
.Os
.Sh NAME
@@ -385,8 +385,10 @@ If no interfaces are left running,
.Nm
will exit.
.It Fl l , Fl Fl leasetime Ar seconds
-Request a specific lease time in
+Request a lease time of
.Ar seconds .
+.Ar -1
+represents an infinite lease time.
By default
.Nm
does not request any lease time and leaves it in the hands of the
Index: src/external/bsd/dhcpcd/dist/src/logerr.c
diff -u src/external/bsd/dhcpcd/dist/src/logerr.c:1.7 src/external/bsd/dhcpcd/dist/src/logerr.c:1.8
--- src/external/bsd/dhcpcd/dist/src/logerr.c:1.7 Thu Jul 2 17:15:00 2020
+++ src/external/bsd/dhcpcd/dist/src/logerr.c Sun Sep 6 14:55:34 2020
@@ -52,7 +52,6 @@
struct logctx {
char log_buf[BUFSIZ];
unsigned int log_opts;
- FILE *log_err;
#ifndef SMALL
FILE *log_file;
#ifdef LOGERR_TAG
@@ -120,14 +119,13 @@ vlogprintf_r(struct logctx *ctx, FILE *s
int len = 0, e;
va_list a;
#ifndef SMALL
- FILE *err = ctx->log_err == NULL ? stderr : ctx->log_err;
bool log_pid;
#ifdef LOGERR_TAG
bool log_tag;
#endif
- if ((stream == err && ctx->log_opts & LOGERR_ERR_DATE) ||
- (stream != err && ctx->log_opts & LOGERR_LOG_DATE))
+ if ((stream == stderr && ctx->log_opts & LOGERR_ERR_DATE) ||
+ (stream != stderr && ctx->log_opts & LOGERR_LOG_DATE))
{
if ((e = logprintdate(stream)) == -1)
return -1;
@@ -135,8 +133,8 @@ vlogprintf_r(struct logctx *ctx, FILE *s
}
#ifdef LOGERR_TAG
- log_tag = ((stream == err && ctx->log_opts & LOGERR_ERR_TAG) ||
- (stream != err && ctx->log_opts & LOGERR_LOG_TAG));
+ log_tag = ((stream == stderr && ctx->log_opts & LOGERR_ERR_TAG) ||
+ (stream != stderr && ctx->log_opts & LOGERR_LOG_TAG));
if (log_tag) {
if (ctx->log_tag == NULL)
ctx->log_tag = getprogname();
@@ -146,8 +144,8 @@ vlogprintf_r(struct logctx *ctx, FILE *s
}
#endif
- log_pid = ((stream == err && ctx->log_opts & LOGERR_ERR_PID) ||
- (stream != err && ctx->log_opts & LOGERR_LOG_PID));
+ 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)
return -1;
@@ -204,12 +202,7 @@ vlogmessage(int pri, const char *fmt, va
(pri <= LOG_ERR ||
(!(ctx->log_opts & LOGERR_QUIET) && pri <= LOG_INFO) ||
(ctx->log_opts & LOGERR_DEBUG && pri <= LOG_DEBUG)))
- {
- FILE *err;
-
- err = ctx->log_err == NULL ? stderr : ctx->log_err;
- len = vlogprintf_r(ctx, err, fmt, args);
- }
+ len = vlogprintf_r(ctx, stderr, fmt, args);
if (!(ctx->log_opts & LOGERR_LOG))
return len;
@@ -370,30 +363,6 @@ logsettag(const char *tag)
#endif
int
-loggeterrfd(void)
-{
- struct logctx *ctx = &_logctx;
- FILE *err = ctx->log_err == NULL ? stderr : ctx->log_err;
-
- return fileno(err);
-}
-
-int
-logseterrfd(int fd)
-{
- struct logctx *ctx = &_logctx;
-
- if (ctx->log_err != NULL)
- fclose(ctx->log_err);
- if (fd == -1) {
- ctx->log_err = NULL;
- return 0;
- }
- ctx->log_err = fdopen(fd, "a");
- return ctx->log_err == NULL ? -1 : 0;
-}
-
-int
logopen(const char *path)
{
struct logctx *ctx = &_logctx;
Index: src/external/bsd/dhcpcd/dist/src/dhcpcd.c
diff -u src/external/bsd/dhcpcd/dist/src/dhcpcd.c:1.41 src/external/bsd/dhcpcd/dist/src/dhcpcd.c:1.42
--- src/external/bsd/dhcpcd/dist/src/dhcpcd.c:1.41 Fri Jul 3 10:46:45 2020
+++ src/external/bsd/dhcpcd/dist/src/dhcpcd.c Sun Sep 6 14:55:34 2020
@@ -336,7 +336,7 @@ dhcpcd_daemonise(struct dhcpcd_ctx *ctx)
#ifdef THERE_IS_NO_FORK
eloop_timeout_delete(ctx->eloop, handle_exit_timeout, ctx);
errno = ENOSYS;
- return 0;
+ return;
#else
int i;
unsigned int logopts = loggetopts();
@@ -361,8 +361,8 @@ dhcpcd_daemonise(struct dhcpcd_ctx *ctx)
/* Don't use loginfo because this makes no sense in a log. */
if (!(logopts & LOGERR_QUIET))
- (void)fprintf(stderr, "forked to background, child pid %d\n",
- getpid());
+ (void)fprintf(stderr,
+ "forked to background, child pid %d\n", getpid());
i = EXIT_SUCCESS;
if (write(ctx->fork_fd, &i, sizeof(i)) == -1)
logerr("write");
@@ -371,11 +371,18 @@ dhcpcd_daemonise(struct dhcpcd_ctx *ctx)
close(ctx->fork_fd);
ctx->fork_fd = -1;
- if (isatty(loggeterrfd())) {
- logopts &= ~LOGERR_ERR;
- logsetopts(logopts);
- logseterrfd(-1);
- }
+ /*
+ * Stop writing to stderr.
+ * On the happy path, only the master 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 master process and either disacrd it or pass
+ * it to the launcher process and then to stderr.
+ */
+ logopts &= ~LOGERR_ERR;
+ logsetopts(logopts);
#endif
}
@@ -1153,6 +1160,15 @@ dhcpcd_setlinkrcvbuf(struct dhcpcd_ctx *
}
#endif
+static void
+dhcpcd_runprestartinterface(void *arg)
+{
+ struct interface *ifp = arg;
+
+ run_preinit(ifp);
+ dhcpcd_prestartinterface(ifp);
+}
+
void
dhcpcd_linkoverflow(struct dhcpcd_ctx *ctx)
{
@@ -1215,9 +1231,11 @@ dhcpcd_linkoverflow(struct dhcpcd_ctx *c
continue;
}
TAILQ_INSERT_TAIL(ctx->ifaces, ifp, next);
- if (ifp->active)
+ if (ifp->active) {
+ dhcpcd_initstate(ifp, 0);
eloop_timeout_add_sec(ctx->eloop, 0,
- dhcpcd_prestartinterface, ifp);
+ dhcpcd_runprestartinterface, ifp);
+ }
}
free(ifaces);
@@ -1765,6 +1783,24 @@ dhcpcd_fork_cb(void *arg)
eloop_exit(ctx->eloop, exit_code);
}
+static void
+dhcpcd_stderr_cb(void *arg)
+{
+ struct dhcpcd_ctx *ctx = arg;
+ char log[BUFSIZ];
+ ssize_t len;
+
+ len = read(ctx->stderr_fd, log, sizeof(log));
+ if (len == -1) {
+ if (errno != ECONNRESET)
+ logerr(__func__);
+ return;
+ }
+
+ log[len] = '\0';
+ fprintf(stderr, "%s", log);
+}
+
int
main(int argc, char **argv)
{
@@ -1778,7 +1814,7 @@ main(int argc, char **argv)
ssize_t len;
#if defined(USE_SIGNALS) || !defined(THERE_IS_NO_FORK)
pid_t pid;
- int sigpipe[2];
+ int fork_fd[2], stderr_fd[2];
#endif
#ifdef USE_SIGNALS
int sig = 0;
@@ -2100,11 +2136,20 @@ printpidfile:
}
#endif
+#ifdef PRIVSEP
+ ps_init(&ctx);
+#endif
+
#ifndef SMALL
if (ctx.options & DHCPCD_DUMPLEASE &&
ioctl(fileno(stdin), FIONREAD, &i, sizeof(i)) == 0 &&
i > 0)
{
+ ctx.options |= DHCPCD_FORKED; /* pretend child process */
+#ifdef PRIVSEP
+ if (IN_PRIVSEP(&ctx) && ps_mastersandbox(&ctx) == -1)
+ goto exit_failure;
+#endif
ifp = calloc(1, sizeof(*ifp));
if (ifp == NULL) {
logerr(__func__);
@@ -2153,6 +2198,14 @@ printpidfile:
ctx.control_fd = control_open(NULL, AF_UNSPEC,
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;
+ goto exit_failure;
+ }
+ ctx.options |= DHCPCD_FORKED;
+#endif
if (!(ctx.options & DHCPCD_DUMPLEASE))
loginfox("sending commands to dhcpcd process");
len = control_send(&ctx, argc, argv);
@@ -2206,29 +2259,40 @@ printpidfile:
if (freopen(_PATH_DEVNULL, "r", stdin) == NULL)
logerr("%s: freopen stdin", __func__);
-
-#ifdef PRIVSEP
- ps_init(&ctx);
-#endif
-
-#ifdef USE_SIGNALS
- if (pipe(sigpipe) == -1) {
- logerr("pipe");
- goto exit_failure;
- }
-#ifdef HAVE_CAPSICUM
- if (ps_rights_limit_fdpair(sigpipe) == -1) {
- logerr("ps_rights_limit_fdpair");
+#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)
+ {
+ logerr("socketpair");
goto exit_failure;
}
-#endif
switch (pid = fork()) {
case -1:
logerr("fork");
goto exit_failure;
case 0:
- ctx.fork_fd = sigpipe[1];
- close(sigpipe[0]);
+ ctx.fork_fd = fork_fd[1];
+ close(fork_fd[0]);
+#ifdef PRIVSEP_RIGHTS
+ if (ps_rights_limit_fd(fork_fd[1]) == -1) {
+ logerr("ps_rights_limit_fdpair");
+ goto exit_failure;
+ }
+#endif
+ /*
+ * 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 (setsid() == -1) {
logerr("%s: setsid", __func__);
goto exit_failure;
@@ -2248,10 +2312,22 @@ printpidfile:
break;
default:
ctx.options |= DHCPCD_FORKED; /* A lie */
- ctx.fork_fd = sigpipe[0];
- close(sigpipe[1]);
+ 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)
+ {
+ logerr("ps_rights_limit_fdpair");
+ 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);
goto run_loop;
}
@@ -2270,22 +2346,6 @@ printpidfile:
if_disable_rtadv();
#endif
- if (isatty(STDOUT_FILENO) &&
- freopen(_PATH_DEVNULL, "r", stdout) == NULL)
- logerr("%s: freopen stdout", __func__);
- if (isatty(STDERR_FILENO)) {
- int fd = dup(STDERR_FILENO);
-
- if (fd == -1)
- logerr("%s: dup", __func__);
- else if (logseterrfd(fd) == -1)
- logerr("%s: logseterrfd", __func__);
- else if (freopen(_PATH_DEVNULL, "r", stderr) == NULL) {
- logseterrfd(-1);
- logerr("%s: freopen stderr", __func__);
- }
- }
-
#ifdef PRIVSEP
if (IN_PRIVSEP(&ctx) && ps_start(&ctx) == -1) {
logerr("ps_start");
Index: src/external/bsd/dhcpcd/dist/src/if-options.c
diff -u src/external/bsd/dhcpcd/dist/src/if-options.c:1.26 src/external/bsd/dhcpcd/dist/src/if-options.c:1.27
--- src/external/bsd/dhcpcd/dist/src/if-options.c:1.26 Thu Jul 2 13:59:19 2020
+++ src/external/bsd/dhcpcd/dist/src/if-options.c Sun Sep 6 14:55:34 2020
@@ -59,6 +59,8 @@
#define SET_CONFIG_BLOCK(ifo) ((ifo)->options |= DHCPCD_FORKED)
#define CLEAR_CONFIG_BLOCK(ifo) ((ifo)->options &= ~DHCPCD_FORKED)
+static unsigned long long default_options;
+
const struct option cf_options[] = {
{"background", no_argument, NULL, 'b'},
{"script", required_argument, NULL, 'c'},
@@ -759,6 +761,10 @@ parse_option(struct dhcpcd_ctx *ctx, con
break;
case 'l':
ARG_REQUIRED;
+ if (strcmp(arg, "-1") == 0) {
+ ifo->leasetime = DHCP_INFINITE_LIFETIME;
+ break;
+ }
ifo->leasetime = (uint32_t)strtou(arg, NULL,
0, 0, UINT32_MAX, &e);
if (e) {
@@ -1021,6 +1027,7 @@ parse_option(struct dhcpcd_ctx *ctx, con
}
ifo->options |= DHCPCD_CLIENTID;
ifo->clientid[0] = (uint8_t)s;
+ ifo->options &= ~DHCPCD_DUID;
break;
case 'J':
ifo->options |= DHCPCD_BROADCAST;
@@ -1204,13 +1211,23 @@ parse_option(struct dhcpcd_ctx *ctx, con
ifo->options |= DHCPCD_ONESHOT;
break;
case '4':
+#ifdef INET
ifo->options &= ~DHCPCD_IPV6;
ifo->options |= DHCPCD_IPV4;
break;
+#else
+ logerrx("INET has been compiled out");
+ return -1;
+#endif
case '6':
+#ifdef INET6
ifo->options &= ~DHCPCD_IPV4;
ifo->options |= DHCPCD_IPV6;
break;
+#else
+ logerrx("INET6 has been compiled out");
+ return -1;
+#endif
case O_IPV4:
ifo->options |= DHCPCD_IPV4;
break;
@@ -2090,6 +2107,12 @@ invalid_token:
break;
case O_CONTROLGRP:
ARG_REQUIRED;
+#ifdef PRIVSEP
+ /* Control group is already set by this point.
+ * We don't need to pledge getpw either with this. */
+ if (IN_PRIVSEP(ctx))
+ break;
+#endif
#ifdef _REENTRANT
l = sysconf(_SC_GETGR_R_SIZE_MAX);
if (l == -1)
@@ -2326,18 +2349,30 @@ read_config(struct dhcpcd_ctx *ctx,
/* Seed our default options */
if ((ifo = default_config(ctx)) == NULL)
return NULL;
- ifo->options |= DHCPCD_DAEMONISE | DHCPCD_GATEWAY;
-#ifdef PLUGIN_DEV
- ifo->options |= DHCPCD_DEV;
-#endif
+ if (default_options == 0) {
+ default_options |= DHCPCD_DAEMONISE | DHCPCD_GATEWAY;
#ifdef INET
- ifo->options |= DHCPCD_IPV4 | DHCPCD_ARP | DHCPCD_DHCP | DHCPCD_IPV4LL;
+ skip = socket(PF_INET, SOCK_DGRAM, 0);
+ if (skip != -1) {
+ close(skip);
+ default_options |= DHCPCD_IPV4 | DHCPCD_ARP |
+ DHCPCD_DHCP | DHCPCD_IPV4LL;
+ }
#endif
#ifdef INET6
- ifo->options |= DHCPCD_IPV6 | DHCPCD_IPV6RS;
- ifo->options |= DHCPCD_IPV6RA_AUTOCONF | DHCPCD_IPV6RA_REQRDNSS;
- ifo->options |= DHCPCD_DHCP6;
+ skip = socket(PF_INET6, SOCK_DGRAM, 0);
+ if (skip != -1) {
+ close(skip);
+ default_options |= DHCPCD_IPV6 | DHCPCD_IPV6RS |
+ DHCPCD_IPV6RA_AUTOCONF | DHCPCD_IPV6RA_REQRDNSS |
+ DHCPCD_DHCP6;
+ }
#endif
+#ifdef PLUGIN_DEV
+ default_options |= DHCPCD_DEV;
+#endif
+ }
+ ifo->options |= default_options;
CLEAR_CONFIG_BLOCK(ifo);
Index: src/external/bsd/dhcpcd/dist/src/ipv6.c
diff -u src/external/bsd/dhcpcd/dist/src/ipv6.c:1.13 src/external/bsd/dhcpcd/dist/src/ipv6.c:1.14
--- src/external/bsd/dhcpcd/dist/src/ipv6.c:1.13 Thu Jul 2 13:59:19 2020
+++ src/external/bsd/dhcpcd/dist/src/ipv6.c Sun Sep 6 14:55:34 2020
@@ -679,6 +679,14 @@ ipv6_addaddr1(struct ipv6_addr *ia, cons
/* Adjust plftime and vltime based on acquired time */
pltime = ia->prefix_pltime;
vltime = ia->prefix_vltime;
+
+ if (ifp->options->options & DHCPCD_LASTLEASE_EXTEND) {
+ /* We don't want the kernel to expire the address.
+ * The saved times will be re-applied to the ia
+ * before exiting this function. */
+ ia->prefix_vltime = ia->prefix_pltime = ND6_INFINITE_LIFETIME;
+ }
+
if (timespecisset(&ia->acquired) &&
(ia->prefix_pltime != ND6_INFINITE_LIFETIME ||
ia->prefix_vltime != ND6_INFINITE_LIFETIME))
@@ -1092,33 +1100,22 @@ ipv6_anyglobal(struct interface *sifp)
struct interface *ifp;
struct ipv6_state *state;
struct ipv6_addr *ia;
-#ifdef BSD
bool forwarding;
-#if defined(PRIVSEP) && defined(HAVE_PLEDGE)
+ /* BSD forwarding is either on or off.
+ * Linux forwarding is technically the same as it's
+ * configured by the "all" interface.
+ * Per interface only affects IsRouter of NA messages. */
+#if defined(PRIVSEP) && (defined(HAVE_PLEDGE) || defined(__linux__))
if (IN_PRIVSEP(sifp->ctx))
- forwarding = ps_root_ip6forwarding(sifp->ctx, NULL) == 1;
+ forwarding = ps_root_ip6forwarding(sifp->ctx, NULL) != 0;
else
#endif
- forwarding = ip6_forwarding(NULL) == 1;
-#endif
-
+ forwarding = ip6_forwarding(NULL) != 0;
TAILQ_FOREACH(ifp, sifp->ctx->ifaces, next) {
-#ifdef BSD
if (ifp != sifp && !forwarding)
continue;
-#else
-#if defined(PRIVSEP) && defined(__linux__)
- if (IN_PRIVSEP(sifp->ctx)) {
- if (ifp != sifp &&
- ps_root_ip6forwarding(sifp->ctx, ifp->name) != 1)
- continue;
- } else
-#endif
- if (ifp != sifp && ip6_forwarding(ifp->name) != 1)
- continue;
-#endif
state = IPV6_STATE(ifp);
if (state == NULL)
Index: src/external/bsd/dhcpcd/dist/src/ipv6nd.c
diff -u src/external/bsd/dhcpcd/dist/src/ipv6nd.c:1.22 src/external/bsd/dhcpcd/dist/src/ipv6nd.c:1.23
--- src/external/bsd/dhcpcd/dist/src/ipv6nd.c:1.22 Thu Jul 2 13:59:19 2020
+++ src/external/bsd/dhcpcd/dist/src/ipv6nd.c Sun Sep 6 14:55:34 2020
@@ -544,11 +544,11 @@ ipv6nd_advertise(struct ipv6_addr *ia)
na->nd_na_flags_reserved = ND_NA_FLAG_OVERRIDE;
#if defined(PRIVSEP) && (defined(__linux__) || defined(HAVE_PLEDGE))
if (IN_PRIVSEP(ctx)) {
- if (ps_root_ip6forwarding(ctx, ifp->name) == 1)
+ if (ps_root_ip6forwarding(ctx, ifp->name) != 0)
na->nd_na_flags_reserved |= ND_NA_FLAG_ROUTER;
} else
#endif
- if (ip6_forwarding(ifp->name) == 1)
+ if (ip6_forwarding(ifp->name) != 0)
na->nd_na_flags_reserved |= ND_NA_FLAG_ROUTER;
na->nd_na_target = ia->addr;
Index: src/external/bsd/dhcpcd/dist/src/privsep.c
diff -u src/external/bsd/dhcpcd/dist/src/privsep.c:1.6 src/external/bsd/dhcpcd/dist/src/privsep.c:1.7
--- src/external/bsd/dhcpcd/dist/src/privsep.c:1.6 Thu Jul 2 13:59:19 2020
+++ src/external/bsd/dhcpcd/dist/src/privsep.c Sun Sep 6 14:55:34 2020
@@ -34,6 +34,7 @@
* Spawn an unpriv process to send/receive common network data.
* Then drop all privs and start running.
* Every process aside from the privileged actioneer is chrooted.
+ * All privsep processes ignore signals - only the master process accepts them.
*
* dhcpcd will maintain the config file in the chroot, no need to handle
* this in a script or something.
@@ -74,6 +75,8 @@
#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>
@@ -109,7 +112,7 @@ ps_init(struct dhcpcd_ctx *ctx)
return 0;
}
-int
+static int
ps_dropprivs(struct dhcpcd_ctx *ctx)
{
struct passwd *pw = ctx->ps_user;
@@ -121,9 +124,10 @@ ps_dropprivs(struct dhcpcd_ctx *ctx)
if (chdir("/") == -1)
logerr("%s: chdir `/'", __func__);
- if (setgroups(1, &pw->pw_gid) == -1 ||
+ if ((setgroups(1, &pw->pw_gid) == -1 ||
setgid(pw->pw_gid) == -1 ||
- setuid(pw->pw_uid) == -1)
+ setuid(pw->pw_uid) == -1) &&
+ (errno != EPERM || ctx->options & DHCPCD_FORKED))
{
logerr("failed to drop privileges");
return -1;
@@ -162,7 +166,7 @@ ps_dropprivs(struct dhcpcd_ctx *ctx)
/* Prohibit writing to files.
* Obviously this won't work if we are using a logfile
* or redirecting stderr to a file. */
- if (ctx->logfile == NULL && isatty(loggeterrfd())) {
+ if (ctx->logfile == NULL) {
if (setrlimit(RLIMIT_FSIZE, &rzero) == -1)
logerr("setrlimit RLIMIT_FSIZE");
}
@@ -283,12 +287,10 @@ ps_dostart(struct dhcpcd_ctx *ctx,
void *recv_ctx, int (*callback)(void *), void (*signal_cb)(int, void *),
unsigned int flags)
{
- int stype;
int fd[2];
pid_t pid;
- stype = SOCK_CLOEXEC | SOCK_NONBLOCK;
- if (socketpair(AF_UNIX, SOCK_DGRAM | stype, 0, fd) == -1) {
+ if (xsocketpair(AF_UNIX, SOCK_DGRAM | SOCK_CXNB, 0, fd) == -1) {
logerr("%s: socketpair", __func__);
return -1;
}
@@ -341,6 +343,14 @@ ps_dostart(struct dhcpcd_ctx *ctx,
close(ctx->ps_root_fd);
ctx->ps_root_fd = -1;
}
+
+#ifdef PRIVSEP_RIGHTS
+ /* We cannot limit the root process in any way. */
+ if (ps_rights_limit_stdio() == -1) {
+ logerr("ps_rights_limit_stdio");
+ goto errexit;
+ }
+#endif
}
if (priv_fd != &ctx->ps_inet_fd && ctx->ps_inet_fd != -1) {
@@ -471,9 +481,10 @@ ps_mastersandbox(struct dhcpcd_ctx *ctx)
}
#ifdef PRIVSEP_RIGHTS
- if ((ps_rights_limit_ioctl(ctx->pf_inet_fd) == -1 ||
- ps_rights_limit_fd(ctx->link_fd) == -1) &&
- errno != ENOSYS)
+ 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)
{
logerr("%s: cap_rights_limit", __func__);
return -1;
@@ -645,12 +656,12 @@ ps_sendpsmmsg(struct dhcpcd_ctx *ctx, in
iovlen = 1;
len = writev(fd, iov, iovlen);
-#ifdef PRIVSEP_DEBUG
- logdebugx("%s: %zd", __func__, len);
-#endif
- if ((len == -1 || len == 0) && ctx->options & DHCPCD_FORKED &&
- !(ctx->options & DHCPCD_PRIVSEPROOT))
- eloop_exit(ctx->eloop, len == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
+ if (len == -1) {
+ logerr(__func__);
+ if (ctx->options & DHCPCD_FORKED &&
+ !(ctx->options & DHCPCD_PRIVSEPROOT))
+ eloop_exit(ctx->eloop, EXIT_FAILURE);
+ }
return len;
}
@@ -789,10 +800,9 @@ ps_recvmsg(struct dhcpcd_ctx *ctx, int r
};
ssize_t len = recvmsg(rfd, &msg, 0);
-#ifdef PRIVSEP_DEBUG
- logdebugx("%s: recv fd %d, %zd bytes", __func__, rfd, len);
-#endif
+ if (len == -1)
+ logerr("%s: recvmsg", __func__);
if (len == -1 || len == 0) {
if (ctx->options & DHCPCD_FORKED &&
!(ctx->options & DHCPCD_PRIVSEPROOT))
@@ -803,12 +813,12 @@ ps_recvmsg(struct dhcpcd_ctx *ctx, int r
iov[0].iov_len = (size_t)len;
len = ps_sendcmdmsg(wfd, cmd, &msg);
-#ifdef PRIVSEP_DEBUG
- logdebugx("%s: send fd %d, %zu bytes", __func__, wfd, len);
-#endif
- if ((len == -1 || len == 0) && ctx->options & DHCPCD_FORKED &&
- !(ctx->options & DHCPCD_PRIVSEPROOT))
- eloop_exit(ctx->eloop, len == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
+ if (len == -1) {
+ logerr("ps_sendcmdmsg");
+ if (ctx->options & DHCPCD_FORKED &&
+ !(ctx->options & DHCPCD_PRIVSEPROOT))
+ eloop_exit(ctx->eloop, EXIT_FAILURE);
+ }
return len;
}