}
#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;
}
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;
* 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;
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
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 *);
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
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;
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
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 *);
#define PS_IOCTLINDIRECT 0x0103
#define PS_IP6FORWARDING 0x0104
#define PS_GETIFADDRS 0x0105
+#define PS_IFIGNOREGRP 0x0106
/* Dev Commands */
#define PS_DEV_LISTENING 0x0201