]> git.ipfire.org Git - thirdparty/dhcpcd.git/commitdiff
privsep: Remove pledges inet and dns from the master process
authorRoy Marples <roy@marples.name>
Fri, 5 Jun 2020 10:12:21 +0000 (11:12 +0100)
committerRoy Marples <roy@marples.name>
Fri, 5 Jun 2020 10:12:21 +0000 (11:12 +0100)
Achieved by adding IPC to ignore interfaces names based on
the interface group.

This means every process just pledges stdio for IPC which the
exception of the master process which also pledges route so it
can access the routing table.

src/dhcpcd.c
src/if-bsd.c
src/if.h
src/privsep-bsd.c
src/privsep-root.h
src/privsep.h

index 1363b3c7f379af231e747495f3b6d5bc1415f4de..dddf328107b07ac33aaf0b1edd679898af3e281e 100644 (file)
@@ -2309,7 +2309,7 @@ printpidfile:
                }
 #endif
 #ifdef HAVE_PLEDGE
-               if (pledge("stdio inet route dns", NULL) == -1) {
+               if (pledge("stdio route", NULL) == -1) {
                        logerr("%s: pledge", __func__);
                        goto exit_failure;
                }
index 78735c7b9fd8c7c04a39f6778db0ef1ba91f2777..495d9acb3b7442cd6573b38f7b2774293750c76d 100644 (file)
@@ -292,21 +292,10 @@ if_ignore1(const char *drvname)
        return false;
 }
 
-bool
-if_ignore(struct dhcpcd_ctx *ctx, const char *ifname)
-{
-       struct if_spec spec;
-
-       if (if_nametospec(ifname, &spec) != 0)
-               return false;
-
-       if (if_ignore1(spec.drvname))
-               return true;
-
 #ifdef SIOCGIFGROUP
-#ifdef HAVE_PLEDGE
-#warning Fix SIOCGIFGROUP to use privsep to remove inet pledge requirement
-#endif
+int
+if_ignoregroup(int s, const char *ifname)
+{
        struct ifgroupreq ifgr = { .ifgr_len = 0 };
        struct ifg_req *ifg;
        size_t ifg_len;
@@ -316,12 +305,12 @@ if_ignore(struct dhcpcd_ctx *ctx, const char *ifname)
         * will be very unlikely.... */
 
        strlcpy(ifgr.ifgr_name, ifname, sizeof(ifgr.ifgr_name));
-       if (ioctl(ctx->pf_inet_fd, SIOCGIFGROUP, &ifgr) == -1 ||
+       if (ioctl(s, SIOCGIFGROUP, &ifgr) == -1 ||
            (ifgr.ifgr_groups = malloc(ifgr.ifgr_len)) == NULL ||
-           ioctl(ctx->pf_inet_fd, SIOCGIFGROUP, &ifgr) == -1)
+           ioctl(s, SIOCGIFGROUP, &ifgr) == -1)
        {
                logerr(__func__);
-               return false;
+               return -1;
        }
 
        for (ifg = ifgr.ifgr_groups, ifg_len = ifgr.ifgr_len;
@@ -329,13 +318,35 @@ if_ignore(struct dhcpcd_ctx *ctx, const char *ifname)
             ifg++, ifg_len -= sizeof(*ifg))
        {
                if (if_ignore1(ifg->ifgrq_group))
-                       return true;
+                       return 1;
        }
-#else
-       UNUSED(ctx);
+       return 0;
+}
 #endif
 
+bool
+if_ignore(struct dhcpcd_ctx *ctx, const char *ifname)
+{
+       struct if_spec spec;
+
+       if (if_nametospec(ifname, &spec) != 0)
+               return false;
+
+       if (if_ignore1(spec.drvname))
+               return true;
+
+#ifdef SIOCGIFGROUP
+#if defined(PRIVSEP) && defined(HAVE_PLEDGE)
+       if (IN_PRIVSEP(ctx))
+               return ps_root_ifignoregroup(ctx, ifname) == 1 ? true : false;
+#endif
+       else
+               return if_ignoregroup(ctx->pf_inet_fd, ifname) == 1 ?
+                   true : false;
+#else
+       UNUSED(ctx);
        return false;
+#endif
 }
 
 int
index e644afc8c025738b2e1510980bebd2ab0eedcf93..8abf079a783b4fcd793747eca8c79ac856cb4a91 100644 (file)
--- a/src/if.h
+++ b/src/if.h
@@ -182,6 +182,7 @@ int if_nametospec(const char *, struct if_spec *);
 int if_conf(struct interface *);
 int if_init(struct interface *);
 int if_getssid(struct interface *);
+int if_ignoregroup(int, const char *);
 bool if_ignore(struct dhcpcd_ctx *, const char *);
 int if_vimaster(struct dhcpcd_ctx *ctx, const char *);
 unsigned short if_vlanid(const struct interface *);
index 28b74354096830e91c0c699566f9e3ada5198a41..d09686d81ec052187a0b3698bd662ec69e05ba4d 100644 (file)
@@ -136,6 +136,24 @@ ps_root_doindirectioctl(unsigned long req, void *data, size_t len)
 
        return ps_root_doioctldom(PF_INET, req, &ifr, sizeof(ifr));
 }
+
+static ssize_t
+ps_root_doifignoregroup(void *data, size_t len)
+{
+       int s, err;
+
+       if (len == 0 || ((const char *)data)[len - 1] != '\0') {
+               errno = EINVAL;
+               return -1;
+       }
+
+       s = socket(PF_INET, SOCK_DGRAM, 0);
+       if (s == -1)
+               return -1;
+       err = if_ignoregroup(s, data);
+       close(s);
+       return err;
+}
 #endif
 
 ssize_t
@@ -160,6 +178,8 @@ ps_root_os(struct ps_msghdr *psm, struct msghdr *msg,
        case PS_IOCTLINDIRECT:
                err = ps_root_doindirectioctl(psm->ps_flags, data, len);
                break;
+       case PS_IFIGNOREGRP:
+               return ps_root_doifignoregroup(data, len);
 #endif
        default:
                errno = ENOTSUP;
@@ -228,4 +248,14 @@ ps_root_indirectioctl(struct dhcpcd_ctx *ctx, unsigned long request,
                return -1;
        return ps_root_readerror(ctx, data, len);
 }
+
+ssize_t
+ps_root_ifignoregroup(struct dhcpcd_ctx *ctx, const char *ifname)
+{
+
+       if (ps_sendcmd(ctx, ctx->ps_root_fd, PS_IFIGNOREGRP, 0,
+           ifname, strlen(ifname) + 1) == -1)
+               return -1;
+       return ps_root_readerror(ctx, NULL, 0);
+}
 #endif
index a8e34227a2388cb84a7c580e0a331b9cebb831b9..371431bf2ef9f36dd3a09b157dd702cfc97632d5 100644 (file)
@@ -54,6 +54,7 @@ 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);
+ssize_t ps_root_ifignoregroup(struct dhcpcd_ctx *, const char *);
 #endif
 #ifdef __linux__
 ssize_t ps_root_sendnetlink(struct dhcpcd_ctx *, int, struct msghdr *);
index f1fee41e9eddc7638fe5a205a4ebb86363e42469..b22dfd9f278872d3a1ba4279558595efb1f65313 100644 (file)
@@ -57,6 +57,7 @@
 #define        PS_IOCTLINDIRECT        0x0103
 #define        PS_IP6FORWARDING        0x0104
 #define        PS_GETIFADDRS           0x0105
+#define        PS_IFIGNOREGRP          0x0106
 
 /* Dev Commands */
 #define        PS_DEV_LISTENING        0x0201