]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
Widen types passed to xfr*BitInt to reject too large values. 17240/head
authorMiod Vallat <miod.vallat@powerdns.com>
Fri, 24 Apr 2026 06:33:54 +0000 (08:33 +0200)
committerMiod Vallat <miod.vallat@powerdns.com>
Mon, 4 May 2026 09:44:15 +0000 (11:44 +0200)
Signed-off-by: Miod Vallat <miod.vallat@powerdns.com>
pdns/dnswriter.cc
pdns/dnswriter.hh

index d5079c5dafa1318955cd20d81346e5997db35600..d541c2f64ba791b4a8143acbe917c13573070479 100644 (file)
@@ -134,6 +134,9 @@ template <typename Container> void GenericDNSPacketWriter<Container>::addOpt(con
 
 template <typename Container> void GenericDNSPacketWriter<Container>::xfr48BitInt(uint64_t val)
 {
+  if ((val >> 48) != 0) {
+    throw runtime_error("Value too large to fit in 48 bits");
+  }
   std::array<unsigned char, 6> bytes;
   uint16_t theLeft = htons((val >> 32)&0xffffU);
   uint32_t theRight = htonl(val & 0xffffffffU);
@@ -148,23 +151,32 @@ template <typename Container> void GenericDNSPacketWriter<Container>::xfrNodeOrL
   d_content.insert(d_content.end(), val.content, val.content + sizeof(val.content));
 }
 
-template <typename Container> void GenericDNSPacketWriter<Container>::xfr32BitInt(uint32_t val)
+template <typename Container> void GenericDNSPacketWriter<Container>::xfr32BitInt(uint64_t val)
 {
-  uint32_t rval=htonl(val);
+  if (val > std::numeric_limits<uint32_t>::max()) {
+    throw runtime_error("Value too large to fit in 32 bits");
+  }
+  uint32_t rval=htonl(static_cast<uint32_t>(val));
   uint8_t* ptr=reinterpret_cast<uint8_t*>(&rval);
   d_content.insert(d_content.end(), ptr, ptr+4);
 }
 
-template <typename Container> void GenericDNSPacketWriter<Container>::xfr16BitInt(uint16_t val)
+template <typename Container> void GenericDNSPacketWriter<Container>::xfr16BitInt(uint64_t val)
 {
-  uint16_t rval=htons(val);
+  if (val > std::numeric_limits<uint16_t>::max()) {
+    throw runtime_error("Value too large to fit in 16 bits");
+  }
+  uint16_t rval=htons(static_cast<uint16_t>(val));
   uint8_t* ptr=reinterpret_cast<uint8_t*>(&rval);
   d_content.insert(d_content.end(), ptr, ptr+2);
 }
 
-template <typename Container> void GenericDNSPacketWriter<Container>::xfr8BitInt(uint8_t val)
+template <typename Container> void GenericDNSPacketWriter<Container>::xfr8BitInt(uint64_t val)
 {
-  d_content.push_back(val);
+  if (val > std::numeric_limits<uint8_t>::max()) {
+    throw runtime_error("Value too large to fit in 8 bits");
+  }
+  d_content.push_back(static_cast<uint8_t>(val));
 }
 
 
index fda97854db1359825cabc1cd1be6639d54bb69f6..02a728a0f5709a2a4a942500733440bdc8458fc9 100644 (file)
@@ -87,8 +87,8 @@ public:
 
   void xfr48BitInt(uint64_t val);
   void xfrNodeOrLocatorID(const NodeOrLocatorID& val);
-  void xfr32BitInt(uint32_t val);
-  void xfr16BitInt(uint16_t val);
+  void xfr32BitInt(uint64_t val);
+  void xfr16BitInt(uint64_t val);
   void xfrType(uint16_t val)
   {
     xfr16BitInt(val);
@@ -125,7 +125,7 @@ public:
     xfr32BitInt(val);
   }
 
-  void xfr8BitInt(uint8_t val);
+  void xfr8BitInt(uint64_t val);
 
   void xfrName(const DNSName& name, bool compress=false);
   void xfrText(const string& text, bool multi=false, bool lenField=true);