]> git.ipfire.org Git - thirdparty/dhcpcd.git/commitdiff
privsep: Add function for indirect ioctl
authorRoy Marples <roy@marples.name>
Sun, 10 May 2020 11:19:59 +0000 (12:19 +0100)
committerRoy Marples <roy@marples.name>
Sun, 10 May 2020 11:19:59 +0000 (12:19 +0100)
src/privsep-bsd.c
src/privsep-root.h
src/privsep.h

index b64040d6d27ec02f813b37d4362fa62b68a4a43b..1a105b63a620820117a41940efd1f90c3d1de4a5 100644 (file)
@@ -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:
@@ -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)
 {
index 466087929a4a866b3c6d7caa8b2c6cc0c7570167..27a481a61be75c61958163946dc76e883d262fd2 100644 (file)
@@ -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 *);
index cb16ac1fadb00ef086d4c1501b6e03ed7d57b4de..9d156e9e1ac4ab28acefa2db482758f7b543709c 100644 (file)
 /* 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