From e6935cd001dc439d49edeba0c1fa6e31cef000be Mon Sep 17 00:00:00 2001 From: Peter van Dijk Date: Tue, 6 Apr 2021 21:48:23 +0200 Subject: [PATCH] fix read alignment in dnspcap --- pdns/dnspcap.cc | 11 +++++++++-- pdns/dnspcap.hh | 4 +++- pdns/dnsreplay.cc | 2 +- 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/pdns/dnspcap.cc b/pdns/dnspcap.cc index c7d634504f..669faea87e 100644 --- a/pdns/dnspcap.cc +++ b/pdns/dnspcap.cc @@ -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); diff --git a/pdns/dnspcap.hh b/pdns/dnspcap.hh index 5cb73a325c..1689ee92ce 100644 --- a/pdns/dnspcap.hh +++ b/pdns/dnspcap.hh @@ -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 d_fp{nullptr, fclose}; string d_fname; diff --git a/pdns/dnsreplay.cc b/pdns/dnsreplay.cc index 1bfffd3fed..3679e73bcb 100644 --- a/pdns/dnsreplay.cc +++ b/pdns/dnsreplay.cc @@ -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; -- 2.47.2