From: Roy Marples Date: Sun, 10 May 2020 11:19:59 +0000 (+0100) Subject: privsep: Add function for indirect ioctl X-Git-Tag: v9.1.0~82 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1608a3170735cc697625b2d472286ba95fc88a91;p=thirdparty%2Fdhcpcd.git privsep: Add function for indirect ioctl --- diff --git a/src/privsep-bsd.c b/src/privsep-bsd.c index b64040d6..1a105b63 100644 --- a/src/privsep-bsd.c +++ b/src/privsep-bsd.c @@ -29,6 +29,7 @@ #include #include +#include #include #include "dhcpcd.h" @@ -41,12 +42,30 @@ ps_root_doioctldom(int domain, unsigned long req, void *data, size_t len) int s, err; s = socket(domain, SOCK_DGRAM, 0); - if (s != -1) - err = ioctl(s, req, data, len); - else - err = -1; - if (s != -1) - close(s); + if (s == -1) + return -1; + err = ioctl(s, req, data, len); + close(s); + return err; +} + +static ssize_t +ps_root_doindirectioctl(unsigned long req, void *data, size_t len) +{ + char *p = data; + struct ifreq ifr = { .ifr_flags = 0 }; + ssize_t err; + + if (len < IFNAMSIZ) { + errno = EINVAL; + return -1; + } + + strlcpy(ifr.ifr_name, p, IFNAMSIZ); + ifr.ifr_data = p + IFNAMSIZ; + err = ps_root_doioctldom(PF_INET, req, &ifr, sizeof(ifr)); + if (err != -1) + memmove(data, ifr.ifr_data, len - IFNAMSIZ); return err; } @@ -78,6 +97,8 @@ ps_root_os(struct ps_msghdr *psm, struct msghdr *msg) return ps_root_doioctldom(PF_LINK, psm->ps_flags, data, len); case PS_IOCTL6: return ps_root_doioctldom(PF_INET6, psm->ps_flags, data, len); + case PS_IOCTLINDIRECT: + return ps_root_doindirectioctl(psm->ps_flags, data, len); case PS_ROUTE: return ps_root_doroute(data, len); default: @@ -113,6 +134,20 @@ ps_root_ioctl6(struct dhcpcd_ctx *ctx, unsigned long request, return ps_root_ioctldom(ctx, PS_IOCTL6, request, data, len); } +ssize_t +ps_root_indirectioctl(struct dhcpcd_ctx *ctx, unsigned long request, + const char *ifname, void *data, size_t len) +{ + char buf[PS_BUFLEN]; + + strlcpy(buf, ifname, IFNAMSIZ); + memcpy(buf + IFNAMSIZ, data, len); + if (ps_sendcmd(ctx, ctx->ps_root_fd, PS_IOCTLINDIRECT, + request, buf, IFNAMSIZ + len) == -1) + return -1; + return ps_root_readerror(ctx, data, len); +} + ssize_t ps_root_route(struct dhcpcd_ctx *ctx, void *data, size_t len) { diff --git a/src/privsep-root.h b/src/privsep-root.h index 46608792..27a481a6 100644 --- a/src/privsep-root.h +++ b/src/privsep-root.h @@ -44,6 +44,8 @@ ssize_t ps_root_os(struct ps_msghdr *, struct msghdr *); ssize_t ps_root_route(struct dhcpcd_ctx *, void *, size_t); ssize_t ps_root_ioctllink(struct dhcpcd_ctx *, unsigned long, void *, size_t); ssize_t ps_root_ioctl6(struct dhcpcd_ctx *, unsigned long, void *, size_t); +ssize_t ps_root_indirectioctl(struct dhcpcd_ctx *, unsigned long, const char *, + void *, size_t); #endif #ifdef __linux__ ssize_t ps_root_sendnetlink(struct dhcpcd_ctx *, int, struct msghdr *); diff --git a/src/privsep.h b/src/privsep.h index cb16ac1f..9d156e9e 100644 --- a/src/privsep.h +++ b/src/privsep.h @@ -52,9 +52,10 @@ /* BSD Commands */ #define PS_IOCTLLINK 0x15 #define PS_IOCTL6 0x16 +#define PS_IOCTLINDIRECT 0x17 /* Linux commands */ -#define PS_WRITEPATHUINT 0x17 +#define PS_WRITEPATHUINT 0x18 #define PS_DELETE 0x20 #define PS_START 0x40