diff options
author | Thomas Markwalder <tmark@isc.org> | 2017-06-12 11:43:15 -0400 |
---|---|---|
committer | Thomas Markwalder <tmark@isc.org> | 2017-06-12 11:43:15 -0400 |
commit | 2d70dfc69b6a97c3afdbc81513234f2d31e3eacc (patch) | |
tree | 5098f4dde63c6db3bf5e6b3adcdfeb5d349d7690 | |
parent | 2a796026d948970d93a3bb16536614de9b7e9cdc (diff) | |
download | isc-dhcp-2d70dfc69b6a97c3afdbc81513234f2d31e3eacc.tar.gz |
[v4_1_esv] Server now handles prefix/pool prefix length mismatches
Merged in 35378.
-rw-r--r-- | RELNOTES | 11 | ||||
-rw-r--r-- | server/confpars.c | 11 | ||||
-rw-r--r-- | server/dhcpv6.c | 11 |
3 files changed, 26 insertions, 7 deletions
@@ -140,6 +140,17 @@ by Eric Young (eay@cryptsoft.com). freebsd, linux, macos, netbsd, openbsd. [ISC-Bugs #36169] +- The server nows checks both the address and length of a prefix delegation + when attempting to match it to a prefix pool. This ensures the server + responds properly when pool configurations change such that once valid, + "in-pool" delegations are now treated as being invalid. During lease + file loading at startup, the server will discard any PD leases that + are deemed "out-of-pool" either by address or mis-matched prefix length. + Clients seeking to renew or rebind such leases will get a response of + No Binding in the case of the former, and the prefix delegation with + lifetimes set to zero in the case of the latter. + [ISC-Bugs #35378] + Changes since 4.1-ESV-R14b1 - None diff --git a/server/confpars.c b/server/confpars.c index 56811612..889aa283 100644 --- a/server/confpars.c +++ b/server/confpars.c @@ -5344,13 +5344,16 @@ parse_ia_pd_declaration(struct parse *cfile) { binding_scope_dereference(&scope, MDL); } - /* find the pool this address is in */ + /* Find the pool this address is in. We need to check prefix + * lengths too in case the pool has been reconfigured. */ pool = NULL; - if (find_ipv6_pool(&pool, D6O_IA_PD, - &iapref->addr) != ISC_R_SUCCESS) { + if ((find_ipv6_pool(&pool, D6O_IA_PD, + &iapref->addr) != ISC_R_SUCCESS) || + (pool->units != iapref->plen)) { inet_ntop(AF_INET6, &iapref->addr, addr_buf, sizeof(addr_buf)); - log_error("No pool found for prefix %s", addr_buf); + log_error("No pool found for prefix %s/%d", addr_buf, + iapref->plen); iasubopt_dereference(&iapref, MDL); continue; } diff --git a/server/dhcpv6.c b/server/dhcpv6.c index 9099e067..77bad87e 100644 --- a/server/dhcpv6.c +++ b/server/dhcpv6.c @@ -1139,22 +1139,25 @@ try_client_v6_prefix(struct iasubopt **pref, if (requested_pref->len < sizeof(tmp_plen) + sizeof(tmp_pref)) { return ISC_R_INVALIDARG; } + tmp_plen = (int) requested_pref->data[0]; - if ((tmp_plen < 3) || (tmp_plen > 128) || - ((int)tmp_plen != pool->units)) { + if ((tmp_plen < 3) || (tmp_plen > 128)) { return ISC_R_FAILURE; } + memcpy(&tmp_pref, requested_pref->data + 1, sizeof(tmp_pref)); if (IN6_IS_ADDR_UNSPECIFIED(&tmp_pref)) { return ISC_R_FAILURE; } + ia.len = 16; memcpy(&ia.iabuf, &tmp_pref, 16); if (!is_cidr_mask_valid(&ia, (int) tmp_plen)) { return ISC_R_FAILURE; } - if (!ipv6_in_pool(&tmp_pref, pool)) { + if (!ipv6_in_pool(&tmp_pref, pool) || + ((int)tmp_plen != pool->units)) { return ISC_R_ADDRNOTAVAIL; } @@ -1166,6 +1169,7 @@ try_client_v6_prefix(struct iasubopt **pref, if (result != ISC_R_SUCCESS) { return result; } + (*pref)->addr = tmp_pref; (*pref)->plen = tmp_plen; @@ -1174,6 +1178,7 @@ try_client_v6_prefix(struct iasubopt **pref, if (result != ISC_R_SUCCESS) { iasubopt_dereference(pref, MDL); } + return result; } |