Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/roy]: src/external/bsd/dhcpcd/dist/src Import dhcpcd-7.2.2 with the foll...
details: https://anonhg.NetBSD.org/src/rev/8392e1c2f711
branches: roy
changeset: 451033:8392e1c2f711
user: roy <roy%NetBSD.org@localhost>
date: Sat May 04 09:40:27 2019 +0000
description:
Import dhcpcd-7.2.2 with the following changes:
* DHCP: Ensure dhcp is running on the interface received from
* BSD: Link handling has been simplified, however it is expected
that if an interface supports SIOCGIFMEDIA then it reports
the correct link status via route(4) for reliable operations
* BPF: ARP filter is more robust
* BSD: Validate RTM message lengths
This security issue has been addressed:
* DHCPv6: Fix a potential read overflow with D6_OPTION_PD_EXCLUDE
Many thanks to Maxime Villard <max%m00nbsd.net@localhost> for discovering this issue.
diffstat:
external/bsd/dhcpcd/dist/src/bpf.c | 23 ++-
external/bsd/dhcpcd/dist/src/defs.h | 2 +-
external/bsd/dhcpcd/dist/src/dhcp.c | 7 +-
external/bsd/dhcpcd/dist/src/dhcp6.c | 48 ++++----
external/bsd/dhcpcd/dist/src/dhcpcd.c | 99 +++++------------
external/bsd/dhcpcd/dist/src/dhcpcd.h | 1 -
external/bsd/dhcpcd/dist/src/if-bsd.c | 143 ++++++++++++++++++--------
external/bsd/dhcpcd/dist/src/if-linux.c | 9 +
external/bsd/dhcpcd/dist/src/if-options.c | 2 +-
external/bsd/dhcpcd/dist/src/if-sun.c | 160 +++++++++++++++++++----------
external/bsd/dhcpcd/dist/src/if.c | 72 ++++---------
external/bsd/dhcpcd/dist/src/if.h | 2 +-
12 files changed, 312 insertions(+), 256 deletions(-)
diffs (truncated from 1144 to 300 lines):
diff -r a243c030c783 -r 8392e1c2f711 external/bsd/dhcpcd/dist/src/bpf.c
--- a/external/bsd/dhcpcd/dist/src/bpf.c Fri Apr 26 14:32:27 2019 +0000
+++ b/external/bsd/dhcpcd/dist/src/bpf.c Sat May 04 09:40:27 2019 +0000
@@ -301,6 +301,7 @@
/* Normally this is needed by bootp.
* Once that uses this again, the ARP guard here can be removed. */
#ifdef ARP
+#define BPF_CMP_HWADDR_LEN ((((HWADDR_LEN / 4) + 2) * 2) + 1)
static unsigned int
bpf_cmp_hwaddr(struct bpf_insn *bpf, size_t bpf_len, size_t off,
bool equal, uint8_t *hwaddr, size_t hwaddr_len)
@@ -414,7 +415,7 @@
sizeof(((struct ether_arp *)0)->arp_sha), 1, 0),
BPF_STMT(BPF_RET + BPF_K, 0),
};
-#define bpf_arp_ether_len __arraycount(bpf_arp_ether)
+#define BPF_ARP_ETHER_LEN __arraycount(bpf_arp_ether)
static const struct bpf_insn bpf_arp_filter [] = {
/* Make sure this is for IP. */
@@ -425,21 +426,25 @@
BPF_STMT(BPF_LD + BPF_H + BPF_IND, offsetof(struct arphdr, ar_op)),
BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, ARPOP_REQUEST, 2, 0),
/* or ARP REPLY. */
- BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, ARPOP_REPLY, 1, 1),
+ BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, ARPOP_REPLY, 1, 0),
BPF_STMT(BPF_RET + BPF_K, 0),
/* Make sure the protocol length matches. */
BPF_STMT(BPF_LD + BPF_B + BPF_IND, offsetof(struct arphdr, ar_pln)),
BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, sizeof(in_addr_t), 1, 0),
BPF_STMT(BPF_RET + BPF_K, 0),
};
-#define bpf_arp_filter_len __arraycount(bpf_arp_filter)
-#define bpf_arp_extra ((((ARP_ADDRS_MAX + 1) * 2) * 2) + 2)
-#define bpf_arp_hw ((((HWADDR_LEN / 4) + 2) * 2) + 1)
+#define BPF_ARP_FILTER_LEN __arraycount(bpf_arp_filter)
+
+#define BPF_ARP_ADDRS_LEN 1 + (ARP_ADDRS_MAX * 2) + 3 + \
+ (ARP_ADDRS_MAX * 2) + 1
+
+#define BPF_ARP_LEN BPF_ARP_ETHER_LEN + BPF_ARP_FILTER_LEN + \
+ BPF_CMP_HWADDR_LEN + BPF_ARP_ADDRS_LEN
int
bpf_arp(struct interface *ifp, int fd)
{
- struct bpf_insn bpf[3+ bpf_arp_filter_len + bpf_arp_hw + bpf_arp_extra];
+ struct bpf_insn bpf[BPF_ARP_LEN];
struct bpf_insn *bp;
struct iarp_state *state;
uint16_t arp_len;
@@ -452,7 +457,7 @@
switch(ifp->family) {
case ARPHRD_ETHER:
memcpy(bp, bpf_arp_ether, sizeof(bpf_arp_ether));
- bp += bpf_arp_ether_len;
+ bp += BPF_ARP_ETHER_LEN;
arp_len = sizeof(struct ether_header)+sizeof(struct ether_arp);
break;
default:
@@ -462,10 +467,10 @@
/* Copy in the main filter. */
memcpy(bp, bpf_arp_filter, sizeof(bpf_arp_filter));
- bp += bpf_arp_filter_len;
+ bp += BPF_ARP_FILTER_LEN;
/* Ensure it's not from us. */
- bp += bpf_cmp_hwaddr(bp, bpf_arp_hw, sizeof(struct arphdr),
+ bp += bpf_cmp_hwaddr(bp, BPF_CMP_HWADDR_LEN, sizeof(struct arphdr),
false, ifp->hwaddr, ifp->hwlen);
state = ARP_STATE(ifp);
diff -r a243c030c783 -r 8392e1c2f711 external/bsd/dhcpcd/dist/src/defs.h
--- a/external/bsd/dhcpcd/dist/src/defs.h Fri Apr 26 14:32:27 2019 +0000
+++ b/external/bsd/dhcpcd/dist/src/defs.h Sat May 04 09:40:27 2019 +0000
@@ -28,7 +28,7 @@
#define CONFIG_H
#define PACKAGE "dhcpcd"
-#define VERSION "7.2.1"
+#define VERSION "7.2.2"
#ifndef CONFIG
# define CONFIG SYSCONFDIR "/" PACKAGE ".conf"
diff -r a243c030c783 -r 8392e1c2f711 external/bsd/dhcpcd/dist/src/dhcp.c
--- a/external/bsd/dhcpcd/dist/src/dhcp.c Fri Apr 26 14:32:27 2019 +0000
+++ b/external/bsd/dhcpcd/dist/src/dhcp.c Sat May 04 09:40:27 2019 +0000
@@ -3499,9 +3499,14 @@
logerr(__func__);
return;
}
+ if (D_CSTATE(ifp) == NULL) {
+ logdebugx("%s: received BOOTP for inactive interface",
+ ifp->name);
+ return;
+ }
}
- dhcp_handlebootp(ifp, (struct bootp *)buf, (size_t)bytes,
+ dhcp_handlebootp(ifp, (struct bootp *)(void *)buf, (size_t)bytes,
&from.sin_addr);
#endif
}
diff -r a243c030c783 -r 8392e1c2f711 external/bsd/dhcpcd/dist/src/dhcp6.c
--- a/external/bsd/dhcpcd/dist/src/dhcp6.c Fri Apr 26 14:32:27 2019 +0000
+++ b/external/bsd/dhcpcd/dist/src/dhcp6.c Sat May 04 09:40:27 2019 +0000
@@ -2166,40 +2166,38 @@
state->expire = a->prefix_vltime;
i++;
- o = dhcp6_findoption(o, ol, D6_OPTION_PD_EXCLUDE, &ol);
a->prefix_exclude_len = 0;
memset(&a->prefix_exclude, 0, sizeof(a->prefix_exclude));
-#if 0
- if (ex == NULL) {
- struct dhcp6_option *w;
- uint8_t *wp;
-
- w = calloc(1, 128);
- w->len = htons(2);
- wp = D6_OPTION_DATA(w);
- *wp++ = 64;
- *wp++ = 0x78;
- ex = w;
- }
-#endif
+ o = dhcp6_findoption(o, ol, D6_OPTION_PD_EXCLUDE, &ol);
if (o == NULL)
continue;
- if (ol < 2) {
- logerrx("%s: truncated PD Exclude", ifp->name);
+
+ /* RFC 6603 4.2 says option length MUST be between 2 and 17.
+ * This allows 1 octet for prefix length and 16 for the
+ * subnet ID. */
+ if (ol < 2 || ol > 17) {
+ logerrx("%s: invalid PD Exclude option", ifp->name);
+ continue;
+ }
+
+ /* RFC 6603 4.2 says prefix length MUST be between the
+ * length of the IAPREFIX prefix length + 1 and 128. */
+ if (*o < a->prefix_len + 1 || *o > 128) {
+ logerrx("%s: invalid PD Exclude length", ifp->name);
+ continue;
+ }
+
+ ol--;
+ /* Check option length matches prefix length. */
+ if (((*o - a->prefix_len - 1) / NBBY) + 1 != ol) {
+ logerrx("%s: PD Exclude length mismatch", ifp->name);
continue;
}
a->prefix_exclude_len = *o++;
- ol--;
- if (((a->prefix_exclude_len - a->prefix_len - 1) / NBBY) + 1
- != ol)
- {
- logerrx("%s: PD Exclude length mismatch", ifp->name);
- a->prefix_exclude_len = 0;
- continue;
- }
- nb = a->prefix_len % NBBY;
+
memcpy(&a->prefix_exclude, &a->prefix,
sizeof(a->prefix_exclude));
+ nb = a->prefix_len % NBBY;
if (nb)
ol--;
pw = a->prefix_exclude.s6_addr +
diff -r a243c030c783 -r 8392e1c2f711 external/bsd/dhcpcd/dist/src/dhcpcd.c
--- a/external/bsd/dhcpcd/dist/src/dhcpcd.c Fri Apr 26 14:32:27 2019 +0000
+++ b/external/bsd/dhcpcd/dist/src/dhcpcd.c Sat May 04 09:40:27 2019 +0000
@@ -84,6 +84,9 @@
const size_t dhcpcd_signals_len = __arraycount(dhcpcd_signals);
#endif
+#define IF_UPANDRUNNING(a) \
+ (((a)->flags & (IFF_UP | IFF_RUNNING)) == (IFF_UP | IFF_RUNNING))
+
static void
usage(void)
{
@@ -653,25 +656,6 @@
}
static void
-dhcpcd_pollup(void *arg)
-{
- struct interface *ifp = arg;
- int carrier;
-
- carrier = if_carrier(ifp); /* will set ifp->flags */
- if (carrier == LINK_UP && !(ifp->flags & IFF_UP)) {
- struct timespec tv;
-
- tv.tv_sec = 0;
- tv.tv_nsec = IF_POLL_UP * NSEC_PER_MSEC;
- eloop_timeout_add_tv(ifp->ctx->eloop, &tv, dhcpcd_pollup, ifp);
- return;
- }
-
- dhcpcd_handlecarrier(ifp->ctx, carrier, ifp->flags, ifp->name);
-}
-
-static void
dhcpcd_initstate2(struct interface *ifp, unsigned long long options)
{
struct if_options *ifo;
@@ -724,35 +708,18 @@
!ifp->active)
return;
- switch(carrier) {
- case LINK_UNKNOWN:
- carrier = if_carrier(ifp); /* will set ifp->flags */
- break;
- case LINK_UP:
- /* we have a carrier! Still need to check for IFF_UP */
- if (flags & IFF_UP)
+ if (carrier == LINK_UNKNOWN) {
+ if (ifp->wireless) {
+ carrier = LINK_DOWN;
ifp->flags = flags;
- else {
- /* So we need to poll for IFF_UP as there is no
- * kernel notification when it's set. */
- dhcpcd_pollup(ifp);
- return;
- }
- break;
- default:
+ } else
+ carrier = if_carrier(ifp);
+ } else
ifp->flags = flags;
- }
+ if (carrier == LINK_UNKNOWN)
+ carrier = IF_UPANDRUNNING(ifp) ? LINK_UP : LINK_DOWN;
- /* If we here, we don't need to poll for IFF_UP any longer
- * if generated by a kernel event. */
- eloop_timeout_delete(ifp->ctx->eloop, dhcpcd_pollup, ifp);
-
- if (carrier == LINK_UNKNOWN) {
- if (errno != ENOTTY && errno != ENXIO) {
- /* Don't log an error if interface departed */
- logerr("%s: %s", ifp->name, __func__);
- }
- } else if (carrier == LINK_DOWN || (ifp->flags & IFF_UP) == 0) {
+ if (carrier == LINK_DOWN || (ifp->flags & IFF_UP) == 0) {
if (ifp->carrier != LINK_DOWN) {
if (ifp->carrier == LINK_UP)
loginfox("%s: carrier lost", ifp->name);
@@ -867,7 +834,6 @@
struct if_options *ifo = ifp->options;
char buf[DUID_LEN * 3];
int carrier;
- struct timespec tv;
if (ifo->options & DHCPCD_LINK) {
switch (ifp->carrier) {
@@ -879,14 +845,22 @@
case LINK_UNKNOWN:
/* No media state available.
* Loop until both IFF_UP and IFF_RUNNING are set */
- if ((carrier = if_carrier(ifp)) == LINK_UNKNOWN) {
- tv.tv_sec = 0;
- tv.tv_nsec = IF_POLL_UP * NSEC_PER_MSEC;
- eloop_timeout_add_tv(ifp->ctx->eloop,
- &tv, dhcpcd_startinterface, ifp);
- } else
- dhcpcd_handlecarrier(ifp->ctx, carrier,
- ifp->flags, ifp->name);
+ carrier = if_carrier(ifp);
+ if (carrier == LINK_UNKNOWN) {
+ if (IF_UPANDRUNNING(ifp))
+ carrier = LINK_UP;
+ else {
+ struct timespec tv;
+
+ tv.tv_sec = 0;
+ tv.tv_nsec = IF_POLL_UP * NSEC_PER_MSEC;
+ eloop_timeout_add_tv(ifp->ctx->eloop,
+ &tv, dhcpcd_startinterface, ifp);
+ return;
+ }
+ }
+ dhcpcd_handlecarrier(ifp->ctx, carrier,
+ ifp->flags, ifp->name);
return;
}
}
@@ -987,20 +961,6 @@
)
logerr("%s: %s", __func__, ifp->name);
- if (ifp->options->options & DHCPCD_LINK &&
- ifp->carrier == LINK_UNKNOWN)
Home |
Main Index |
Thread Index |
Old Index