Module Name: src Committed By: martin Date: Sun May 5 09:02:45 UTC 2019
Modified Files: src/external/bsd/dhcpcd/dist/src [netbsd-7]: dhcp6.c Log Message: Apply patch, requested by roy in ticket #1695: external/bsd/dhcpcd/dist/src/dhcp6.c DHCPv6: Fix a potential read overflow with D6_OPTION_PD_EXCLUDE To generate a diff of this commit: cvs rdiff -u -r1.1.1.12.4.4 -r1.1.1.12.4.5 \ src/external/bsd/dhcpcd/dist/src/dhcp6.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/external/bsd/dhcpcd/dist/src/dhcp6.c diff -u src/external/bsd/dhcpcd/dist/src/dhcp6.c:1.1.1.12.4.4 src/external/bsd/dhcpcd/dist/src/dhcp6.c:1.1.1.12.4.5 --- src/external/bsd/dhcpcd/dist/src/dhcp6.c:1.1.1.12.4.4 Fri Apr 26 19:47:23 2019 +++ src/external/bsd/dhcpcd/dist/src/dhcp6.c Sun May 5 09:02:45 2019 @@ -2152,40 +2152,38 @@ dhcp6_findpd(struct interface *ifp, cons 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; } - a->prefix_exclude_len = *o++; + + /* 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--; - if (((a->prefix_exclude_len - a->prefix_len - 1) / NBBY) + 1 - != ol) - { + /* Check option length matches prefix length. */ + if (((*o - 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; + a->prefix_exclude_len = *o++; + memcpy(&a->prefix_exclude, &a->prefix, sizeof(a->prefix_exclude)); + nb = a->prefix_len % NBBY; if (nb) ol--; pw = a->prefix_exclude.s6_addr +