]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
fix read alignment in dnspcap
authorPeter van Dijk <peter.van.dijk@powerdns.com>
Tue, 6 Apr 2021 19:48:23 +0000 (21:48 +0200)
committerPeter van Dijk <peter.van.dijk@powerdns.com>
Wed, 7 Apr 2021 07:54:49 +0000 (09:54 +0200)
pdns/dnspcap.cc
pdns/dnspcap.hh
pdns/dnsreplay.cc

index c7d634504fcad7a2cb2509daa440716648e10825..669faea87ee1b99766f586fb92a515f1328d728a 100644 (file)
@@ -59,6 +59,13 @@ PcapPacketReader::PcapPacketReader(const string& fname) : d_fname(fname)
   else throw runtime_error((boost::format("Unsupported link type %d") % d_pfh.linktype).str());
 
   d_runts = d_oversized = d_correctpackets = d_nonetheripudp = 0;
+
+  size_t alignmentCorrection = d_skipMediaHeader % alignof(struct ip);
+
+  d_buffer = d_readbuffer + alignmentCorrection;
+  d_bufsize = sizeof(d_readbuffer) - alignmentCorrection;
+
+  if (d_skipMediaHeader > d_bufsize) throw runtime_error("media header is too big");
 }
 
 void PcapPacketReader::checkedFreadSize(void* ptr, size_t size) 
@@ -85,9 +92,9 @@ try
       continue;
     }
 
-    if(d_pheader.caplen > sizeof(d_buffer)) {
+    if(d_pheader.caplen > d_bufsize) {
       d_oversized++;
-      throw runtime_error((boost::format("Can't handle a %d byte packet, have space for %d")  % d_pheader.caplen % sizeof(d_buffer)).str());
+      throw runtime_error((boost::format("Can't handle a %d byte packet, have space for %d")  % d_pheader.caplen % d_bufsize).str());
     }
 
     checkedFreadSize(d_buffer, d_pheader.caplen);
index 5cb73a325c3c6d921f845be23b0cf8ea537a68c3..1689ee92cedcde625254f66c62d0dc17c124cc6c 100644 (file)
@@ -115,7 +115,9 @@ public:
 
   pdns_pcap_file_header d_pfh;
   unsigned int d_runts, d_oversized, d_correctpackets, d_nonetheripudp;
-  char d_buffer[32768];
+  alignas (struct ip) char d_readbuffer[32768];
+  char *d_buffer;
+  size_t d_bufsize;
 private:
   std::unique_ptr<FILE, int(*)(FILE*)> d_fp{nullptr, fclose};
   string d_fname;
index 1bfffd3fed657aa0c049945b228734058c996b1e..3679e73bcb271712f3db61ff902cc827addf580e 100644 (file)
@@ -627,7 +627,7 @@ static bool sendPacketFromPR(PcapPacketReader& pr, const ComboAddress& remote, i
       uint16_t dlen = pr.d_len;
 
       if (stamp >= 0) {
-        static_assert(sizeof(pr.d_buffer) >= 1500, "The size of the underlying buffer should be at least 1500 bytes");
+        static_assert(sizeof(pr.d_readbuffer) >= 1500, "The size of the underlying buffer should be at least 1500 bytes");
         if (dlen > 1500) {
           /* the existing packet is larger than the maximum size we are willing to send, and it won't get better by adding ECS */
           return false;