diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index a9b4ddb..57ed6e3 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -13,11 +13,11 @@ jobs: ubuntu: strategy: matrix: - os: [ ubuntu-latest, ubuntu-22.04 ] + os: [ ubuntu-latest ] runs-on: ${{ matrix.os }} steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v6 - name: Install Lua run: | @@ -30,7 +30,29 @@ jobs: - name: Build run: make + macos: + strategy: + matrix: + os: [ macos-15, macos-26 ] + runs-on: ${{ matrix.os }} + + steps: + - uses: actions/checkout@v6 + + - name: Install Lua + run: | + brew install lua + + - name: Configure + run: ./configure + + - name: Build + run: make + +# The BSDs are currently broken on github + openbsd: + if: false runs-on: ubuntu-latest steps: - name: Bootstrap OpenBSD-latest @@ -50,6 +72,7 @@ jobs: make freebsd: + if: false runs-on: ubuntu-latest steps: - name: Bootstrap FreeBSD-latest @@ -69,6 +92,7 @@ jobs: make netbsd: + if: false runs-on: ubuntu-latest steps: - name: Bootstrap NetBSD-latest diff --git a/.gitignore b/.gitignore index 00e80ba..31198e4 100644 --- a/.gitignore +++ b/.gitignore @@ -3,8 +3,9 @@ config.mk config.h config.log +*.dSYM/** *.o -*.So +*.soo *.so *.tar.xz diff --git a/compat/reallocarray.c b/compat/reallocarray.c new file mode 100644 index 0000000..0374515 --- /dev/null +++ b/compat/reallocarray.c @@ -0,0 +1,62 @@ +/* $NetBSD: reallocarr.c,v 1.4 2015/08/20 20:08:04 joerg Exp $ */ + +/*- + * Copyright (c) 2015 Joerg Sonnenberger . + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include + +/* + * To be clear, this is NetBSD's more refined reallocarr(3) function + * made to look like OpenBSD's more useable reallocarray(3) interface. + */ +#include "reallocarray.h" + +#define SQRT_SIZE_MAX (((size_t)1) << (sizeof(size_t) * CHAR_BIT / 2)) +void * +reallocarray(void *ptr, size_t n, size_t size) +{ + if (n == 0 || size == 0) + return realloc(ptr, 0); + + /* + * Try to avoid division here. + * + * It isn't possible to overflow during multiplication if neither + * operand uses any of the most significant half of the bits. + */ + if ((n | size) >= SQRT_SIZE_MAX && n > SIZE_MAX / size) { + errno = ENOMEM; + return NULL; + } + return realloc(ptr, n * size); +} diff --git a/compat/reallocarray.h b/compat/reallocarray.h new file mode 100644 index 0000000..3bc34a3 --- /dev/null +++ b/compat/reallocarray.h @@ -0,0 +1,39 @@ +/* $NetBSD: reallocarr.c,v 1.4 2015/08/20 20:08:04 joerg Exp $ */ + +/*- + * Copyright (c) 2015 Joerg Sonnenberger . + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef REALLOCARRAY_H +#define REALLOCARRAY_H + +#include + +void *reallocarray(void *, size_t, size_t); + +#endif diff --git a/config-null.mk b/config-null.mk index c7a8de3..6bf701d 100644 --- a/config-null.mk +++ b/config-null.mk @@ -1,3 +1 @@ # This space left intentionally blank - -DHCPCD_SRCS+= dhcpcd-embedded.c diff --git a/configure b/configure index 9f1e879..a1a3216 100755 --- a/configure +++ b/configure @@ -327,13 +327,16 @@ EOF else echo "no" fi - rm -rf _test.c _test + rm -rf _test.* _test fi else echo "CPPFLAGS+= -DNDEBUG" >>$CONFIG_MK fi case "$OS" in +darwin*) + echo "LDFLAGS_SO+= -Wl,-undefined,dynamic_lookup" >>$CONFIG_MK + ;; freebsd*|kfreebsd*) # FreeBSD hide some newer POSIX APIs behind _GNU_SOURCE ... echo "CPPFLAGS+= -D_GNU_SOURCE" >>$CONFIG_MK @@ -381,7 +384,7 @@ _CC=false if $XCC _test.c -o _test >/dev/null 2>&3; then [ -x _test ] && _CC=true fi -rm -f _test.c _test +rm -rf _test.* _test if ! $_CC; then echo $XCC echo "$CC does not create executables" >&2 @@ -394,8 +397,7 @@ $CC --version | $SED -e '1!d' if [ -z "$DHCPSD_USER" ]; then printf "Detecting a suitable user for dhcpsd ... " for x in _dhcpsd dhcpsd _dhcpd dhcpd; do - home=$(getent passwd $x 2>/dev/null | cut -d: -f6) - if [ -d "$home" ]; then + if id "$x" >/dev/null 2>&1; then DHCPSD_USER="$x" echo "$DHCPSD_USER" break @@ -430,7 +432,7 @@ if $XCC _capsicum.c -o _capsicum -lcasper -lcap_net 2>&3; then else echo "no" fi - rm -f _capsicum.c _capsicum + rm -rf _capsicum.* _capsicum fi if [ -z "$SANDBOX" ]; then @@ -448,7 +450,7 @@ EOF else echo "no" fi - rm -f _pledge.c _pledge + rm -rf _pledge.* _pledge fi abort=false @@ -474,7 +476,7 @@ else echo "libc support for getifaddrs is required - aborting" >&2 abort=true fi -rm -f _getifaddrs.c _getifaddrs +rm -rf _getifaddrs.* _getifaddrs $abort && exit 1 printf "Testing for clock_gettime ... " @@ -495,7 +497,7 @@ else echo "libc support for clock_getttime is required - aborting" >&2 abort=true fi -rm -f _clock_gettime.c _clock_gettime +rm -rf _clock_gettime.* _clock_gettime $abort && exit 1 if [ -z "$ARC4RANDOM" ]; then @@ -512,7 +514,7 @@ EOF ARC4RANDOM=no fi echo "$ARC4RANDOM" - rm -f _arc4random.c _arc4random + rm -rf _arc4random.* _arc4random fi if [ "$ARC4RANDOM" = no ]; then echo "COMPAT_SRCS+= compat/arc4random.c" >>$CONFIG_MK @@ -536,7 +538,7 @@ EOF fi echo "$CLOSEFROM" fi -rm -f _closefrom.c _closefrom +rm -rf _closefrom.* _closefrom if [ "$CLOSEFROM" = no ]; then echo "COMPAT_SRCS+= compat/closefrom.c" >>$CONFIG_MK echo "#include \"compat/closefrom.h\"" >>$CONFIG_H @@ -561,7 +563,7 @@ echo "$IOCTL_REQ" if [ "$IOCTL_REQ" != "unsigned long" ]; then echo "#define IOCTL_REQUEST_TYPE $IOCTL_REQ" >>$CONFIG_H fi -rm -f _ioctl.c _ioctl +rm -rf _ioctl.* _ioctl printf "Testing for inet_ntoa ... " cat <_inet_ntoa.c @@ -586,9 +588,31 @@ else echo "libc support for inet_ntoa is required - aborting" >&2 abort=true fi -rm -f _inet_ntoa.c _inet_ntoa +rm -rf _inet_ntoa.* _inet_ntoa $abort && exit 1 +if [ -z "$SETPROCTITLE" ]; then + printf "Testing for setproctitle ... " + cat << EOF >_setproctitle.c +#include +#include +int main(void) { + setproctitle("foo"); + return 0; +} +EOF + if $XCC _setproctitle.c -o _setproctitle 2>&3; then + SETPROCTITLE=yes + else + SETPROCTITLE=no + fi + echo "$SETPROCTITLE" + rm -rf _setproctitle.* _setproctitle +fi +if [ "$SETPROCTITLE" != no ]; then + echo "#define HAVE_SETPROCTITLE" >>$CONFIG_H +fi + if [ -z "$STRLCPY" ]; then printf "Testing for strlcpy ... " cat <_strlcpy.c @@ -605,7 +629,7 @@ EOF STRLCPY=no fi echo "$STRLCPY" - rm -f _strlcpy.c _strlcpy + rm -rf _strlcpy.* _strlcpy fi if [ "$STRLCPY" = no ]; then echo "COMPAT_SRCS+= compat/strlcpy.c" >>$CONFIG_MK @@ -629,7 +653,7 @@ EOF RBTREE=no fi echo "$RBTREE" - rm -f _rbtree.c _rbtree + rm -rf _rbtree.* _rbtree fi if [ "$RBTREE" = no ]; then echo "VENDOR_SRCS+= vendor/rbtree.c" >>$CONFIG_MK @@ -659,7 +683,7 @@ EOF REALLOCARRAY=no fi echo "$REALLOCARRAY" - rm -f _reallocarray.c _reallocarray + rm -rf _reallocarray.* _reallocarray fi if [ "$REALLOCARRAY" = no ]; then echo "COMPAT_SRCS+= compat/reallocarray.c" >>$CONFIG_MK diff --git a/src/common.c b/src/common.c index 3848d58..b60f0a9 100644 --- a/src/common.c +++ b/src/common.c @@ -461,12 +461,44 @@ sa_pton(struct sockaddr *sa, const char *src) return inet_pton(sa->sa_family, src, addr); } +#if !defined(HAVE_SOCK_CLOEXEC) || !defined(HAVE_SOCK_NONBLOCK) +static int +xsetfd(int fd, int flags) +{ + int oflags; + +#ifndef HAVE_SOCK_CLOEXEC + if (flags & SOCK_CLOEXEC) { + oflags = fcntl(fd, F_GETFD); + if (oflags == -1) + return -1; + if (!(oflags & FD_CLOEXEC) && + fcntl(fd, F_SETFD, oflags | FD_CLOEXEC) == -1) + return -1; + } +#endif + +#ifndef HAVE_SOCK_NONBLOCK + if (flags & SOCK_NONBLOCK) { + oflags = fcntl(fd, F_GETFL); + if (oflags == -1) + return -1; + if (!(oflags & O_NONBLOCK) && + fcntl(fd, F_SETFL, oflags | O_NONBLOCK) == -1) + return -1; + } +#endif + + return 0; +} +#endif + int xsocket(int domain, int type, int protocol) { int s; #if !defined(HAVE_SOCK_CLOEXEC) || !defined(HAVE_SOCK_NONBLOCK) - int xflags, xtype = type; + int xtype = type; #endif #ifndef HAVE_SOCK_CLOEXEC @@ -481,24 +513,44 @@ xsocket(int domain, int type, int protocol) if ((s = socket(domain, type, protocol)) == -1) return -1; +#if !defined(HAVE_SOCK_CLOEXEC) || !defined(HAVE_SOCK_NONBLOCK) + if (xtype != type && xsetfd(s, xtype) == -1) { + close(s); + return -1; + } +#endif + + return s; +} + +int +xsocketpair(int domain, int type, int protocol, int fdset[2]) +{ + int s; +#if !defined(HAVE_SOCK_CLOEXEC) || !defined(HAVE_SOCK_NONBLOCK) + int xtype = type; +#endif + #ifndef HAVE_SOCK_CLOEXEC - if ((xtype & SOCK_CLOEXEC) && - ((xflags = fcntl(s, F_GETFD)) == -1 || - fcntl(s, F_SETFD, xflags | FD_CLOEXEC) == -1)) - goto out; + if (xtype & SOCK_CLOEXEC) + type &= ~SOCK_CLOEXEC; #endif #ifndef HAVE_SOCK_NONBLOCK - if ((xtype & SOCK_NONBLOCK) && - ((xflags = fcntl(s, F_GETFL)) == -1 || - fcntl(s, F_SETFL, xflags | O_NONBLOCK) == -1)) - goto out; + if (xtype & SOCK_NONBLOCK) + type &= ~SOCK_NONBLOCK; #endif - return s; + if ((s = socketpair(domain, type, protocol, fdset)) == -1) + return -1; #if !defined(HAVE_SOCK_CLOEXEC) || !defined(HAVE_SOCK_NONBLOCK) -out: - close(s); - return -1; + if (xtype != type && + (xsetfd(fdset[0], xtype) == -1 || xsetfd(fdset[1], xtype) == -1)) { + close(fdset[0]); + close(fdset[1]); + return -1; + } #endif + + return s; } diff --git a/src/common.h b/src/common.h index 7514fd6..f500dc0 100644 --- a/src/common.h +++ b/src/common.h @@ -134,4 +134,5 @@ hash_fnv1a(const void *key, size_t len) #define SOCK_CXNB SOCK_CLOEXEC | SOCK_NONBLOCK #endif int xsocket(int, int, int); +int xsocketpair(int, int, int, int[2]); #endif diff --git a/src/dhcpsd.c b/src/dhcpsd.c index e5b425f..8b6c999 100644 --- a/src/dhcpsd.c +++ b/src/dhcpsd.c @@ -129,7 +129,14 @@ dhcpsd_dropperms(int do_chroot) UNUSED(do_chroot); #endif - if (initgroups(DHCPSD_USER, pw->pw_gid) == -1 || +/* Avoid a compile warnings on Darwin. */ +#ifdef __APPLE__ +#define INITGROUPS_GID(gid) (int)(gid) +#else +#define INITGROUPS_GID(gid) (gid) +#endif + + if (initgroups(DHCPSD_USER, INITGROUPS_GID(pw->pw_gid)) == -1 || setgid(pw->pw_gid) == -1 || setuid(pw->pw_uid) == -1) { logerr("%s: error dropping privileges", __func__); return -1; @@ -197,8 +204,8 @@ dhcpsd_fork(struct ctx *ctx) cap_rights_t rights; #endif - if (socketpair(AF_UNIX, SOCK_SEQPACKET | SOCK_CLOEXEC | SOCK_NONBLOCK, - 0, fork_fd) == -1) { + if (xsocketpair(PF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC, 0, fork_fd) == + -1) { logerr("socketpair"); return -1; } @@ -250,7 +257,7 @@ dhcpsd_fork(struct ctx *ctx) } break; default: -#ifdef BSD +#ifdef HAVE_SETPROCTITLE setproctitle("[launcher]"); #endif ctx->ctx_options &= ~DHCPSD_MAIN; @@ -280,9 +287,8 @@ dhcpsd_send_launcher(struct ctx *ctx, int exit_code) { if (ctx->ctx_fork_fd == -1) return; - if (send(ctx->ctx_fork_fd, &exit_code, sizeof(exit_code), MSG_EOR) == - -1) - logerr("%s: sendmsg", __func__); + if (send(ctx->ctx_fork_fd, &exit_code, sizeof(exit_code), 0) == -1) + logerr("%s: send", __func__); close(ctx->ctx_fork_fd); ctx->ctx_fork_fd = -1; } @@ -489,7 +495,7 @@ main(int argc, char **argv) if (dhcpsd_dropperms(1) == -1) goto exit; -#ifdef BSD +#ifdef HAVE_SETPROCTITLE setproctitle("DHCP Server Daemon"); #endif @@ -606,7 +612,7 @@ main(int argc, char **argv) dhcp_free(ctx.ctx_dhcp); eloop_free(ctx.ctx_eloop); ctx.ctx_eloop = NULL; - svc_free(ctx.ctx_unpriv); + srv_free(ctx.ctx_unpriv); #ifdef HAVE_CASPER if (ctx.ctx_capnet) cap_close(ctx.ctx_capnet); diff --git a/src/dhcpsd.h b/src/dhcpsd.h index a622b9f..acea3ef 100644 --- a/src/dhcpsd.h +++ b/src/dhcpsd.h @@ -35,7 +35,7 @@ struct ifaddrs; struct dhcp_ctx; struct eloop; struct if_head; -struct svc_ctx; +struct srv_ctx; struct plugin; #ifdef HAVE_CASPER typedef struct cap_channel cap_channel_t; @@ -47,7 +47,7 @@ struct ctx { struct eloop *ctx_eloop; struct if_head *ctx_ifaces; - struct svc_ctx *ctx_unpriv; + struct srv_ctx *ctx_unpriv; struct plugin *ctx_plugins; size_t ctx_nplugins; diff --git a/src/eloop.c b/src/eloop.c index 52dd206..9956461 100644 --- a/src/eloop.c +++ b/src/eloop.c @@ -36,7 +36,7 @@ * On Linux use epoll(7) * Everywhere else use ppoll(2) */ -#ifdef BSD +#if defined(BSD) || defined(__APPLE__) #include #define USE_KQUEUE #if defined(__NetBSD__) @@ -625,6 +625,12 @@ eloop_open(struct eloop *eloop) fd = kqueue1(O_CLOEXEC); #elif defined(KQUEUE_CLOEXEC) fd = kqueuex(KQUEUE_CLOEXEC); +#elif defined(USE_KQUEUE) && defined(__APPLE__) + /* macOS does not allow setting CLOEXEC on kqueue. + * This should not be a problem because eloop consumers + * fork and exec rather than just exec and kqueue is + * automatically closed on fork. */ + fd = kqueue(); #elif defined(USE_KQUEUE) int flags; @@ -694,7 +700,11 @@ eloop_forked(struct eloop *eloop, unsigned short flags) unsigned short events; int err; - /* The fd is invalid after a fork, no need to close it. */ +/* kqueue invalidates the fd on fork. + * epoll shares state across fork, so we close the old and create a new one. */ +#ifdef USE_EPOLL + close(eloop->fd); +#endif eloop->fd = -1; if (flags && eloop_open(eloop) == -1) return -1; @@ -871,7 +881,7 @@ eloop_waitfd(int fd) struct pollfd pfd = { .fd = fd, .events = POLLIN }; int err; - err = ppoll(&pfd, 1, NULL, NULL); + err = poll(&pfd, 1, -1); if (err == -1 || err == 0) return err; @@ -1092,4 +1102,4 @@ eloop_start(struct eloop *eloop) } return eloop->exitcode; -} +} \ No newline at end of file diff --git a/src/if.c b/src/if.c index 6c82950..ed16ecb 100644 --- a/src/if.c +++ b/src/if.c @@ -64,12 +64,12 @@ if_learnifaces(struct ctx *ctx) struct ifaddrs *ifa; struct interface *ifp; #ifdef AF_LINK - const struct sockaddr_dl *sdl; + struct sockaddr_dl *sdl; #ifdef IFLR_ACTIVE struct if_laddrreq iflr = { .flags = IFLR_PREFIX }; #endif #elif defined(AF_PACKET) - const struct sockaddr_ll *sll; + struct sockaddr_ll *sll; #endif for (ifa = ctx->ctx_ifa; ifa; ifa = ifa->ifa_next) { @@ -84,7 +84,7 @@ if_learnifaces(struct ctx *ctx) #endif #ifdef IFLR_ACTIVE - sdl = (const void *)ifa->ifa_addr; + sdl = (void *)ifa->ifa_addr; /* We need to check for active address */ strlcpy(iflr.iflr_name, ifa->ifa_name, sizeof(iflr.iflr_name)); @@ -107,7 +107,7 @@ if_learnifaces(struct ctx *ctx) #ifdef AF_LINK #ifndef IFLR_ACTIVE - sdl = (const void *)ifa->ifa_addr; + sdl = (void *)ifa->ifa_addr; #endif switch (sdl->sdl_type) { @@ -150,22 +150,16 @@ if_learnifaces(struct ctx *ctx) } ifp->if_index = sdl->sdl_index; ifp->if_hwlen = sdl->sdl_alen; - if (ifp->if_hwlen != 0) { -#ifdef CLLADDR - memcpy(ifp->if_hwaddr, CLLADDR(sdl), ifp->if_hwlen); -#else + if (ifp->if_hwlen != 0) memcpy(ifp->if_hwaddr, LLADDR(sdl), ifp->if_hwlen); -#endif - } #elif defined(AF_PACKET) - sll = (const void *)ifa->ifa_addr; + sll = (void *)ifa->ifa_addr; ifp->if_index = (unsigned int)sll->sll_ifindex; ifp->if_hwtype = sll->sll_hatype; ifp->if_hwlen = sll->sll_halen; if (ifp->if_hwlen != 0) memcpy(ifp->if_hwaddr, sll->sll_addr, ifp->if_hwlen); #endif - switch (ifp->if_hwtype) { case ARPHRD_ETHER: ifp->if_output = if_ether_output; diff --git a/src/plugin.h b/src/plugin.h index 3966945..550a2ae 100644 --- a/src/plugin.h +++ b/src/plugin.h @@ -33,7 +33,7 @@ struct ctx; struct interface; -struct svc_ctx; +struct srv_ctx; struct bootp; struct dhcp_pool; struct dhcp_lease; @@ -66,7 +66,7 @@ struct plugin { const struct bootp *, size_t, unsigned int *); int (*p_expire_lease)(struct plugin *, const struct dhcp_lease *); int (*p_store_leases)(struct plugin *); - ssize_t (*p_dispatch)(struct plugin *, struct svc_ctx *, unsigned int, + ssize_t (*p_dispatch)(struct plugin *, struct srv_ctx *, unsigned int, const void *, size_t); int p_unpriv; }; diff --git a/src/plugins/Makefile b/src/plugins/Makefile index 0c0fe9b..2e8a0fb 100644 --- a/src/plugins/Makefile +++ b/src/plugins/Makefile @@ -1,5 +1,4 @@ TOP= ../../ -include ${TOP}/Makefile.inc include ${TOP}/iconfig.mk CFLAGS?= -O2 @@ -14,7 +13,6 @@ PLUGINS+= addrinfo ethers PLUGINS+= ${LUA_PLUGIN} SRCS= ${PLUGINS:=.c} OBJS= ${SRCS:.c=.o} -SOBJS= ${OBJS:.o=.So} PLUGS= ${PLUGINS:=.so} MAN8= dhcpsd_auto.8 dhcpsd_leasefile.8 @@ -22,16 +20,16 @@ MAN8+= dhcpsd_addrinfo.8 dhcpsd_ethers.8 MAN8+= dhcpsd_icmp.8 MAN8+= ${LUA_MAN8} -CLEANFILES+= ${OBJS} ${SOBJS} ${PLUGS} +CLEANFILES+= ${OBJS} ${PLUGS} CLEANFILES+= dhcpsd_leasefile.8 ${LUA_MAN8} -.SUFFIXES: .So .so .in +.SUFFIXES: .in .so -.c.So: +.c.o: ${CC} ${PICFLAG} -DPIC ${CFLAGS} ${CDBGFLAGS} ${CPPFLAGS} -c $< -o $@ -.So.so: - ${CC} ${LDFLAGS} -shared -Wl,-x -o $@ -Wl,-soname,$@ $< ${LIBS} +.o.so: + ${CC} ${LDFLAGS} ${LDFLAGS_SO} -shared -Wl,-x -o $@ $< ${LIBS} .in: ${SED} ${SED_CONFDIR} ${SED_DBDIR} ${SED_PLUGINDIR} $< > $@ @@ -39,14 +37,14 @@ CLEANFILES+= dhcpsd_leasefile.8 ${LUA_MAN8} all: ${PLUGS} ${MAN8} # verstable.h has a few compiler warnings so we hide it away -icmp.So: +icmp.o: icmp.c ${CC} ${PICFLAG} -DPIC ${CFLAGS} ${CPPFLAGS} ${VERSTABLE_CFLAGS} -c icmp.c -o $@ -lua.So: +lua.o: lua.c ${CC} ${PICFLAG} -DPIC ${CFLAGS} ${CDBGFLAGS} ${LUA_CFLAGS} ${CPPFLAGS} -c lua.c -o $@ -lua.so: lua.So - ${CC} ${LDFLAGS} -shared -Wl,-x -o $@ -Wl,-soname,$@ lua.So ${LUA_LIBS} +lua.so: lua.o + ${CC} ${LDFLAGS} ${LDFLAGS_SO} -shared -Wl,-x -o $@ lua.o ${LUA_LIBS} lint: _lint diff --git a/src/plugins/ethers.c b/src/plugins/ethers.c index 478f8c7..be6af3f 100644 --- a/src/plugins/ethers.c +++ b/src/plugins/ethers.c @@ -49,7 +49,6 @@ #include "common.h" #include "dhcp.h" #include "dhcpsd.h" -#include "logerr.h" #include "plugin.h" #include "service.h" @@ -60,7 +59,7 @@ static const char ethers_description[] = #define E_LOOKUPHOSTNAME 1U static ssize_t -ethers_run_lookup_hostname(struct plugin *p, struct svc_ctx *sctx, +ethers_run_lookup_hostname(struct plugin *p, struct srv_ctx *sctx, const void *data, size_t datalen) { struct ether_addr *ether_addr = (struct ether_addr *)UNCONST(data); @@ -82,11 +81,11 @@ ethers_run_lookup_hostname(struct plugin *p, struct svc_ctx *sctx, hnamelen = strlen(hname) + 1; out: - return svc_send(sctx, p, E_LOOKUPHOSTNAME, err, hname, hnamelen); + return srv_send(sctx, p, E_LOOKUPHOSTNAME, err, hname, hnamelen); } static ssize_t -ethers_dispatch(struct plugin *p, struct svc_ctx *sctx, unsigned int cmd, +ethers_dispatch(struct plugin *p, struct srv_ctx *sctx, unsigned int cmd, const void *data, size_t len) { switch (cmd) { @@ -113,7 +112,7 @@ ethers_lookup_hostname(struct plugin *p, char *hostname, } memcpy(&ea, bootp->chaddr, sizeof(ea)); - err = svc_run(p->p_ctx->ctx_unpriv, p, E_LOOKUPHOSTNAME, &ea, + err = srv_run(p->p_ctx->ctx_unpriv, p, E_LOOKUPHOSTNAME, &ea, sizeof(ea), &result, &hname, &hnamelen); if (err == -1 || result != 0) return -1; diff --git a/src/plugins/lua.c b/src/plugins/lua.c index 210d02c..caa4ddc 100644 --- a/src/plugins/lua.c +++ b/src/plugins/lua.c @@ -39,6 +39,7 @@ #include #include #include +#include #include #include #include @@ -84,7 +85,7 @@ static struct lua_ctx lua_ctx; #define L_EXPIRELEASE 6U static ssize_t -lua_run_configure_pools(struct plugin *p, struct svc_ctx *sctx, +lua_run_configure_pools(struct plugin *p, struct srv_ctx *sctx, const char *ifname, size_t ifnamelen) { struct lua_ctx *l = p->p_pctx; @@ -222,14 +223,14 @@ lua_run_configure_pools(struct plugin *p, struct svc_ctx *sctx, err = (ssize_t)npools; out: - err = svc_send(sctx, p, L_CONFIGUREPOOLS, err, pools, + err = srv_send(sctx, p, L_CONFIGUREPOOLS, err, pools, sizeof(*pool) * npools); free(pools); return err; } static ssize_t -lua_run_lookup_hostname(struct plugin *p, struct svc_ctx *sctx, +lua_run_lookup_hostname(struct plugin *p, struct srv_ctx *sctx, const void *data, size_t len) { ssize_t err = -1; @@ -270,27 +271,21 @@ lua_run_lookup_hostname(struct plugin *p, struct svc_ctx *sctx, err = 0; out: - return svc_send(sctx, p, L_LOOKUPADDR, err, hname, hnamelen); + return srv_send(sctx, p, L_LOOKUPHOSTNAME, err, hname, hnamelen); } static ssize_t -lua_run_lookup_addr(struct plugin *p, struct svc_ctx *sctx, const void *data, +lua_run_lookup_addr(struct plugin *p, struct srv_ctx *sctx, const void *data, size_t len) { ssize_t err = -1; struct lua_ctx *l = p->p_pctx; lua_State *L = l->L; const char *addr; + char *datap = UNCONST(data); + size_t hostname_len; char hostname[DHCP_HOSTNAME_LEN]; - memcpy(hostname, data, sizeof(hostname)); - /* Aligns bootp */ - memmove(UNCONST(data), (const char *)data + sizeof(hostname), - len - sizeof(hostname)); - len -= sizeof(hostname); - - l->l_req = data; - l->l_reqlen = len; - char chaddr[l->l_req->hlen * 3]; + char chaddr[sizeof(((struct bootp *)0)->chaddr) * 3]; struct sockaddr_in sin = { .sin_family = AF_INET, #ifdef BSD @@ -304,6 +299,35 @@ lua_run_lookup_addr(struct plugin *p, struct svc_ctx *sctx, const void *data, { .iov_base = &sin, .iov_len = sizeof(sin) }, }; + if (len < sizeof(hostname_len)) { + errno = EINVAL; + goto out; + } + memcpy(&hostname_len, datap, sizeof(hostname_len)); + datap += sizeof(hostname_len); + len -= sizeof(hostname_len); + + if (hostname_len != 0) { + if (len < hostname_len || hostname_len > sizeof(hostname)) { + errno = EINVAL; + goto out; + } + memcpy(hostname, datap, hostname_len); + datap += hostname_len; + len -= hostname_len; + } else + hostname[0] = '\0'; + + if (len < sizeof(*l->l_req)) { + errno = EINVAL; + goto out; + } + /* Aligns bootp */ + memmove(UNCONST(data), datap, len); + + l->l_req = data; + l->l_reqlen = len; + lua_pop(L, lua_gettop(L)); lua_getglobal(L, "lookup_addr"); @@ -347,7 +371,7 @@ lua_run_lookup_addr(struct plugin *p, struct svc_ctx *sctx, const void *data, err = 0; out: - return svc_sendv(sctx, p, L_LOOKUPADDR, err, iov, ARRAYCOUNT(iov)); + return srv_sendv(sctx, p, L_LOOKUPADDR, err, iov, ARRAYCOUNT(iov)); } static int @@ -526,7 +550,7 @@ lua_add_dhcp_uint16(lua_State *L) return 0; } - u16 = htons(data); + u16 = htons((uint16_t)data); DHCP_PUT_U16(&l->l_p, l->l_e, (uint8_t)optn, u16); return 0; } @@ -553,7 +577,7 @@ lua_add_dhcp_uint32(lua_State *L) return 0; } - u32 = htonl(data); + u32 = htonl((uint32_t)data); DHCP_PUT_U32(&l->l_p, l->l_e, (uint8_t)optn, u32); return 0; } @@ -613,7 +637,7 @@ lua_add_dhcp_domain(lua_State *L) } static ssize_t -lua_run_add_dhcp_options(struct plugin *p, struct svc_ctx *sctx, +lua_run_add_dhcp_options(struct plugin *p, struct srv_ctx *sctx, const void *dhcp, size_t dhcplen) { struct lua_ctx *l = p->p_pctx; @@ -655,13 +679,13 @@ lua_run_add_dhcp_options(struct plugin *p, struct svc_ctx *sctx, ldo->ldo_optslen = (size_t)(l->l_p - ldo->ldo_opts); out: - return svc_send(sctx, p, L_ADDDHCPOPTIONS, err, &l->l_dhcp, + return srv_send(sctx, p, L_ADDDHCPOPTIONS, err, &l->l_dhcp, offsetof(struct lua_dhcp_opts, ldo_optslen) + sizeof(l->l_dhcp.ldo_optslen) + l->l_dhcp.ldo_optslen); } static ssize_t -lua_run_expire_lease(struct plugin *p, struct svc_ctx *sctx, +lua_run_expire_lease(struct plugin *p, struct srv_ctx *sctx, const void *payload, size_t payloadlen) { const struct dhcp_lease *dl = payload; @@ -672,7 +696,7 @@ lua_run_expire_lease(struct plugin *p, struct svc_ctx *sctx, char ipbuf[INET_ADDRSTRLEN]; const char *ip, *flags; - if (payloadlen < sizeof(dl)) { + if (payloadlen < sizeof(*dl)) { errno = EINVAL; goto out; } @@ -712,11 +736,11 @@ lua_run_expire_lease(struct plugin *p, struct svc_ctx *sctx, err = (ssize_t)lua_tointeger(L, -1); out: - return svc_send(sctx, p, L_EXPIRELEASE, err, NULL, 0); + return srv_send(sctx, p, L_EXPIRELEASE, err, NULL, 0); } static ssize_t -lua_run_commit_lease(struct plugin *p, struct svc_ctx *sctx, +lua_run_commit_lease(struct plugin *p, struct srv_ctx *sctx, const void *payload, size_t payloadlen) { struct dhcp_lease dl; @@ -796,7 +820,7 @@ lua_run_commit_lease(struct plugin *p, struct svc_ctx *sctx, err = (ssize_t)lua_tointeger(L, -1); out: - return svc_send(sctx, p, L_COMMITLEASE, err, &f, sizeof(f)); + return srv_send(sctx, p, L_COMMITLEASE, err, &f, sizeof(f)); } static int @@ -880,7 +904,7 @@ lua_lookup_hostname(struct plugin *p, char *hostname, const struct bootp *bootp, void *hname; size_t hnamelen; - err = svc_run(p->p_ctx->ctx_unpriv, p, L_LOOKUPHOSTNAME, bootp, + err = srv_run(p->p_ctx->ctx_unpriv, p, L_LOOKUPHOSTNAME, bootp, bootplen, &result, &hname, &hnamelen); if (err == -1 || result == -1) @@ -901,9 +925,13 @@ static int lua_lookup_addr(struct plugin *p, struct sockaddr *sa, uint32_t *ltime, const char *hostname, const struct bootp *bootp, size_t bootplen) { - char hname[DHCP_HOSTNAME_LEN] = { '\0' }; + size_t hostname_len = hostname ? strlen(hostname) + 1 : 0; struct iovec iov[] = { - { .iov_base = hname, .iov_len = sizeof(hname) }, + { + .iov_base = &hostname_len, + .iov_len = sizeof(hostname_len), + }, + { .iov_base = UNCONST(hostname), .iov_len = hostname_len }, { .iov_base = UNCONST(bootp), .iov_len = bootplen }, }; ssize_t err, result; @@ -911,9 +939,7 @@ lua_lookup_addr(struct plugin *p, struct sockaddr *sa, uint32_t *ltime, uint8_t *dp; size_t len; - if (hostname != NULL) - strlcpy(hname, hostname, sizeof(hname)); - err = svc_runv(p->p_ctx->ctx_unpriv, p, L_LOOKUPADDR, iov, + err = srv_runv(p->p_ctx->ctx_unpriv, p, L_LOOKUPADDR, iov, ARRAYCOUNT(iov), &result, &data, &len); if (err == -1 || result == -1) @@ -937,7 +963,7 @@ lua_configure_pools(struct plugin *p, struct interface *ifp) size_t poolslen, npools; struct dhcp_pool *pool; - err = svc_run(p->p_ctx->ctx_unpriv, p, L_CONFIGUREPOOLS, ifp->if_name, + err = srv_run(p->p_ctx->ctx_unpriv, p, L_CONFIGUREPOOLS, ifp->if_name, strlen(ifp->if_name) + 1, &result, &_pools, &poolslen); if (err == -1 || result == -1) return -1; @@ -966,7 +992,7 @@ lua_add_dhcp_options(struct plugin *plug, struct bootp *bootp, uint8_t **p, size_t optslen; struct lua_dhcp_opts *ldo; - err = svc_run(plug->p_ctx->ctx_unpriv, plug, L_ADDDHCPOPTIONS, req, + err = srv_run(plug->p_ctx->ctx_unpriv, plug, L_ADDDHCPOPTIONS, req, reqlen, &result, &opts, &optslen); if (err == -1 || result == -1) return -1; @@ -1006,7 +1032,7 @@ lua_commit_lease(struct plugin *p, const struct dhcp_lease *lease, unsigned int *f = NULL; size_t flen; - err = svc_runv(p->p_ctx->ctx_unpriv, p, L_COMMITLEASE, iov, + err = srv_runv(p->p_ctx->ctx_unpriv, p, L_COMMITLEASE, iov, ARRAYCOUNT(iov), &result, (void *)&f, &flen); if (err == -1) return -1; @@ -1020,7 +1046,7 @@ lua_expire_lease(struct plugin *p, const struct dhcp_lease *lease) { ssize_t err, result; - err = svc_run(p->p_ctx->ctx_unpriv, p, L_EXPIRELEASE, lease, + err = srv_run(p->p_ctx->ctx_unpriv, p, L_EXPIRELEASE, lease, sizeof(*lease), &result, NULL, NULL); if (err == -1) return -1; @@ -1028,7 +1054,7 @@ lua_expire_lease(struct plugin *p, const struct dhcp_lease *lease) } static ssize_t -lua_dispatch(struct plugin *p, struct svc_ctx *sctx, unsigned int cmd, +lua_dispatch(struct plugin *p, struct srv_ctx *sctx, unsigned int cmd, const void *data, size_t len) { switch (cmd) { diff --git a/src/service.c b/src/service.c index 2e3f0f9..510ee67 100644 --- a/src/service.c +++ b/src/service.c @@ -43,7 +43,7 @@ #include "logerr.h" #include "service.h" -struct svc_cmd { +struct srv_cmd { uintptr_t sc_plugin; unsigned int sc_cmd; int sc_errno; @@ -51,86 +51,96 @@ struct svc_cmd { size_t sc_datalen; }; -static void -svc_recv(void *arg, unsigned short e) +static ssize_t +srv_recv(struct srv_ctx *sctx, unsigned short e) { - struct svc_ctx *sctx = arg; - struct svc_result *sr = &sctx->svc_result; - struct svc_cmd cmd; + struct srv_result *sr = &sctx->srv_result; + struct srv_cmd cmd; struct iovec iov[] = { { .iov_base = &cmd, .iov_len = sizeof(cmd), }, - { .iov_base = NULL, .iov_len = 0 }, }; struct msghdr msg = { .msg_iov = iov, .msg_iovlen = 1 }; ssize_t nread; if (e & ELE_HANGUP) { hangup: - eloop_exit(sctx->svc_ctx->ctx_eloop, EXIT_SUCCESS); - return; + eloop_exit(sctx->srv_ctx->ctx_eloop, EXIT_SUCCESS); + return -1; } if (e != ELE_READ) { logerrx("%s: unexpected operation %u", __func__, e); - return; + return -1; } - nread = recvmsg(sctx->svc_fd, &msg, MSG_WAITALL | MSG_PEEK); + nread = recvmsg(sctx->srv_fd, &msg, MSG_WAITALL); if (nread == 0) goto hangup; if (nread == -1) { logerr("%s: recvmsg cmd", __func__); - return; + return -1; } if (nread != sizeof(cmd)) { logerrx("%s: invalid read len: %zd", __func__, nread); - return; + return -1; } - if (sctx->svc_buflen < cmd.sc_datalen) { - void *nbuf = realloc(sctx->svc_buf, cmd.sc_datalen); - if (nbuf == NULL) { - logerr("%s: realloc", __func__); - return; + if (cmd.sc_datalen != 0) { + if (sctx->srv_buflen < cmd.sc_datalen) { + void *nbuf = realloc(sctx->srv_buf, cmd.sc_datalen); + if (nbuf == NULL) { + logerr("%s: realloc", __func__); + return -1; + } + sctx->srv_buf = nbuf; + sctx->srv_buflen = cmd.sc_datalen; + } + iov[0].iov_base = sctx->srv_buf; + iov[0].iov_len = cmd.sc_datalen; + + nread = recvmsg(sctx->srv_fd, &msg, MSG_WAITALL); + if (nread == -1) { + logerr("%s: recvmsg data", __func__); + return -1; + } + if ((size_t)nread != cmd.sc_datalen) { + logerrx("%s: read datalen mismatch: %zu != %zu", + __func__, (size_t)nread, cmd.sc_datalen); + return -1; } - sctx->svc_buf = nbuf; - sctx->svc_buflen = cmd.sc_datalen; } - iov[1].iov_base = sctx->svc_buf; - iov[1].iov_len = sctx->svc_buflen; - msg.msg_iovlen = 2; sr->sr_result = cmd.sc_result; sr->sr_errno = cmd.sc_errno; - - nread = recvmsg(sctx->svc_fd, &msg, 0); - if (nread == -1) { - logerr("%s: recvmsg cmd", __func__); - return; - } - if ((size_t)nread != sizeof(cmd) + cmd.sc_datalen) { - logerrx("%s: read datalen mismatch: %zd != %zd", __func__, - nread, sizeof(cmd) + cmd.sc_datalen); - return; - } - + sr->sr_data = cmd.sc_datalen != 0 ? sctx->srv_buf : NULL; sr->sr_datalen = cmd.sc_datalen; - sr->sr_data = sr->sr_datalen != 0 ? sctx->svc_buf : NULL; /* We are either a dispatcher for the helper, or a blocking loop for a * response */ - if (sctx->svc_dispatch != NULL) - sctx->svc_dispatch(sctx, (struct plugin *)cmd.sc_plugin, - cmd.sc_cmd, sctx->svc_buf, cmd.sc_datalen); + if (sctx->srv_dispatch != NULL) + sctx->srv_dispatch(sctx, (struct plugin *)cmd.sc_plugin, + cmd.sc_cmd, cmd.sc_datalen ? sctx->srv_buf : NULL, + cmd.sc_datalen); + + return (ssize_t)cmd.sc_datalen; +} + +static void +srv_recvl(void *arg, unsigned short e) +{ + struct srv_ctx *sctx = arg; + + if (srv_recv(sctx, e) == -1 && !(e & ELE_HANGUP)) + eloop_exit(sctx->srv_ctx->ctx_eloop, EXIT_FAILURE); } ssize_t -svc_sendv(struct svc_ctx *sctx, struct plugin *p, unsigned int cmd, +srv_sendv(struct srv_ctx *sctx, struct plugin *p, unsigned int cmd, ssize_t result, struct iovec *iov, int iovlen) { - struct svc_cmd sc = { + struct srv_cmd sc = { .sc_plugin = (uintptr_t)p, .sc_cmd = cmd, .sc_result = result, @@ -160,37 +170,38 @@ svc_sendv(struct svc_ctx *sctx, struct plugin *p, unsigned int cmd, sc.sc_datalen += iov[i].iov_len; } - ssize_t err = sendmsg(sctx->svc_fd, &msg, MSG_EOR); + ssize_t err = sendmsg(sctx->srv_fd, &msg, 0); return err; } ssize_t -svc_send(struct svc_ctx *sctx, struct plugin *p, unsigned int cmd, +srv_send(struct srv_ctx *sctx, struct plugin *p, unsigned int cmd, ssize_t result, const void *data, size_t len) { struct iovec iov[] = { { .iov_base = UNCONST(data), .iov_len = len }, }; - return svc_sendv(sctx, p, cmd, result, iov, len == 0 ? 0 : 1); + return srv_sendv(sctx, p, cmd, result, iov, len == 0 ? 0 : 1); } int -svc_runv(struct svc_ctx *sctx, struct plugin *p, unsigned int cmd, +srv_runv(struct srv_ctx *sctx, struct plugin *p, unsigned int cmd, struct iovec *iov, int iovlen, ssize_t *res, void **rdata, size_t *rlen) { - struct svc_result *result = &sctx->svc_result; + struct srv_result *result = &sctx->srv_result; int events; - if (svc_sendv(sctx, p, cmd, 0, iov, iovlen) == -1) { - logerr("%s: svc_write", __func__); + if (srv_sendv(sctx, p, cmd, 0, iov, iovlen) == -1) { + logerr("%s: srv_write", __func__); return -1; } - events = eloop_waitfd(sctx->svc_fd); + events = eloop_waitfd(sctx->srv_fd); if (events == -1) return -1; - svc_recv(sctx, (unsigned short)events); + if (srv_recv(sctx, (unsigned short)events) == -1) + return -1; if (result->sr_result == -1) errno = result->sr_errno; @@ -204,22 +215,22 @@ svc_runv(struct svc_ctx *sctx, struct plugin *p, unsigned int cmd, } int -svc_run(struct svc_ctx *sctx, struct plugin *p, unsigned int cmd, +srv_run(struct srv_ctx *sctx, struct plugin *p, unsigned int cmd, const void *data, size_t len, ssize_t *res, void **rdata, size_t *rlen) { struct iovec iov[] = { { .iov_base = UNCONST(data), .iov_len = len }, }; - return svc_runv(sctx, p, cmd, iov, len == 0 ? 0 : 1, res, rdata, rlen); + return srv_runv(sctx, p, cmd, iov, len == 0 ? 0 : 1, res, rdata, rlen); } -struct svc_ctx * -svc_init(struct ctx *ctx, const char *name, - ssize_t (*dispatch)(struct svc_ctx *, struct plugin *, unsigned int, +struct srv_ctx * +srv_init(struct ctx *ctx, const char *name, + ssize_t (*dispatch)(struct srv_ctx *, struct plugin *, unsigned int, const void *, size_t)) { - struct svc_ctx *sctx; + struct srv_ctx *sctx; int fdset[2], fd; pid_t pid; unsigned int logopts; @@ -230,19 +241,18 @@ svc_init(struct ctx *ctx, const char *name, return NULL; } - sctx->svc_ctx = ctx; - sctx->svc_fd = -1; - sctx->svc_dispatch = NULL; + sctx->srv_ctx = ctx; + sctx->srv_fd = -1; + sctx->srv_dispatch = NULL; - sctx->svc_buflen = 1024; - sctx->svc_buf = malloc(sctx->svc_buflen); - if (sctx->svc_buf == NULL) { + sctx->srv_buflen = 1024; + sctx->srv_buf = malloc(sctx->srv_buflen); + if (sctx->srv_buf == NULL) { logerr("%s: malloc", __func__); goto error; } - if (socketpair(AF_UNIX, SOCK_SEQPACKET | SOCK_CLOEXEC | SOCK_NONBLOCK, - 0, fdset) == -1) { + if (xsocketpair(PF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC, 0, fdset) == -1) { logerr("%s: socketpair", __func__); goto error; } @@ -251,15 +261,13 @@ svc_init(struct ctx *ctx, const char *name, switch (pid) { case -1: logerr("%s: fork", __func__); - close(fdset[0]); - close(fdset[1]); goto error; case 0: - sctx->svc_fd = fdset[1]; + sctx->srv_fd = fdset[1]; close(fdset[0]); break; default: - sctx->svc_fd = fdset[0]; + sctx->srv_fd = fdset[0]; close(fdset[1]); logdebugx("service: spawned %s on pid %ld", name, (long)pid); return sctx; @@ -267,14 +275,14 @@ svc_init(struct ctx *ctx, const char *name, ctx->ctx_options &= ~DHCPSD_MAIN; ctx->ctx_options |= DHCPSD_UNPRIV | DHCPSD_RUN; - sctx->svc_dispatch = dispatch; + sctx->srv_dispatch = dispatch; if (eloop_forked(ctx->ctx_eloop, ELF_KEEP_SIGNALS) == -1) { logerr("%s: eloop_forked", __func__); goto error; } - if (eloop_event_add(ctx->ctx_eloop, sctx->svc_fd, ELE_READ, svc_recv, + if (eloop_event_add(ctx->ctx_eloop, sctx->srv_fd, ELE_READ, srv_recvl, sctx) == -1) { logerr("%s: eloop_event_add", __func__); goto error; @@ -306,18 +314,18 @@ svc_init(struct ctx *ctx, const char *name, return sctx; error: - svc_free(sctx); + srv_free(sctx); return NULL; } void -svc_free(struct svc_ctx *ctx) +srv_free(struct srv_ctx *ctx) { if (ctx == NULL) return; - if (ctx->svc_fd != -1) - close(ctx->svc_fd); - free(ctx->svc_buf); + if (ctx->srv_fd != -1) + close(ctx->srv_fd); + free(ctx->srv_buf); free(ctx); } diff --git a/src/service.h b/src/service.h index 2236e67..4b93b28 100644 --- a/src/service.h +++ b/src/service.h @@ -36,35 +36,35 @@ struct plugin; -struct svc_result { +struct srv_result { ssize_t sr_result; int sr_errno; void *sr_data; size_t sr_datalen; }; -struct svc_ctx { - struct ctx *svc_ctx; - int svc_fd; - void *svc_buf; - size_t svc_buflen; - struct svc_result svc_result; - ssize_t (*svc_dispatch)(struct svc_ctx *, struct plugin *, unsigned int, +struct srv_ctx { + struct ctx *srv_ctx; + int srv_fd; + void *srv_buf; + size_t srv_buflen; + struct srv_result srv_result; + ssize_t (*srv_dispatch)(struct srv_ctx *, struct plugin *, unsigned int, const void *, size_t); }; -struct svc_ctx *svc_init(struct ctx *, const char *, - ssize_t (*dispatch)(struct svc_ctx *, struct plugin *, unsigned int, +struct srv_ctx *srv_init(struct ctx *, const char *, + ssize_t (*dispatch)(struct srv_ctx *, struct plugin *, unsigned int, const void *, size_t)); -void svc_free(struct svc_ctx *); -#define svc_dropperms dhcpsd_dropperms -ssize_t svc_send(struct svc_ctx *, struct plugin *, unsigned int, ssize_t, +void srv_free(struct srv_ctx *); +#define srv_dropperms dhcpsd_dropperms +ssize_t srv_send(struct srv_ctx *, struct plugin *, unsigned int, ssize_t, const void *, size_t); -ssize_t svc_sendv(struct svc_ctx *, struct plugin *, unsigned int, ssize_t, +ssize_t srv_sendv(struct srv_ctx *, struct plugin *, unsigned int, ssize_t, struct iovec *, int); -int svc_run(struct svc_ctx *, struct plugin *, unsigned int, const void *, +int srv_run(struct srv_ctx *, struct plugin *, unsigned int, const void *, size_t, ssize_t *, void **, size_t *); -int svc_runv(struct svc_ctx *, struct plugin *, unsigned int, struct iovec *, +int srv_runv(struct srv_ctx *, struct plugin *, unsigned int, struct iovec *, int, ssize_t *, void **, size_t *); #endif diff --git a/src/unpriv.c b/src/unpriv.c index eb51b61..b3e1d39 100644 --- a/src/unpriv.c +++ b/src/unpriv.c @@ -44,7 +44,6 @@ #include "service.h" #include "unpriv.h" -#define U_GETADDRINFO 1 #define U_GETADDRINFO 1 struct unpriv_addrinfo { @@ -64,7 +63,7 @@ struct unpriv_getaddrinfo { }; int -unpriv_getaddrinfo(struct svc_ctx *ctx, const char *hostname, +unpriv_getaddrinfo(struct srv_ctx *ctx, const char *hostname, const char *servname, struct addrinfo *hints, struct addrinfo **restrict res) { @@ -94,7 +93,7 @@ unpriv_getaddrinfo(struct svc_ctx *ctx, const char *hostname, u_gai.u_gai_hints.u_ai_protocol = hints->ai_protocol; } - err = svc_run(ctx, 0, U_GETADDRINFO, &u_gai, sizeof(u_gai), &result, + err = srv_run(ctx, 0, U_GETADDRINFO, &u_gai, sizeof(u_gai), &result, &rdata, &rdata_len); if (err == -1) return -1; @@ -155,7 +154,7 @@ unpriv_getaddrinfo(struct svc_ctx *ctx, const char *hostname, } static ssize_t -unpriv_dispatch(struct svc_ctx *sctx, struct plugin *p, unsigned int cmd, +unpriv_dispatch(struct srv_ctx *sctx, struct plugin *p, unsigned int cmd, const void *data, size_t len) { const struct unpriv_getaddrinfo *u_gai = data; @@ -227,7 +226,7 @@ unpriv_dispatch(struct svc_ctx *sctx, struct plugin *p, unsigned int cmd, freeaddrinfo(ai_result); - res = svc_send(sctx, NULL, U_GETADDRINFO, err, reply, + res = srv_send(sctx, NULL, U_GETADDRINFO, err, reply, sizeof(*reply) * n); free(reply); return res; @@ -235,15 +234,15 @@ unpriv_dispatch(struct svc_ctx *sctx, struct plugin *p, unsigned int cmd, err: freeaddrinfo(ai_result); free(reply); - return svc_send(sctx, NULL, cmd, err, NULL, 0); + return srv_send(sctx, NULL, cmd, err, NULL, 0); } -struct svc_ctx * +struct srv_ctx * unpriv_init(struct ctx *ctx) { if (ctx->ctx_unpriv != NULL) goto out; - ctx->ctx_unpriv = svc_init(ctx, "unprivileged helper", unpriv_dispatch); + ctx->ctx_unpriv = srv_init(ctx, "unprivileged helper", unpriv_dispatch); if (ctx->ctx_unpriv == NULL) return NULL; @@ -251,7 +250,7 @@ unpriv_init(struct ctx *ctx) if (ctx->ctx_options & DHCPSD_RUN) { ctx->ctx_options |= DHCPSD_UNPRIV; dhcpsd_dropperms(0); -#ifdef BSD +#ifdef HAVE_SETPROCTITLE setproctitle("unprivileged helper"); #endif } diff --git a/src/unpriv.h b/src/unpriv.h index 00cf974..121116d 100644 --- a/src/unpriv.h +++ b/src/unpriv.h @@ -29,11 +29,11 @@ #ifndef UNPRIV_H #define UNPRIV_H -struct svc_ctx; +struct srv_ctx; struct addrinfo; -struct svc_ctx *unpriv_init(struct ctx *); -int unpriv_getaddrinfo(struct svc_ctx *, const char *, const char *, +struct srv_ctx *unpriv_init(struct ctx *); +int unpriv_getaddrinfo(struct srv_ctx *, const char *, const char *, struct addrinfo *, struct addrinfo **restrict); void unpriv_freeaddrinfo(struct addrinfo *); #endif