diff --git a/pdns/proxy-protocol.cc b/pdns/proxy-protocol.cc index a68f094c902e..9bf48adcc343 100644 --- a/pdns/proxy-protocol.cc +++ b/pdns/proxy-protocol.cc @@ -32,7 +32,7 @@ static const string proxymagic(PROXYMAGIC, PROXYMAGICLEN); static void makeSimpleHeader(uint8_t command, uint8_t protocol, uint16_t contentLen, size_t additionalSize, std::string& out) { const uint8_t versioncommand = (0x20 | command); - const size_t totalSize = proxymagic.size() + sizeof(versioncommand) + sizeof(protocol) + sizeof(contentLen) + contentLen + additionalSize; + const size_t totalSize = proxymagic.size() + sizeof(versioncommand) + sizeof(protocol) + sizeof(contentLen) + additionalSize; if (out.capacity() < totalSize) { out.reserve(totalSize); } @@ -75,14 +75,15 @@ std::string makeProxyHeader(bool tcp, const ComboAddress& source, const ComboAdd } } - size_t total = (addrSize * 2) + sizeof(sourcePort) + sizeof(destinationPort) + valuesSize; - if (total > std::numeric_limits::max()) { - throw std::runtime_error("The size of a proxy protocol header is limited to " + std::to_string(std::numeric_limits::max()) + ", trying to send one of size " + std::to_string(total)); + /* size of the data that will come _after_ the minimal proxy protocol header */ + size_t additionalDataSize = (addrSize * 2) + sizeof(sourcePort) + sizeof(destinationPort) + valuesSize; + if (additionalDataSize > std::numeric_limits::max()) { + throw std::runtime_error("The size of a proxy protocol header is limited to " + std::to_string(std::numeric_limits::max()) + ", trying to send one of size " + std::to_string(additionalDataSize)); } - const uint16_t contentlen = htons(static_cast(total)); + const uint16_t contentlen = htons(static_cast(additionalDataSize)); std::string ret; - makeSimpleHeader(command, protocol, contentlen, total, ret); + makeSimpleHeader(command, protocol, contentlen, additionalDataSize, ret); // We already established source and destination sin_family equivalence if (source.isIPv4()) { diff --git a/pdns/test-proxy_protocol_cc.cc b/pdns/test-proxy_protocol_cc.cc index e61f9787618e..6a672c4dac01 100644 --- a/pdns/test-proxy_protocol_cc.cc +++ b/pdns/test-proxy_protocol_cc.cc @@ -101,6 +101,18 @@ BOOST_AUTO_TEST_CASE(test_tlv_values_content_len_signedness) { } } +BOOST_AUTO_TEST_CASE(test_payload_too_large) { + const bool tcp = false; + const ComboAddress src("[2001:db8::1]:0"); + const ComboAddress dest("[::1]:65535"); + std::string largeValue; + /* this value is larger than the maximum size for a TLV */ + largeValue.resize(65536, 'A'); + const std::vector values = {{ largeValue, 255 }}; + + BOOST_CHECK_THROW(makeProxyHeader(tcp, src, dest, values), std::runtime_error); +} + BOOST_AUTO_TEST_CASE(test_tlv_values_length_signedness) { std::string largeValue; /* this value will make the TLV length parsing fail in case of signedness mistake */