# HG changeset patch # User Roy Marples # Date 1604074304 0 # Node ID 274d31419935bd51f73167fa6c7d5d4179b47244 # Parent 071a9ea183636cdfa05efd5c6f98839694f8b8e5 privsep: don't leave a BOOTP process hanging around on SIGUSR1 When not in master mode. diff -r 071a9ea18363 -r 274d31419935 src/dhcp.c --- a/src/dhcp.c Fri Oct 30 15:16:02 2020 +0000 +++ b/src/dhcp.c Fri Oct 30 16:11:44 2020 +0000 @@ -1520,21 +1520,15 @@ #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 @@ 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; } @@ -1757,6 +1778,9 @@ else to.s_addr = INADDR_BROADCAST; + logdebugx("from %s", inet_ntoa(from)); + logdebugx("to %s", inet_ntoa(to)); + /* * If not listening on the unspecified address we can * only receive broadcast messages via BPF. @@ -2321,23 +2345,24 @@ 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)