Mercurial > hg > dhcpcd
changeset 4953:109206a59cc6 draft
privsep: Delay control startup after starting privsep
This means we don't need to close it for other processes.
Add ps_init so that we can change directory permissions before
starting privsep itself.
| author | Roy Marples <roy@marples.name> |
|---|---|
| date | Thu, 09 Jan 2020 15:39:18 +0000 |
| parents | e77138b6ec3b |
| children | 52e1039652ea |
| files | src/control.c src/control.h src/dhcpcd.c src/privsep.c src/privsep.h |
| diffstat | 5 files changed, 71 insertions(+), 81 deletions(-) [+] |
line wrap: on
line diff
--- a/src/control.c Thu Jan 09 14:48:56 2020 +0000 +++ b/src/control.c Thu Jan 09 15:39:18 2020 +0000 @@ -269,25 +269,22 @@ int retval = 0; struct fd_list *l; - if (ctx->options & DHCPCD_FORKED) - goto freeit; - - if (ctx->control_fd == -1) - return 0; - - control_close(ctx); - if (unlink(ctx->control_sock) == -1) - retval = -1; + if (ctx->control_fd != -1) { + eloop_event_delete(ctx->eloop, ctx->control_fd); + close(ctx->control_fd); + ctx->control_fd = -1; + if (unlink(ctx->control_sock) == -1 && errno != ENOENT) + retval = -1; + } if (ctx->control_unpriv_fd != -1) { eloop_event_delete(ctx->eloop, ctx->control_unpriv_fd); close(ctx->control_unpriv_fd); ctx->control_unpriv_fd = -1; - if (unlink(UNPRIVSOCKET) == -1) + if (unlink(UNPRIVSOCKET) == -1 && errno != ENOENT) retval = -1; } -freeit: while ((l = TAILQ_FIRST(&ctx->control_fds))) { TAILQ_REMOVE(&ctx->control_fds, l, next); eloop_event_delete(ctx->eloop, l->fd); @@ -448,14 +445,3 @@ eloop_event_add_w(fd->ctx->eloop, fd->fd, control_writeone, fd); return 0; } - -void -control_close(struct dhcpcd_ctx *ctx) -{ - - if (ctx->control_fd != -1) { - eloop_event_delete(ctx->eloop, ctx->control_fd); - close(ctx->control_fd); - ctx->control_fd = -1; - } -}
--- a/src/control.h Thu Jan 09 14:48:56 2020 +0000 +++ b/src/control.h Thu Jan 09 15:39:18 2020 +0000 @@ -71,6 +71,5 @@ int control_open(const char *); ssize_t control_send(struct dhcpcd_ctx *, int, char * const *); int control_queue(struct fd_list *, void *, size_t, bool); -void control_close(struct dhcpcd_ctx *ctx); #endif
--- a/src/dhcpcd.c Thu Jan 09 14:48:56 2020 +0000 +++ b/src/dhcpcd.c Thu Jan 09 15:39:18 2020 +0000 @@ -1917,7 +1917,6 @@ if (ctx.control_fd != -1) { loginfox("sending commands to master dhcpcd process"); len = control_send(&ctx, argc, argv); - control_close(&ctx); if (len > 0) { logdebugx("send OK"); goto exit_success; @@ -1989,6 +1988,13 @@ logdebugx(PACKAGE "-" VERSION " starting"); +#ifdef PRIVSEP + if (ps_init(&ctx) == -1 && errno != 0) { + logerr("ps_init"); + goto exit_failure; + } +#endif + #ifdef USE_SIGNALS if (pipe(sigpipe) == -1) { logerr("pipe"); @@ -2038,6 +2044,21 @@ } #endif +#ifdef BSD + /* Disable the kernel RTADV sysctl as early as possible. */ + if (ctx.options & DHCPCD_IPV6 && ctx.options & DHCPCD_IPV6RS) + if_disable_rtadv(); +#endif + +#ifdef PRIVSEP + if (ctx.options & DHCPCD_PRIVSEP && ps_start(&ctx) == -1) { + logerr("ps_start"); + goto exit_failure; + } + if (ctx.options & DHCPCD_FORKED) + goto run_loop; +#endif + if (control_start(&ctx, ctx.options & DHCPCD_MASTER ? NULL : argv[optind]) == -1) { @@ -2050,21 +2071,6 @@ ctx.options & DHCPCD_IPV4 ? " [ip4]" : "", ctx.options & DHCPCD_IPV6 ? " [ip6]" : ""); -#ifdef BSD - /* Disable the kernel RTADV sysctl as early as possible. */ - if (ctx.options & DHCPCD_IPV6 && ctx.options & DHCPCD_IPV6RS) - if_disable_rtadv(); -#endif - -#ifdef PRIVSEP - if (ps_start(&ctx) == -1 && errno != 0) { - logerr("ps_start"); - goto exit_failure; - } - if (ctx.options & DHCPCD_FORKED) - goto run_loop; -#endif - if (if_opensockets(&ctx) == -1) { logerr("%s: if_opensockets", __func__); goto exit_failure;
--- a/src/privsep.c Thu Jan 09 14:48:56 2020 +0000 +++ b/src/privsep.c Thu Jan 09 15:39:18 2020 +0000 @@ -68,6 +68,35 @@ #include <util.h> #endif +int +ps_init(struct dhcpcd_ctx *ctx) +{ + struct passwd *pw; + gid_t gid = (gid_t)-1; + + errno = 0; + if ((pw = getpwnam(PRIVSEP_USER)) == NULL) { + ctx->options &= ~DHCPCD_PRIVSEP; + if (errno == 0) { + logerrx("no such user %s", PRIVSEP_USER); + /* Just incase logerrx caused an error... */ + errno = 0; + } else + logerr("getpwnam"); + return -1; + } + + + /* Change ownership of stuff we need to drop at exit. */ + if (chown(ctx->pidfile, pw->pw_uid, gid) == -1) + logerr("chown `%s'", ctx->pidfile); + if (chown(DBDIR, pw->pw_uid, gid) == -1) + logerr("chown `%s'", DBDIR); + if (chown(RUNDIR, pw->pw_uid, gid) == -1) + logerr("chown `%s'", RUNDIR); + return 0; +} + pid_t ps_dostart(struct dhcpcd_ctx *ctx, pid_t *priv_pid, int *priv_fd, @@ -80,51 +109,21 @@ int fd[2]; pid_t pid; - /* Even if we're not dropping privs, we need to ensure that the unpriv - * user exists so the processes that do need it startup just fine. */ - errno = 0; - if ((pw = getpwnam(PRIVSEP_USER)) == NULL) { - ctx->options &= ~DHCPCD_PRIVSEP; - if (errno == 0) { - if (ctx == recv_ctx) { /* Only log the once. */ + if (flags & PSF_DROPPRIVS) { + errno = 0; + if ((pw = getpwnam(PRIVSEP_USER)) == NULL) { + if (errno == 0) logerrx("no such user %s", PRIVSEP_USER); - /* Just incase logerrx caused an error... */ - errno = 0; - } - } else - logerr("getpwnam"); - return -1; - } - - if (!(flags & PSF_DROPPRIVS)) { + else + logerr("getpwnam"); + return -1; + } + } else pw = NULL; - goto create_sp; - } - if (priv_pid == NULL) { - gid_t gid = (gid_t)-1; + if (priv_fd == NULL) + goto dropprivs; - /* Main process - change ownership of stuff we need to - * drop at exit. */ - if (pw != NULL) { - if (chown(ctx->pidfile, pw->pw_uid, gid) == -1) - logerr("chown `%s'", ctx->pidfile); - if (chown(DBDIR, pw->pw_uid, gid) == -1) - logerr("chown `%s'", DBDIR); - if (chown(RUNDIR, pw->pw_uid, gid) == -1) - logerr("chown `%s'", RUNDIR); - if (ctx->options & DHCPCD_MASTER) { - if (chown(ctx->control_sock, - pw->pw_uid, gid) == -1) - logerr("chown `%s'", ctx->control_sock); - if (chown(UNPRIVSOCKET, pw->pw_uid, gid) == -1) - logerr("chown `%s'", UNPRIVSOCKET); - } - } - goto dropprivs; - } - -create_sp: stype = SOCK_CLOEXEC | SOCK_NONBLOCK; if (socketpair(AF_UNIX, SOCK_DGRAM | stype, 0, fd) == -1) { logerr("socketpair"); @@ -159,7 +158,6 @@ close(ctx->fork_fd); ctx->fork_fd = -1; } - control_close(ctx); pidfile_clean(); eloop_clear(ctx->eloop);
