]> git.ipfire.org Git - thirdparty/dhcpcd.git/commitdiff
privsep: Filter ioctls to a known list.
authorRoy Marples <roy@marples.name>
Wed, 20 May 2020 17:14:38 +0000 (18:14 +0100)
committerRoy Marples <roy@marples.name>
Wed, 20 May 2020 17:14:38 +0000 (18:14 +0100)
In-case the master process is broken into.

src/privsep-bsd.c
src/privsep-root.c

index d714eee4e9aba0beb4faa4d97c7fe331a91c4021..e73984e44323d028546c54f84b7f492b38eadec7 100644 (file)
 
 #include <sys/ioctl.h>
 
+/* Need these for filtering the ioctls */
+#include <net/if.h>
+#include <netinet/in.h>
+#include <netinet6/in6_var.h>
+#include <netinet6/nd6.h>
+
 #include <errno.h>
 #include <string.h>
 #include <unistd.h>
@@ -41,6 +47,38 @@ ps_root_doioctldom(int domain, unsigned long req, void *data, size_t len)
 {
        int s, err;
 
+       /* Only allow these ioctls */
+       switch(req) {
+#ifdef SIOCIFAFATTACH
+       case SIOCIFAFATTACH:    /* FALLTHROUGH */
+#endif
+#ifdef SIOCSIFXFLAGS
+       case SIOCSIFXFLAGS:     /* FALLTHROUGH */
+#endif
+#ifdef SIOCSIFINFO_FLAGS
+       case SIOCSIFINFO_FLAGS: /* FALLTHROUGH */
+#endif
+#ifdef SIOCSRTRFLUSH_IN6
+       case SIOCSRTRFLUSH_IN6: /* FALLTHROUGH */
+       case SIOCSPFXFLUSH_IN6: /* FALLTHROUGH */
+#endif
+#if defined(SIOCALIFADDR) && defined(IFLR_ACTIVE)
+       case SIOCALIFADDR:      /* FALLTHROUGH */
+       case SIOCDLIFADDR:      /* FALLTHROUGH */
+#else
+       case SIOCSIFLLADDR:     /* FALLTHROUGH */
+#endif
+#ifdef SIOCSIFINFO_IN6
+       case SIOCSIFINFO_IN6:   /* FALLTHROUGH */
+#endif
+       case SIOCAIFADDR_IN6:   /* FALLTHROUGH */
+       case SIOCDIFADDR_IN6:   /* FALLTHROUGH */
+               break;
+       default:
+               errno = EPERM;
+               return -1;
+       }
+
        s = socket(domain, SOCK_DGRAM, 0);
        if (s == -1)
                return -1;
@@ -73,6 +111,15 @@ ps_root_doindirectioctl(unsigned long req, void *data, size_t len)
        struct ifreq ifr = { .ifr_flags = 0 };
        ssize_t err;
 
+       switch(req) {
+       case SIOCG80211NWID:    /* FALLTHROUGH */
+       case SIOCGETVLAN:
+               break;
+       default:
+               errno = EPERM;
+               return -1;
+       }
+
        if (len < IFNAMSIZ) {
                errno = EINVAL;
                return -1;
index f511a43f3311c1dade7f4be9abbe948d77c35a9b..8232a5320a78fd1e89f0c88658b24c4e01488640 100644 (file)
@@ -215,6 +215,27 @@ ps_root_doioctl(unsigned long req, void *data, size_t len)
 {
        int s, err;
 
+       /* Only allow these ioctls */
+       switch(req) {
+#ifdef SIOCAIFADDR
+       case SIOCAIFADDR:       /* FALLTHROUGH */
+       case SIOCDIFADDR:       /* FALLTHROUGH */
+#endif
+#ifdef SIOCSIFHWADDR
+       case SIOCSIFHWADDR:     /* FALLTHROUGH */
+#endif
+#ifdef SIOCGIFPRIORITY
+       case SIOCGIFPRIORITY:   /* FALLTHROUGH */
+#endif
+       case SIOCSIFFLAGS:      /* FALLTHROUGH */
+       case SIOCGIFMTU:        /* FALLTHROUGH */
+       case SIOCSIFMTU:
+               break;
+       default:
+               errno = EPERM;
+               return -1;
+       }
+
        s = socket(PF_INET, SOCK_DGRAM, 0);
        if (s != -1)
 #ifdef IOCTL_REQUEST_TYPE