summaryrefslogtreecommitdiffstats
path: root/src/ipv6nd.c
diff options
context:
space:
mode:
authorRoy Marples <roy@marples.name>2020-05-19 16:19:05 +0100
committerRoy Marples <roy@marples.name>2020-05-19 16:19:05 +0100
commitc5445ce8235c153f4f184067ef58249f598d8629 (patch)
treeb16a5c64baf8b7e6ecfcf1f09cf38d13aa68ff09 /src/ipv6nd.c
parentd2fec927e001f2430bb8d5127403968f23b9c316 (diff)
downloaddhcpcd-c5445ce8235c153f4f184067ef58249f598d8629.tar.xz
privsep: Enable Capsicum for all processes.
Except for the priviledged process. This is quite an in-depth change: * ARP is now one process per address * BPF flags are now returned via privsep * BPF write filters are locked when supported * The root process sends to the network The last step is done by opening RAW sockets and then sending a UDP header (where applicable) to avoid binding to an address which is already in use by the reader sockets. This is slightly wasteful for OS's without sandboxing but does have the very nice side effect of not needing a source address to unicast DHCPs replies from which makes the code smaller.
Diffstat (limited to 'src/ipv6nd.c')
-rw-r--r--src/ipv6nd.c84
1 files changed, 35 insertions, 49 deletions
diff --git a/src/ipv6nd.c b/src/ipv6nd.c
index 09595bc2..924dc9de 100644
--- a/src/ipv6nd.c
+++ b/src/ipv6nd.c
@@ -188,36 +188,45 @@ ipv6nd_printoptions(const struct dhcpcd_ctx *ctx,
}
}
-static int
-ipv6nd_open0(void)
+int
+ipv6nd_open(bool recv)
{
int fd, on;
struct icmp6_filter filt;
-#define SOCK_FLAGS SOCK_CLOEXEC | SOCK_NONBLOCK
- fd = xsocket(PF_INET6, SOCK_RAW | SOCK_FLAGS, IPPROTO_ICMPV6);
-#undef SOCK_FLAGS
+ fd = xsocket(PF_INET6, SOCK_RAW | SOCK_CXNB, IPPROTO_ICMPV6);
if (fd == -1)
return -1;
+ ICMP6_FILTER_SETBLOCKALL(&filt);
+
/* RFC4861 4.1 */
on = 255;
if (setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS,
&on, sizeof(on)) == -1)
goto eexit;
- on = 1;
- if (setsockopt(fd, IPPROTO_IPV6, IPV6_RECVPKTINFO,
- &on, sizeof(on)) == -1)
- goto eexit;
+ if (recv) {
+ on = 1;
+ if (setsockopt(fd, IPPROTO_IPV6, IPV6_RECVPKTINFO,
+ &on, sizeof(on)) == -1)
+ goto eexit;
- on = 1;
- if (setsockopt(fd, IPPROTO_IPV6, IPV6_RECVHOPLIMIT,
- &on, sizeof(on)) == -1)
- goto eexit;
+ on = 1;
+ if (setsockopt(fd, IPPROTO_IPV6, IPV6_RECVHOPLIMIT,
+ &on, sizeof(on)) == -1)
+ goto eexit;
+
+ ICMP6_FILTER_SETPASS(ND_ROUTER_ADVERT, &filt);
+
+#ifdef SO_RERROR
+ on = 1;
+ if (setsockopt(fd, SOL_SOCKET, SO_RERROR,
+ &on, sizeof(on)) == -1)
+ goto eexit;
+#endif
+ }
- ICMP6_FILTER_SETBLOCKALL(&filt);
- ICMP6_FILTER_SETPASS(ND_ROUTER_ADVERT, &filt);
if (setsockopt(fd, IPPROTO_ICMPV6, ICMP6_FILTER,
&filt, sizeof(filt)) == -1)
goto eexit;
@@ -231,7 +240,7 @@ eexit:
#ifdef __sun
int
-ipv6nd_open(struct interface *ifp)
+ipv6nd_openif(struct interface *ifp)
{
int fd;
struct ipv6_mreq mreq = {
@@ -244,7 +253,7 @@ ipv6nd_open(struct interface *ifp)
if (state->nd_fd != -1)
return state->nd_fd;
- fd = ipv6nd_open0();
+ fd = ipv6nd_open0(true);
if (fd == -1)
return -1;
@@ -266,24 +275,6 @@ ipv6nd_open(struct interface *ifp)
eloop_event_add(ifp->ctx->eloop, fd, ipv6nd_handledata, ifp);
return fd;
}
-#else
-int
-ipv6nd_open(struct dhcpcd_ctx *ctx)
-{
- int fd;
-
- if (ctx->nd_fd != -1)
- return ctx->nd_fd;
-
- fd = ipv6nd_open0();
- if (fd == -1)
- return -1;
-
- ctx->nd_fd = fd;
- if (!(IN_PRIVSEP(ctx)))
- eloop_event_add(ctx->eloop, fd, ipv6nd_handledata, ctx);
- return fd;
-}
#endif
static int
@@ -340,6 +331,7 @@ ipv6nd_sendrsprobe(void *arg)
struct cmsghdr *cm;
struct in6_pktinfo pi = { .ipi6_ifindex = ifp->index };
int s;
+ struct dhcpcd_ctx *ctx = ifp->ctx;
if (ipv6_linklocal(ifp) == NULL) {
logdebugx("%s: delaying Router Solicitation for LL address",
@@ -372,6 +364,14 @@ ipv6nd_sendrsprobe(void *arg)
#ifdef __sun
s = state->nd_fd;
#else
+ if (ctx->nd_fd == -1) {
+ ctx->nd_fd = ipv6nd_open(true);
+ if (ctx->nd_fd == -1) {
+ logerr(__func__);
+ return;
+ }
+ eloop_event_add(ctx->eloop, ctx->nd_fd, ipv6nd_handledata, ctx);
+ }
s = ifp->ctx->nd_fd;
#endif
if (sendmsg(s, &msg, 0) == -1) {
@@ -2002,20 +2002,6 @@ ipv6nd_startrs1(void *arg)
#endif
}
- if (!(IN_PRIVSEP(ifp->ctx))) {
-#ifdef __sun
- if (ipv6nd_open(ifp) == -1) {
- logerr(__func__);
- return;
- }
-#else
- if (ipv6nd_open(ifp->ctx) == -1) {
- logerr(__func__);
- return;
- }
-#endif
- }
-
/* Always make a new probe as the underlying hardware
* address could have changed. */
ipv6nd_makersprobe(ifp);