From: Remi Gacogne Date: Mon, 16 Mar 2026 14:18:10 +0000 (+0100) Subject: Small cleanup `EDNSSubnetOpts::makeOptString()` X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=68622bceecb20bfa5431dda533c9735f249e459f;p=thirdparty%2Fpdns.git Small cleanup `EDNSSubnetOpts::makeOptString()` The existing code was relying on implicit integer conversion rules, which was correct but brittle, so let's explicitely check that the source is non-zero. Signed-off-by: Remi Gacogne --- diff --git a/pdns/ednssubnet.cc b/pdns/ednssubnet.cc index 76c445a13a..60513b602e 100644 --- a/pdns/ednssubnet.cc +++ b/pdns/ednssubnet.cc @@ -97,21 +97,27 @@ std::string EDNSSubnetOpts::makeOptString() const { std::string ret; EDNSSubnetOptsWire esow{}; - uint16_t family = htons(source.getNetwork().sin4.sin_family == AF_INET ? 1 : 2); + uint16_t family = htons(source.isIPv4() ? 1 : 2); esow.family = family; esow.sourcePrefixLength = source.getBits(); esow.scopePrefixLength = scopeBits; // NOLINTBEGIN(cppcoreguidelines-pro-type-reinterpret-cast) ret.assign(reinterpret_cast(&esow), sizeof(esow)); - int octetsout = ((esow.sourcePrefixLength - 1) >> 3) + 1; + size_t octetsout = esow.sourcePrefixLength > 0U ? ((esow.sourcePrefixLength - 1) >> 3) + 1 : 0U; ComboAddress src = source.getNetwork(); src.truncate(esow.sourcePrefixLength); - if (family == htons(1)) { + if (source.isIPv4()) { + if (octetsout > sizeof(src.sin4.sin_addr.s_addr)) { + throw std::runtime_error("Trying to copy too many bytes while generating an EDNS Client Subnet option"); + } ret.append(reinterpret_cast(&src.sin4.sin_addr.s_addr), octetsout); } else { + if (octetsout > sizeof(src.sin6.sin6_addr.s6_addr)) { + throw std::runtime_error("Trying to copy too many bytes while generating an EDNS Client Subnet option"); + } ret.append(reinterpret_cast(&src.sin6.sin6_addr.s6_addr), octetsout); } // NOLINTEND(cppcoreguidelines-pro-type-reinterpret-cast)