From 7d6cb00c5812fdbc5e1ae785f90875e050cc5847 Mon Sep 17 00:00:00 2001 From: Roy Marples Date: Tue, 21 Apr 2026 14:17:07 +0100 Subject: [PATCH 1/3] priv: don't launch when not waiting for interfaces --- src/dhcp.c | 5 ++++- src/dhcpsd.8.in | 4 +++- src/dhcpsd.c | 25 ++++++++++++++++++------- 3 files changed, 25 insertions(+), 9 deletions(-) diff --git a/src/dhcp.c b/src/dhcp.c index 8591257..9fdeb42 100644 --- a/src/dhcp.c +++ b/src/dhcp.c @@ -368,7 +368,10 @@ dhcp_outputipudp(struct interface *ifp, const struct in_addr *src, in_cksum(&udp, sizeof(udp), &sum); udp.uh_sum = in_cksum(bootp, len, &sum); - nbytes = priv_sendbpf(ifp, iov, ARRAYCOUNT(iov)); + if (ctx->dhcp_ctx->ctx_options & DHCPSD_WAITIF) + nbytes = priv_sendbpf(ifp, iov, ARRAYCOUNT(iov)); + else + nbytes = writev(ifp->if_bpf->bpf_fd, iov, ARRAYCOUNT(iov)); if (nbytes == -1) logerr("%s: priv_sendbpf: %s", __func__, ifp->if_name); return nbytes; diff --git a/src/dhcpsd.8.in b/src/dhcpsd.8.in index 039b306..bba01fe 100644 --- a/src/dhcpsd.8.in +++ b/src/dhcpsd.8.in @@ -24,7 +24,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd April 16, 2026 +.Dd April 21, 2026 .Dt DHCPSD 8 .Os .Sh NAME @@ -87,6 +87,8 @@ to work with dynamically created interfaces that are in the ready state. If an interface is marked down or departs then .Nm will deactivate the interface. +This requires a privileged helper process to open a BPF socket for each +interface when required. .El .Sh NOTES .Nm diff --git a/src/dhcpsd.c b/src/dhcpsd.c index 82385d8..f0d97e2 100644 --- a/src/dhcpsd.c +++ b/src/dhcpsd.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include #include @@ -324,8 +325,14 @@ dhcpsd_configure_pools(struct interface *ifp) continue; /* XXX When we grow DHCPv6 only open BPF if we configure * a DHCPv4 pool. */ - if (priv_openbpf(ifp) == -1) - return -1; + if (ctx->ctx_options & DHCPSD_WAITIF) { + if (priv_openbpf(ifp) == -1) + return -1; + } else { + ifp->if_bpf = bpf_open(ifp, bpf_bootp, O_WRONLY); + if (ifp->if_bpf == NULL) + return -1; + } /* First plugin with config wins */ npools += n; break; @@ -429,12 +436,16 @@ main(int argc, char **argv) ctx.ctx_argc = argc; ctx.ctx_argv = argv; - if (priv_init(&ctx) == NULL) { - logerr("%s: priv_init", __func__); - goto exit; + /* Waiting for interfaces requires a privileged helper + * to open BPF sockets. */ + if (ctx.ctx_options & DHCPSD_WAITIF) { + if (priv_init(&ctx) == NULL) { + logerr("%s: priv_init", __func__); + goto exit; + } + if (ctx.ctx_options & DHCPSD_RUN) + goto open_pf_inet; } - if (ctx.ctx_options & DHCPSD_RUN) - goto open_pf_inet; if (unpriv_init(&ctx) == NULL) { logerr("%s: unpriv_init", __func__); From a60fda6a405f1dd4c8c93287424318135710b916 Mon Sep 17 00:00:00 2001 From: Roy Marples Date: Tue, 21 Apr 2026 15:13:29 +0100 Subject: [PATCH 2/3] Fix prior --- src/dhcp.c | 15 ++++++++++----- src/dhcpsd.c | 2 +- src/if.c | 11 +++++++---- 3 files changed, 18 insertions(+), 10 deletions(-) diff --git a/src/dhcp.c b/src/dhcp.c index 9fdeb42..8c441f8 100644 --- a/src/dhcp.c +++ b/src/dhcp.c @@ -368,12 +368,17 @@ dhcp_outputipudp(struct interface *ifp, const struct in_addr *src, in_cksum(&udp, sizeof(udp), &sum); udp.uh_sum = in_cksum(bootp, len, &sum); - if (ctx->dhcp_ctx->ctx_options & DHCPSD_WAITIF) + if (ctx->dhcp_ctx->ctx_options & DHCPSD_WAITIF) { nbytes = priv_sendbpf(ifp, iov, ARRAYCOUNT(iov)); - else - nbytes = writev(ifp->if_bpf->bpf_fd, iov, ARRAYCOUNT(iov)); - if (nbytes == -1) - logerr("%s: priv_sendbpf: %s", __func__, ifp->if_name); + if (nbytes == -1) + logerr("%s: priv_sendbpf: %s", __func__, ifp->if_name); + + } else { + nbytes = ifp->if_output(ifp, ifp->if_bpf->bpf_fd, iov, + ARRAYCOUNT(iov)); + if (nbytes == -1) + logerr("%s: if_output: %s", __func__, ifp->if_name); + } return nbytes; } diff --git a/src/dhcpsd.c b/src/dhcpsd.c index f0d97e2..f64d0df 100644 --- a/src/dhcpsd.c +++ b/src/dhcpsd.c @@ -34,9 +34,9 @@ #include #include +#include #include #include -#include #include #include #include diff --git a/src/if.c b/src/if.c index 1090ee4..33d5ae7 100644 --- a/src/if.c +++ b/src/if.c @@ -233,7 +233,8 @@ if_learnifaces(struct ctx *ctx) if_update(ifp, ifa->ifa_addr); if_update_output(ifp); if (if_update_mtu(ifp) == -1) { - logerr("%s: if_update_mtu: %s", __func__, ifa->ifa_name); + logerr("%s: if_update_mtu: %s", __func__, + ifa->ifa_name); free(ifp); continue; } @@ -384,10 +385,12 @@ if_free(struct interface *ifp) srv_if_free = options & DHCPSD_MAIN && !(options & DHCPSD_EXITING); if (srv_if_free) { - if (options & DHCPSD_WAITIF) + if (options & DHCPSD_WAITIF) { loginfox("%s: deactiving interface", ifp->if_name); - if (priv_freeif(ifp) == -1 && errno != ESRCH) - logerr("%s: priv_freeif: %s", __func__, ifp->if_name); + if (priv_freeif(ifp) == -1 && errno != ESRCH) + logerr("%s: priv_freeif: %s", __func__, + ifp->if_name); + } if (unpriv_freeif(ifp) == -1 && errno != ESRCH) logerr("%s: unpriv_freeif: %s", __func__, ifp->if_name); } From b47b7ed90d01248001cfddcfc6a9f9a76c1153b7 Mon Sep 17 00:00:00 2001 From: Roy Marples Date: Tue, 21 Apr 2026 17:08:04 +0100 Subject: [PATCH 3/3] guard if_bpf --- src/dhcp.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/dhcp.c b/src/dhcp.c index 8c441f8..6ae485d 100644 --- a/src/dhcp.c +++ b/src/dhcp.c @@ -372,12 +372,15 @@ dhcp_outputipudp(struct interface *ifp, const struct in_addr *src, nbytes = priv_sendbpf(ifp, iov, ARRAYCOUNT(iov)); if (nbytes == -1) logerr("%s: priv_sendbpf: %s", __func__, ifp->if_name); - - } else { + } else if (ifp->if_bpf != NULL) { nbytes = ifp->if_output(ifp, ifp->if_bpf->bpf_fd, iov, ARRAYCOUNT(iov)); if (nbytes == -1) logerr("%s: if_output: %s", __func__, ifp->if_name); + } else { + errno = ENXIO; + logerr("%s: %s", __func__, ifp->if_name); + nbytes = -1; } return nbytes; }