diff options
| author | Roy Marples <roy@marples.name> | 2020-05-24 10:30:23 +0000 |
|---|---|---|
| committer | Roy Marples <roy@marples.name> | 2020-05-24 10:30:23 +0000 |
| commit | f643f08e35fad9e54777b0e327c8cf768f2d82b3 (patch) | |
| tree | e7847afc494da9d0ed00c6fbce96bedeb40e8e50 /src/privsep-root.c | |
| parent | a4951704171655b11c683bacff6df58da5287aa2 (diff) | |
| download | dhcpcd-f643f08e35fad9e54777b0e327c8cf768f2d82b3.tar.xz | |
privsep: Allow dev plugins to work
For udev at least, it requires a /var/run to be available in the chroot
which is poor. As such, give it a full IPC.
Diffstat (limited to 'src/privsep-root.c')
| -rw-r--r-- | src/privsep-root.c | 104 |
1 files changed, 101 insertions, 3 deletions
diff --git a/src/privsep-root.c b/src/privsep-root.c index b4216760..6a82fb6b 100644 --- a/src/privsep-root.c +++ b/src/privsep-root.c @@ -44,6 +44,7 @@ #include <unistd.h> #include "common.h" +#include "dev.h" #include "dhcpcd.h" #include "dhcp6.h" #include "eloop.h" @@ -525,6 +526,14 @@ ps_root_recvmsgcb(void *arg, struct ps_msghdr *psm, struct msghdr *msg) err = ip6_forwarding(data); break; #endif +#ifdef PLUGIN_DEV + case PS_DEV_INITTED: + err = dev_initialized(ctx, data); + break; + case PS_DEV_LISTENING: + err = dev_listening(ctx); + break; +#endif default: err = ps_root_os(psm, msg); break; @@ -548,6 +557,27 @@ ps_root_recvmsg(void *arg) } static int +ps_root_handleinterface(void *arg, int action, const char *ifname) +{ + struct dhcpcd_ctx *ctx = arg; + unsigned long flag; + + if (action == 1) + flag = PS_DEV_IFADDED; + else if (action == -1) + flag = PS_DEV_IFREMOVED; + else if (action == 0) + flag = PS_DEV_IFUPDATED; + else { + errno = EINVAL; + return -1; + } + + return (int)ps_sendcmd(ctx, ctx->ps_data_fd, PS_DEV_IFCMD, flag, + ifname, strlen(ifname) + 1); +} + +static int ps_root_startcb(void *arg) { struct dhcpcd_ctx *ctx = arg; @@ -582,6 +612,12 @@ ps_root_startcb(void *arg) return -1; #endif + /* Start any dev listening plugin which may want to + * change the interface name provided by the kernel */ + if ((ctx->options & (DHCPCD_MASTER | DHCPCD_DEV)) == + (DHCPCD_MASTER | DHCPCD_DEV)) + dev_start(ctx, ps_root_handleinterface); + return 0; } @@ -603,17 +639,58 @@ ps_root_signalcb(int sig, void *arg) eloop_exit(ctx->eloop, sig == SIGTERM ? EXIT_SUCCESS : EXIT_FAILURE); } +int (*handle_interface)(void *, int, const char *); + +#ifdef PLUGIN_DEV +static ssize_t +ps_root_devcb(struct dhcpcd_ctx *ctx, struct ps_msghdr *psm, struct msghdr *msg) +{ + int action; + struct iovec *iov = msg->msg_iov; + + if (msg->msg_iovlen != 1) { + errno = EINVAL; + return -1; + } + + switch(psm->ps_flags) { + case PS_DEV_IFADDED: + action = 1; + break; + case PS_DEV_IFREMOVED: + action = -1; + break; + case PS_DEV_IFUPDATED: + action = 0; + break; + default: + errno = EINVAL; + return -1; + } + + return dhcpcd_handleinterface(ctx, action, iov->iov_base); +} +#endif + static ssize_t ps_root_dispatchcb(void *arg, struct ps_msghdr *psm, struct msghdr *msg) { struct dhcpcd_ctx *ctx = arg; ssize_t err; + switch(psm->ps_cmd) { +#ifdef PLUGIN_DEV + case PS_DEV_IFCMD: + err = ps_root_devcb(ctx, psm, msg); + break; +#endif + default: + err = ps_bpf_dispatch(ctx, psm, msg); #ifdef INET - err = ps_bpf_dispatch(ctx, psm, msg); - if (err == -1 && errno == ENOTSUP) + if (err == -1 && errno == ENOTSUP) #endif - err = ps_inet_dispatch(ctx, psm, msg); + err = ps_inet_dispatch(ctx, psm, msg); + } return err; } @@ -826,3 +903,24 @@ ps_root_ip6forwarding(struct dhcpcd_ctx *ctx, const char *ifname) return ps_root_readerror(ctx, NULL, 0); } #endif + +#ifdef PLUGIN_DEV +int +ps_root_dev_initialized(struct dhcpcd_ctx *ctx, const char *ifname) +{ + + if (ps_sendcmd(ctx, ctx->ps_root_fd, PS_DEV_INITTED, 0, + ifname, strlen(ifname) + 1)== -1) + return -1; + return (int)ps_root_readerror(ctx, NULL, 0); +} + +int +ps_root_dev_listening(struct dhcpcd_ctx * ctx) +{ + + if (ps_sendcmd(ctx, ctx->ps_root_fd, PS_DEV_LISTENING, 0, NULL, 0)== -1) + return -1; + return (int)ps_root_readerror(ctx, NULL, 0); +} +#endif |
