summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRoy Marples <roy@marples.name>2020-05-10 12:19:59 +0100
committerRoy Marples <roy@marples.name>2020-05-10 12:19:59 +0100
commit82d7c0bc10c09e0fb5ae4df1eeaede78377d1c8b (patch)
treecb279ed101c8eed6c078d41b1bdfe75b514c2aef
parent6c1e0dbd92be10ba63fac479e545c95dd983ea26 (diff)
downloaddhcpcd-82d7c0bc10c09e0fb5ae4df1eeaede78377d1c8b.tar.xz
privsep: Add function for indirect ioctl
-rw-r--r--src/privsep-bsd.c47
-rw-r--r--src/privsep-root.h2
-rw-r--r--src/privsep.h3
3 files changed, 45 insertions, 7 deletions
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 <sys/ioctl.h>
#include <errno.h>
+#include <string.h>
#include <unistd.h>
#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:
@@ -114,6 +135,20 @@ ps_root_ioctl6(struct dhcpcd_ctx *ctx, unsigned long request,
}
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