diff options
author | Stuart Henderson <sthen@cvs.openbsd.org> | 2019-12-18 11:04:15 +0000 |
---|---|---|
committer | Stuart Henderson <sthen@cvs.openbsd.org> | 2019-12-18 11:04:15 +0000 |
commit | 4dc56a39845e9269df10b13964307d93622681ea (patch) | |
tree | 97ce227ce1c02e3a8a86cef13cb8420dc7947401 /usr.sbin/unbound/dns64 | |
parent | 80feb8b533ce2d5a9c0115cf2b292e4d5c844f5b (diff) |
merge Unbound 1.9.6
Diffstat (limited to 'usr.sbin/unbound/dns64')
-rw-r--r-- | usr.sbin/unbound/dns64/dns64.c | 49 |
1 files changed, 37 insertions, 12 deletions
diff --git a/usr.sbin/unbound/dns64/dns64.c b/usr.sbin/unbound/dns64/dns64.c index f2834da2bfc..1a569059aff 100644 --- a/usr.sbin/unbound/dns64/dns64.c +++ b/usr.sbin/unbound/dns64/dns64.c @@ -191,16 +191,19 @@ uitoa(unsigned n, char* s) * * \param ipv6 IPv6 address represented as a 128-bit array in big-endian * order. + * \param ipv6_len length of the ipv6 byte array. * \param offset Index of the MSB of the IPv4 address embedded in the IPv6 * address. */ static uint32_t -extract_ipv4(const uint8_t ipv6[16], const int offset) +extract_ipv4(const uint8_t ipv6[], size_t ipv6_len, const int offset) { - uint32_t ipv4 = (uint32_t)ipv6[offset/8+0] << (24 + (offset%8)) - | (uint32_t)ipv6[offset/8+1] << (16 + (offset%8)) - | (uint32_t)ipv6[offset/8+2] << ( 8 + (offset%8)) - | (uint32_t)ipv6[offset/8+3] << ( 0 + (offset%8)); + uint32_t ipv4; + log_assert(ipv6_len == 16); (void)ipv6_len; + ipv4 = (uint32_t)ipv6[offset/8+0] << (24 + (offset%8)) + | (uint32_t)ipv6[offset/8+1] << (16 + (offset%8)) + | (uint32_t)ipv6[offset/8+2] << ( 8 + (offset%8)) + | (uint32_t)ipv6[offset/8+3] << ( 0 + (offset%8)); if (offset/8+4 < 16) ipv4 |= (uint32_t)ipv6[offset/8+4] >> (8 - offset%8); return ipv4; @@ -214,22 +217,26 @@ extract_ipv4(const uint8_t ipv6[16], const int offset) * \param ipv4 IPv4 address represented as an unsigned 32-bit number. * \param ptr The result will be written here. Must be large enough, be * careful! + * \param nm_len length of the ptr buffer. * * \return The number of characters written. */ static size_t -ipv4_to_ptr(uint32_t ipv4, char ptr[MAX_PTR_QNAME_IPV4]) +ipv4_to_ptr(uint32_t ipv4, char ptr[], size_t nm_len) { static const char IPV4_PTR_SUFFIX[] = "\07in-addr\04arpa"; int i; char* c = ptr; + log_assert(nm_len == MAX_PTR_QNAME_IPV4); for (i = 0; i < 4; ++i) { *c = uitoa((unsigned int)(ipv4 % 256), c + 1); c += *c + 1; + log_assert(c < ptr+nm_len); ipv4 /= 256; } + log_assert(c + sizeof(IPV4_PTR_SUFFIX) <= ptr+nm_len); memmove(c, IPV4_PTR_SUFFIX, sizeof(IPV4_PTR_SUFFIX)); return c + sizeof(IPV4_PTR_SUFFIX) - ptr; @@ -241,13 +248,15 @@ ipv4_to_ptr(uint32_t ipv4, char ptr[MAX_PTR_QNAME_IPV4]) * * \param ptr The domain name. (e.g. "\011[...]\010\012\016\012\03ip6\04arpa") * \param ipv6 The result will be written here, in network byte order. + * \param ipv6_len length of the ipv6 byte array. * * \return 1 on success, 0 on failure. */ static int -ptr_to_ipv6(const char* ptr, uint8_t ipv6[16]) +ptr_to_ipv6(const char* ptr, uint8_t ipv6[], size_t ipv6_len) { int i; + log_assert(ipv6_len == 16); (void)ipv6_len; for (i = 0; i < 64; i++) { int x; @@ -275,14 +284,20 @@ ptr_to_ipv6(const char* ptr, uint8_t ipv6[16]) * Synthesize an IPv6 address based on an IPv4 address and the DNS64 prefix. * * \param prefix_addr DNS64 prefix address. + * \param prefix_addr_len length of the prefix_addr buffer. * \param prefix_net CIDR length of the DNS64 prefix. Must be between 0 and 96. * \param a IPv4 address. + * \param a_len length of the a buffer. * \param aaaa IPv6 address. The result will be written here. + * \param aaaa_len length of the aaaa buffer. */ static void -synthesize_aaaa(const uint8_t prefix_addr[16], int prefix_net, - const uint8_t a[4], uint8_t aaaa[16]) +synthesize_aaaa(const uint8_t prefix_addr[], size_t prefix_addr_len, + int prefix_net, const uint8_t a[], size_t a_len, uint8_t aaaa[], + size_t aaaa_len) { + log_assert(prefix_addr_len == 16 && a_len == 4 && aaaa_len == 16); + (void)prefix_addr_len; (void)a_len; (void)aaaa_len; memcpy(aaaa, prefix_addr, 16); aaaa[prefix_net/8+0] |= a[0] >> (0+prefix_net%8); aaaa[prefix_net/8+1] |= a[0] << (8-prefix_net%8); @@ -447,7 +462,8 @@ handle_ipv6_ptr(struct module_qstate* qstate, int id) /* Convert the PTR query string to an IPv6 address. */ memset(&sin6, 0, sizeof(sin6)); sin6.sin6_family = AF_INET6; - if (!ptr_to_ipv6((char*)qstate->qinfo.qname, sin6.sin6_addr.s6_addr)) + if (!ptr_to_ipv6((char*)qstate->qinfo.qname, sin6.sin6_addr.s6_addr, + sizeof(sin6.sin6_addr.s6_addr))) return module_wait_module; /* Let other module handle this. */ /* @@ -470,7 +486,8 @@ handle_ipv6_ptr(struct module_qstate* qstate, int id) if (!(qinfo.qname = regional_alloc(qstate->region, MAX_PTR_QNAME_IPV4))) return module_error; qinfo.qname_len = ipv4_to_ptr(extract_ipv4(sin6.sin6_addr.s6_addr, - dns64_env->prefix_net), (char*)qinfo.qname); + sizeof(sin6.sin6_addr.s6_addr), dns64_env->prefix_net), + (char*)qinfo.qname, MAX_PTR_QNAME_IPV4); /* Create the new sub-query. */ fptr_ok(fptr_whitelist_modenv_attach_sub(qstate->env->attach_sub)); @@ -740,8 +757,10 @@ dns64_synth_aaaa_data(const struct ub_packed_rrset_key* fk, dd->rr_data[i][1] = 16; synthesize_aaaa( ((struct sockaddr_in6*)&dns64_env->prefix_addr)->sin6_addr.s6_addr, + sizeof(((struct sockaddr_in6*)&dns64_env->prefix_addr)->sin6_addr.s6_addr), dns64_env->prefix_net, &fd->rr_data[i][2], - &dd->rr_data[i][2] ); + fd->rr_len[i]-2, &dd->rr_data[i][2], + dd->rr_len[i]-2); dd->rr_ttl[i] = fd->rr_ttl[i]; } @@ -928,6 +947,12 @@ dns64_inform_super(struct module_qstate* qstate, int id, if(!super_dq) { super_dq = (struct dns64_qstate*)regional_alloc(super->region, sizeof(*super_dq)); + if(!super_dq) { + log_err("out of memory"); + super->return_rcode = LDNS_RCODE_SERVFAIL; + super->return_msg = NULL; + return; + } super->minfo[id] = super_dq; memset(super_dq, 0, sizeof(*super_dq)); super_dq->started_no_cache_store = super->no_cache_store; |