Skip to content

Commit

Permalink
dnsdist: Fix computation of the final proxy protocol payload size
Browse files Browse the repository at this point in the history
  • Loading branch information
rgacogne committed Sep 29, 2022
1 parent 2db6729 commit b98373a
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 6 deletions.
13 changes: 7 additions & 6 deletions pdns/proxy-protocol.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down Expand Up @@ -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<uint16_t>::max()) {
throw std::runtime_error("The size of a proxy protocol header is limited to " + std::to_string(std::numeric_limits<uint16_t>::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<uint16_t>::max()) {
throw std::runtime_error("The size of a proxy protocol header is limited to " + std::to_string(std::numeric_limits<uint16_t>::max()) + ", trying to send one of size " + std::to_string(additionalDataSize));
}

const uint16_t contentlen = htons(static_cast<uint16_t>(total));
const uint16_t contentlen = htons(static_cast<uint16_t>(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()) {
Expand Down
12 changes: 12 additions & 0 deletions pdns/test-proxy_protocol_cc.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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<ProxyProtocolValue> 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 */
Expand Down

0 comments on commit b98373a

Please sign in to comment.