Module Name: src
Committed By: roy
Date: Thu Jun 4 13:08:13 UTC 2020
Modified Files:
src/external/bsd/dhcpcd/dist/src: dhcp.c dhcp6.c dhcpcd.8.in dhcpcd.c
if-bsd.c privsep.c script.c
Log Message:
Sync
To generate a diff of this commit:
cvs rdiff -u -r1.37 -r1.38 src/external/bsd/dhcpcd/dist/src/dhcp.c \
src/external/bsd/dhcpcd/dist/src/dhcpcd.c
cvs rdiff -u -r1.19 -r1.20 src/external/bsd/dhcpcd/dist/src/dhcp6.c
cvs rdiff -u -r1.6 -r1.7 src/external/bsd/dhcpcd/dist/src/dhcpcd.8.in \
src/external/bsd/dhcpcd/dist/src/script.c
cvs rdiff -u -r1.20 -r1.21 src/external/bsd/dhcpcd/dist/src/if-bsd.c
cvs rdiff -u -r1.3 -r1.4 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.37 src/external/bsd/dhcpcd/dist/src/dhcp.c:1.38
--- src/external/bsd/dhcpcd/dist/src/dhcp.c:1.37 Sun May 31 12:52:11 2020
+++ src/external/bsd/dhcpcd/dist/src/dhcp.c Thu Jun 4 13:08:13 2020
@@ -1034,7 +1034,7 @@ make_message(struct bootp **bootpm, cons
auth = NULL; /* appease GCC */
auth_len = 0;
if (ifo->auth.options & DHCPCD_AUTH_SEND) {
- ssize_t alen = dhcp_auth_encode(&ifo->auth,
+ ssize_t alen = dhcp_auth_encode(ifp->ctx, &ifo->auth,
state->auth.token,
NULL, 0, 4, type, NULL, 0);
if (alen != -1 && alen > UINT8_MAX) {
@@ -1129,7 +1129,7 @@ make_message(struct bootp **bootpm, cons
#ifdef AUTH
if (ifo->auth.options & DHCPCD_AUTH_SEND && auth_len != 0)
- dhcp_auth_encode(&ifo->auth, state->auth.token,
+ dhcp_auth_encode(ifp->ctx, &ifo->auth, state->auth.token,
(uint8_t *)bootp, len, 4, type, auth, auth_len);
#endif
@@ -2747,6 +2747,18 @@ dhcp_drop(struct interface *ifp, const c
#endif
}
}
+#ifdef AUTH
+ else if (state->auth.reconf != NULL) {
+ /*
+ * Drop the lease as the token may only be present
+ * in the initial reply message and not subsequent
+ * renewals.
+ * If dhcpcd is restarted, the token is lost.
+ * XXX persist this in another file?
+ */
+ dhcp_unlink(ifp->ctx, state->leasefile);
+ }
+#endif
eloop_timeout_delete(ifp->ctx->eloop, NULL, ifp);
#ifdef AUTH
@@ -4176,3 +4188,24 @@ dhcp_handleifa(int cmd, struct ipv4_addr
return ia;
}
+
+#ifndef SMALL
+int
+dhcp_dump(struct interface *ifp)
+{
+ struct dhcp_state *state;
+
+ ifp->if_data[IF_DATA_DHCP] = state = calloc(1, sizeof(*state));
+ if (state == NULL) {
+ logerr(__func__);
+ return -1;
+ }
+ state->new_len = read_lease(ifp, &state->new);
+ if (state->new == NULL) {
+ logerr("read_lease");
+ return -1;
+ }
+ state->reason = "DUMP";
+ return script_runreason(ifp, state->reason);
+}
+#endif
Index: src/external/bsd/dhcpcd/dist/src/dhcpcd.c
diff -u src/external/bsd/dhcpcd/dist/src/dhcpcd.c:1.37 src/external/bsd/dhcpcd/dist/src/dhcpcd.c:1.38
--- src/external/bsd/dhcpcd/dist/src/dhcpcd.c:1.37 Sun May 31 12:52:11 2020
+++ src/external/bsd/dhcpcd/dist/src/dhcpcd.c Thu Jun 4 13:08:13 2020
@@ -29,6 +29,7 @@
const char dhcpcd_copyright[] = "Copyright (c) 2006-2020 Roy Marples";
#include <sys/file.h>
+#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/time.h>
@@ -86,6 +87,7 @@ const int dhcpcd_signals[] = {
SIGHUP,
SIGUSR1,
SIGUSR2,
+ SIGCHLD,
};
const size_t dhcpcd_signals_len = __arraycount(dhcpcd_signals);
@@ -1340,6 +1342,9 @@ stop_all_interfaces(struct dhcpcd_ctx *c
struct interface *ifp;
ctx->options |= DHCPCD_EXITING;
+ if (ctx->ifaces == NULL)
+ return;
+
/* Drop the last interface first */
TAILQ_FOREACH_REVERSE(ifp, ctx->ifaces, if_head, next) {
if (!ifp->active)
@@ -1395,7 +1400,7 @@ dhcpcd_signal_cb(int sig, void *arg)
unsigned long long opts;
int exit_code;
- if (ctx->options & DHCPCD_FORKED) {
+ if (sig != SIGCHLD && ctx->options & DHCPCD_FORKED) {
pid_t pid = pidfile_read(ctx->pidfile);
if (pid == -1) {
if (errno != ENOENT)
@@ -1441,6 +1446,10 @@ dhcpcd_signal_cb(int sig, void *arg)
if (logopen(ctx->logfile) == -1)
logerr(__func__);
return;
+ case SIGCHLD:
+ while (waitpid(-1, NULL, WNOHANG) > 0)
+ ;
+ return;
default:
logerrx("received signal %d but don't know what to do with it",
sig);
@@ -1663,20 +1672,13 @@ dumperr:
return 0;
}
-static const char *dumpskip[] = {
- "PATH=",
- "pid=",
- "chroot=",
-};
-
static int
dhcpcd_readdump(struct dhcpcd_ctx *ctx)
{
int error = 0;
- size_t nifaces, buflen = 0, dlen, i;
+ size_t nifaces, buflen = 0, dlen;
ssize_t len;
- char *buf = NULL, *dp, *de;
- const char *skip;
+ char *buf = NULL;
again1:
len = read(ctx->control_fd, &nifaces, sizeof(nifaces));
@@ -1723,26 +1725,7 @@ again3:
error = -1;
goto out;
}
- dp = buf;
- de = dp + dlen;
- if (*(de - 1) != '\0') {
- errno = EINVAL;
- error = -1;
- goto out;
- }
- while (dp < de) {
- for (i = 0; i < __arraycount(dumpskip); i++) {
- skip = dumpskip[i];
- if (strncmp(dp, skip, strlen(skip)) == 0)
- break;
- }
- if (i == __arraycount(dumpskip)) {
- if (strncmp(dp, "new_", 4) == 0)
- dp += 4;
- printf("%s\n", dp);
- }
- dp += strlen(dp) + 1;
- }
+ script_dump(buf, dlen);
fflush(stdout);
if (nifaces != 1)
putchar('\n');
@@ -2061,13 +2044,9 @@ printpidfile:
signal(dhcpcd_signals_ignore[si], SIG_IGN);
/* Save signal mask, block and redirect signals to our handler */
- if (eloop_signal_set_cb(ctx.eloop,
+ eloop_signal_set_cb(ctx.eloop,
dhcpcd_signals, dhcpcd_signals_len,
- dhcpcd_signal_cb, &ctx) == -1)
- {
- logerr("%s: eloop_signal_set_cb", __func__);
- goto exit_failure;
- }
+ dhcpcd_signal_cb, &ctx);
if (eloop_signal_mask(ctx.eloop, &ctx.sigset) == -1) {
logerr("%s: eloop_signal_mask", __func__);
goto exit_failure;
@@ -2107,6 +2086,45 @@ printpidfile:
}
#endif
+#ifndef SMALL
+ if (ctx.options & DHCPCD_DUMPLEASE &&
+ ioctl(fileno(stdin), FIONREAD, &i, sizeof(i)) == 0 &&
+ i > 0)
+ {
+ ifp = calloc(1, sizeof(*ifp));
+ if (ifp == NULL) {
+ logerr(__func__);
+ goto exit_failure;
+ }
+ ifp->ctx = &ctx;
+ ifp->options = ifo;
+ switch (family) {
+ case AF_INET:
+#ifdef INET
+ if (dhcp_dump(ifp) == -1)
+ goto exit_failure;
+ break;
+#else
+ logerrx("No DHCP support");
+ goto exit_failure;
+#endif
+ case AF_INET6:
+#ifdef DHCP6
+ if (dhcp6_dump(ifp) == -1)
+ goto exit_failure;
+ break;
+#else
+ logerrx("No DHCP6 support");
+ goto exit_failure;
+#endif
+ default:
+ logerrx("Family not specified. Please use -4 or -6.");
+ goto exit_failure;
+ }
+ goto exit_success;
+ }
+#endif
+
/* Test against siga instead of sig to avoid gcc
* warning about a bogus potential signed overflow.
* The end result will be the same. */
@@ -2194,7 +2212,6 @@ printpidfile:
logerr("fork");
goto exit_failure;
case 0:
- eloop_requeue(ctx.eloop);
break;
default:
ctx.options |= DHCPCD_FORKED; /* A lie */
@@ -2203,7 +2220,6 @@ printpidfile:
}
break;
default:
- waitpid(pid, &i, 0);
ctx.options |= DHCPCD_FORKED; /* A lie */
ctx.fork_fd = sigpipe[0];
close(sigpipe[1]);
Index: src/external/bsd/dhcpcd/dist/src/dhcp6.c
diff -u src/external/bsd/dhcpcd/dist/src/dhcp6.c:1.19 src/external/bsd/dhcpcd/dist/src/dhcp6.c:1.20
--- src/external/bsd/dhcpcd/dist/src/dhcp6.c:1.19 Sun May 31 12:52:11 2020
+++ src/external/bsd/dhcpcd/dist/src/dhcp6.c Thu Jun 4 13:08:13 2020
@@ -881,7 +881,7 @@ dhcp6_makemessage(struct interface *ifp)
#ifdef AUTH
auth_len = 0;
if (ifo->auth.options & DHCPCD_AUTH_SEND) {
- ssize_t alen = dhcp_auth_encode(&ifo->auth,
+ ssize_t alen = dhcp_auth_encode(ifp->ctx, &ifo->auth,
state->auth.token, NULL, 0, 6, type, NULL, 0);
if (alen != -1 && alen > UINT16_MAX) {
errno = ERANGE;
@@ -1196,9 +1196,9 @@ dhcp6_update_auth(struct interface *ifp,
return -1;
state = D6_STATE(ifp);
- return dhcp_auth_encode(&ifp->options->auth, state->auth.token,
- (uint8_t *)state->send, state->send_len,
- 6, state->send->type, opt, opt_len);
+ return dhcp_auth_encode(ifp->ctx, &ifp->options->auth,
+ state->auth.token, (uint8_t *)state->send, state->send_len, 6,
+ state->send->type, opt, opt_len);
}
#endif
@@ -1483,7 +1483,7 @@ void dhcp6_renew(struct interface *ifp)
dhcp6_startrenew(ifp);
}
-int
+bool
dhcp6_dadcompleted(const struct interface *ifp)
{
const struct dhcp6_state *state;
@@ -1493,9 +1493,9 @@ dhcp6_dadcompleted(const struct interfac
TAILQ_FOREACH(ap, &state->addrs, next) {
if (ap->flags & IPV6_AF_ADDED &&
!(ap->flags & IPV6_AF_DADCOMPLETED))
- return 0;
+ return false;
}
- return 1;
+ return true;
}
static void
@@ -3319,7 +3319,7 @@ dhcp6_recvif(struct interface *ifp, cons
loginfox("%s: accepted reconfigure key", ifp->name);
} else if (ifo->auth.options & DHCPCD_AUTH_SEND) {
if (ifo->auth.options & DHCPCD_AUTH_REQUIRE) {
- logerr("%s: no authentication from %s",
+ logerrx("%s: no authentication from %s",
ifp->name, sfrom);
return;
}
@@ -3595,15 +3595,12 @@ dhcp6_recvmsg(struct dhcpcd_ctx *ctx, st
}
if (r->type == DHCP6_RECONFIGURE) {
- logdebugx("%s: RECONFIGURE6 recv from %s,"
- " sending to all interfaces",
- ifp->name, sfrom);
- TAILQ_FOREACH(ifp, ctx->ifaces, next) {
- state = D6_CSTATE(ifp);
- if (state != NULL && state->send != NULL)
- dhcp6_recvif(ifp, sfrom, r, len);
+ if (!IN6_IS_ADDR_LINKLOCAL(&from->sin6_addr)) {
+ logerrx("%s: RECONFIGURE6 recv from %s, not LL",
+ ifp->name, sfrom);
+ return;
}
- return;
+ goto recvif;
}
state = D6_CSTATE(ifp);
@@ -3679,6 +3676,7 @@ dhcp6_recvmsg(struct dhcpcd_ctx *ctx, st
len = (size_t)tlen;
#endif
+recvif:
dhcp6_recvif(ifp, sfrom, r, len);
}
@@ -4041,6 +4039,19 @@ dhcp6_freedrop(struct interface *ifp, in
}
dhcp_unlink(ifp->ctx, state->leasefile);
}
+#ifdef AUTH
+ else if (state->auth.reconf != NULL) {
+ /*
+ * Drop the lease as the token may only be present
+ * in the initial reply message and not subsequent
+ * renewals.
+ * If dhcpcd is restarted, the token is lost.
+ * XXX persist this in another file?
+ */
+ dhcp_unlink(ifp->ctx, state->leasefile);
+ }
+#endif
+
dhcp6_freedrop_addrs(ifp, drop, NULL);
free(state->old);
state->old = state->new;
@@ -4293,3 +4304,24 @@ delegated:
return 1;
}
#endif
+
+#ifndef SMALL
+int
+dhcp6_dump(struct interface *ifp)
+{
+ struct dhcp6_state *state;
+
+ ifp->if_data[IF_DATA_DHCP6] = state = calloc(1, sizeof(*state));
+ if (state == NULL) {
+ logerr(__func__);
+ return -1;
+ }
+ TAILQ_INIT(&state->addrs);
+ if (dhcp6_readlease(ifp, 0) == -1) {
+ logerr("dhcp6_readlease");
+ return -1;
+ }
+ state->reason = "DUMP6";
+ return script_runreason(ifp, state->reason);
+}
+#endif
Index: src/external/bsd/dhcpcd/dist/src/dhcpcd.8.in
diff -u src/external/bsd/dhcpcd/dist/src/dhcpcd.8.in:1.6 src/external/bsd/dhcpcd/dist/src/dhcpcd.8.in:1.7
--- src/external/bsd/dhcpcd/dist/src/dhcpcd.8.in:1.6 Sun May 31 12:52:11 2020
+++ src/external/bsd/dhcpcd/dist/src/dhcpcd.8.in Thu Jun 4 13:08:13 2020
@@ -24,7 +24,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd May 21, 2020
+.Dd May 31, 2020
.Dt DHCPCD 8
.Os
.Sh NAME
@@ -72,7 +72,7 @@
.Op interface
.Nm
.Fl U , Fl Fl dumplease
-.Ar interface
+.Op Ar interface
.Nm
.Fl Fl version
.Nm
@@ -685,15 +685,20 @@ option is not sent in TEST mode so that
To test INFORM the interface needs to be configured with the desired address
before starting
.Nm .
-.It Fl U , Fl Fl dumplease Ar interface
+.It Fl U , Fl Fl dumplease Op Ar interface
Dumps the current lease for the
.Ar interface
to stdout.
+If no
+.Ar interface
+is given then all interfaces are dumped.
Use the
.Fl 4
or
.Fl 6
flags to specify an address family.
+If a lease is piped in via standard input then that is dumped.
+In this case, specifying an address family is mandatory.
.It Fl V , Fl Fl variables
Display a list of option codes, the associated variable and encoding for use in
.Xr dhcpcd-run-hooks 8 .
Index: src/external/bsd/dhcpcd/dist/src/script.c
diff -u src/external/bsd/dhcpcd/dist/src/script.c:1.6 src/external/bsd/dhcpcd/dist/src/script.c:1.7
--- src/external/bsd/dhcpcd/dist/src/script.c:1.6 Sun May 31 12:52:11 2020
+++ src/external/bsd/dhcpcd/dist/src/script.c Thu Jun 4 13:08:13 2020
@@ -1,4 +1,4 @@
-/* stSPDX-License-Identifier: BSD-2-Clause */
+/* SPDX-License-Identifier: BSD-2-Clause */
/*
* dhcpcd - DHCP client daemon
* Copyright (c) 2006-2020 Roy Marples <[email protected]>
@@ -193,6 +193,8 @@ script_buftoenv(struct dhcpcd_ctx *ctx,
}
}
assert(*(bufp - 1) == '\0');
+ if (nenv == 0)
+ return NULL;
if (ctx->script_envlen < nenv) {
env = reallocarray(ctx->script_env, nenv + 1, sizeof(*env));
@@ -235,6 +237,7 @@ make_env(struct dhcpcd_ctx *ctx, const s
#ifdef DHCP6
const struct dhcp6_state *d6_state;
#endif
+ bool is_stdin = ifp->name[0] == '\0';
#ifdef HAVE_OPEN_MEMSTREAM
if (ctx->script_fp == NULL) {
@@ -264,23 +267,19 @@ make_env(struct dhcpcd_ctx *ctx, const s
}
#endif
- /* Needed for scripts */
- path = getenv("PATH");
- if (efprintf(fp, "PATH=%s", path == NULL ? DEFAULT_PATH:path) == -1)
- goto eexit;
- if (efprintf(fp, "reason=%s", reason) == -1)
- goto eexit;
- if (efprintf(fp, "pid=%d", getpid()) == -1)
- goto eexit;
-
-#ifdef PRIVSEP
- if (ctx->options & DHCPCD_PRIVSEP && ctx->ps_user != NULL) {
- if (efprintf(fp, "chroot=%s", ctx->ps_user->pw_dir) == -1)
+ if (!(ifp->ctx->options & DHCPCD_DUMPLEASE)) {
+ /* Needed for scripts */
+ path = getenv("PATH");
+ if (efprintf(fp, "PATH=%s",
+ path == NULL ? DEFAULT_PATH : path) == -1)
+ goto eexit;
+ if (efprintf(fp, "pid=%d", getpid()) == -1)
+ goto eexit;
+ }
+ if (!is_stdin) {
+ if (efprintf(fp, "reason=%s", reason) == -1)
goto eexit;
}
- if (strcmp(reason, "CHROOT") == 0)
- goto make;
-#endif
ifo = ifp->options;
#ifdef INET
@@ -340,9 +339,10 @@ make_env(struct dhcpcd_ctx *ctx, const s
protocol = PROTO_DHCP;
#endif
-
- if (efprintf(fp, "interface=%s", ifp->name) == -1)
- goto eexit;
+ if (!is_stdin) {
+ if (efprintf(fp, "interface=%s", ifp->name) == -1)
+ goto eexit;
+ }
if (ifp->ctx->options & DHCPCD_DUMPLEASE)
goto dumplease;
if (efprintf(fp, "ifcarrier=%s",
@@ -508,9 +508,6 @@ dumplease:
goto eexit;
}
-#ifdef PRIVSEP
-make:
-#endif
/* Convert buffer to argv */
fflush(fp);
@@ -536,6 +533,9 @@ make:
fp = NULL;
#endif
+ if (is_stdin)
+ return buf_pos;
+
if (script_buftoenv(ctx, ctx->script_buf, (size_t)buf_pos) == NULL)
goto eexit;
@@ -686,23 +686,48 @@ script_run(struct dhcpcd_ctx *ctx, char
}
int
+script_dump(const char *env, size_t len)
+{
+ const char *ep = env + len;
+
+ if (len == 0)
+ return 0;
+
+ if (*(ep - 1) != '\0') {
+ errno = EINVAL;
+ return -1;
+ }
+
+ for (; env < ep; env += strlen(env) + 1) {
+ if (strncmp(env, "new_", 4) == 0)
+ env += 4;
+ printf("%s\n", env);
+ }
+ return 0;
+}
+
+int
script_runreason(const struct interface *ifp, const char *reason)
{
struct dhcpcd_ctx *ctx = ifp->ctx;
char *argv[2];
int status = 0;
struct fd_list *fd;
+ long buflen;
if (ctx->script == NULL &&
TAILQ_FIRST(&ifp->ctx->control_fds) == NULL)
return 0;
/* Make our env */
- if (make_env(ifp->ctx, ifp, reason) == -1) {
+ if ((buflen = make_env(ifp->ctx, ifp, reason)) == -1) {
logerr(__func__);
return -1;
}
+ if (strncmp(reason, "DUMP", 4) == 0)
+ return script_dump(ctx->script_buf, (size_t)buflen);
+
if (ctx->script == NULL)
goto send_listeners;
Index: src/external/bsd/dhcpcd/dist/src/if-bsd.c
diff -u src/external/bsd/dhcpcd/dist/src/if-bsd.c:1.20 src/external/bsd/dhcpcd/dist/src/if-bsd.c:1.21
--- src/external/bsd/dhcpcd/dist/src/if-bsd.c:1.20 Sun May 31 12:52:11 2020
+++ src/external/bsd/dhcpcd/dist/src/if-bsd.c Thu Jun 4 13:08:13 2020
@@ -100,10 +100,12 @@
#define RT_ADVANCE(x, n) (x += RT_ROUNDUP((n)->sa_len))
#endif
-/* Ignore these interface names which look like ethernet but are virtual. */
+/* Ignore these interface names which look like ethernet but are virtual or
+ * just won't work without explicit configuration. */
static const char * const ifnames_ignore[] = {
"bridge",
"fwe", /* Firewire */
+ "fwip", /* Firewire */
"tap",
"xvif", /* XEN DOM0 -> guest interface */
NULL
Index: src/external/bsd/dhcpcd/dist/src/privsep.c
diff -u src/external/bsd/dhcpcd/dist/src/privsep.c:1.3 src/external/bsd/dhcpcd/dist/src/privsep.c:1.4
--- src/external/bsd/dhcpcd/dist/src/privsep.c:1.3 Sun May 31 12:52:11 2020
+++ src/external/bsd/dhcpcd/dist/src/privsep.c Thu Jun 4 13:08:13 2020
@@ -131,6 +131,41 @@ ps_dropprivs(struct dhcpcd_ctx *ctx)
return 0;
}
+static int
+ps_setbuf0(int fd, int ctl, int minlen)
+{
+ int len;
+ socklen_t slen;
+
+ slen = sizeof(len);
+ if (getsockopt(fd, SOL_SOCKET, ctl, &len, &slen) == -1)
+ return -1;
+
+#ifdef __linux__
+ len /= 2;
+#endif
+ if (len >= minlen)
+ return 0;
+
+ return setsockopt(fd, SOL_SOCKET, ctl, &minlen, sizeof(minlen));
+}
+
+static int
+ps_setbuf(int fd)
+{
+ /* Ensure we can receive a fully sized privsep message.
+ * Double the send buffer. */
+ int minlen = (int)sizeof(struct ps_msg);
+
+ if (ps_setbuf0(fd, SO_RCVBUF, minlen) == -1 ||
+ ps_setbuf0(fd, SO_SNDBUF, minlen * 2) == -1)
+ {
+ logerr(__func__);
+ return -1;
+ }
+ return 0;
+}
+
pid_t
ps_dostart(struct dhcpcd_ctx *ctx,
pid_t *priv_pid, int *priv_fd,
@@ -160,11 +195,13 @@ ps_dostart(struct dhcpcd_ctx *ctx,
case 0:
*priv_fd = fd[1];
close(fd[0]);
+ ps_setbuf(*priv_fd);
break;
default:
*priv_pid = pid;
*priv_fd = fd[0];
close(fd[1]);
+ ps_setbuf(*priv_fd);
if (recv_unpriv_msg == NULL)
;
#ifdef HAVE_CAPSICUM
@@ -206,12 +243,8 @@ ps_dostart(struct dhcpcd_ctx *ctx,
ctx->ps_inet_fd = -1;
}
- if (eloop_signal_set_cb(ctx->eloop,
- dhcpcd_signals, dhcpcd_signals_len, signal_cb, ctx) == -1)
- {
- logerr("%s: eloop_signal_set_cb", __func__);
- goto errexit;
- }
+ eloop_signal_set_cb(ctx->eloop,
+ dhcpcd_signals, dhcpcd_signals_len, signal_cb, ctx);
/* ctx->sigset aready has the initial sigmask set in main() */
if (eloop_signal_mask(ctx->eloop, NULL) == -1) {
@@ -251,67 +284,35 @@ errexit:
(void)ps_sendcmd(ctx, *priv_fd, PS_STOP, 0, NULL, 0);
shutdown(*priv_fd, SHUT_RDWR);
*priv_fd = -1;
+ eloop_exit(ctx->eloop, EXIT_FAILURE);
return -1;
}
int
ps_dostop(struct dhcpcd_ctx *ctx, pid_t *pid, int *fd)
{
- int status;
+ int err = 0;
#ifdef PRIVSEP_DEBUG
logdebugx("%s: pid %d fd %d", __func__, *pid, *fd);
#endif
- if (*pid == 0)
- return 0;
- eloop_event_delete(ctx->eloop, *fd);
- if (ps_sendcmd(ctx, *fd, PS_STOP, 0, NULL, 0) == -1 &&
- errno != ECONNRESET)
- logerr(__func__);
- if (shutdown(*fd, SHUT_RDWR) == -1 && errno != ENOTCONN)
- logerr(__func__);
- close(*fd);
- *fd = -1;
- /* We won't have permission for all processes .... */
-#if 0
- if (kill(*pid, SIGTERM) == -1)
- logerr(__func__);
-#endif
- status = 0;
-
-#ifdef HAVE_CAPSICUM
- unsigned int cap_mode = 0;
- int cap_err = cap_getmode(&cap_mode);
- if (cap_err == -1) {
- if (errno != ENOSYS)
- logerr("%s: cap_getmode", __func__);
- } else if (cap_mode != 0)
- goto nowait;
-#endif
-
- /* Wait for the process to finish */
- while (waitpid(*pid, &status, 0) == -1) {
- if (errno != EINTR) {
- logerr("%s: waitpid", __func__);
- status = 0;
- break;
+ if (*fd != -1) {
+ eloop_event_delete(ctx->eloop, *fd);
+ if (ps_sendcmd(ctx, *fd, PS_STOP, 0, NULL, 0) == -1 ||
+ shutdown(*fd, SHUT_RDWR) == -1)
+ {
+ logerr(__func__);
+ err = -1;
}
-#ifdef PRIVSEP_DEBUG
- else
- logerr("%s: waitpid ", __func__);
-#endif
+ close(*fd);
+ *fd = -1;
}
-#ifdef HAVE_CAPSICUM
-nowait:
-#endif
- *pid = 0;
-
-#ifdef PRIVSEP_DEBUG
- logdebugx("%s: status %d", __func__, status);
-#endif
- return status;
+ /* Don't wait for the process as it may not respond to the shutdown
+ * request. We'll reap the process on receipt of SIGCHLD. */
+ *pid = 0;
+ return err;
}
int
@@ -507,7 +508,8 @@ ps_sendpsmmsg(struct dhcpcd_ctx *ctx, in
#ifdef PRIVSEP_DEBUG
logdebugx("%s: %zd", __func__, len);
#endif
- if ((len == -1 || len == 0) && ctx->options & DHCPCD_FORKED)
+ if ((len == -1 || len == 0) && ctx->options & DHCPCD_FORKED &&
+ !(ctx->options & DHCPCD_PRIVSEPROOT))
eloop_exit(ctx->eloop, len == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
return len;
}
@@ -650,8 +652,12 @@ ps_recvmsg(struct dhcpcd_ctx *ctx, int r
#ifdef PRIVSEP_DEBUG
logdebugx("%s: recv fd %d, %zd bytes", __func__, rfd, len);
#endif
- if ((len == -1 || len == 0) && ctx->options & DHCPCD_FORKED) {
- eloop_exit(ctx->eloop, len == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
+
+ if (len == -1 || len == 0) {
+ if (ctx->options & DHCPCD_FORKED &&
+ !(ctx->options & DHCPCD_PRIVSEPROOT))
+ eloop_exit(ctx->eloop,
+ len == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
return len;
}
@@ -660,7 +666,8 @@ ps_recvmsg(struct dhcpcd_ctx *ctx, int r
#ifdef PRIVSEP_DEBUG
logdebugx("%s: send fd %d, %zu bytes", __func__, wfd, len);
#endif
- if ((len == -1 || len == 0) && ctx->options & DHCPCD_FORKED)
+ if ((len == -1 || len == 0) && ctx->options & DHCPCD_FORKED &&
+ !(ctx->options & DHCPCD_PRIVSEPROOT))
eloop_exit(ctx->eloop, len == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
return len;
}
@@ -682,8 +689,6 @@ ps_recvpsmsg(struct dhcpcd_ctx *ctx, int
logdebugx("%s: %zd", __func__, len);
#endif
- if (len == -1 && (errno == ECONNRESET || errno == EBADF))
- len = 0;
if (len == -1 || len == 0)
stop = true;
else {