]> granicus.if.org Git - pdns/commitdiff
rec: Don't copy the UDP query from a buffer to a string
authorRemi Gacogne <remi.gacogne@powerdns.com>
Fri, 13 Apr 2018 16:45:41 +0000 (18:45 +0200)
committerRemi Gacogne <remi.gacogne@powerdns.com>
Mon, 16 Apr 2018 12:07:39 +0000 (14:07 +0200)
pdns/pdns_recursor.cc

index f91e31fefa9600dfea30611ca41def525f72f5ea..78c85174ec8335c9dae7809db1c9e37e32f40888 100644 (file)
@@ -1985,21 +1985,30 @@ static string* doProcessUDPQuestion(const std::string& question, const ComboAddr
 static void handleNewUDPQuestion(int fd, FDMultiplexer::funcparam_t& var)
 {
   ssize_t len;
-  char data[1500];
+  static thread_local std::string data;
   ComboAddress fromaddr;
   struct msghdr msgh;
   struct iovec iov;
   char cbuf[256];
   bool firstQuery = true;
 
+  data.resize(1500);
   fromaddr.sin6.sin6_family=AF_INET6; // this makes sure fromaddr is big enough
-  fillMSGHdr(&msgh, &iov, cbuf, sizeof(cbuf), data, sizeof(data), &fromaddr);
+  fillMSGHdr(&msgh, &iov, cbuf, sizeof(cbuf), &data[0], data.size(), &fromaddr);
 
   for(;;)
   if((len=recvmsg(fd, &msgh, 0)) >= 0) {
 
     firstQuery = false;
 
+    if (static_cast<size_t>(len) < sizeof(dnsheader)) {
+      g_stats.ignoredCount++;
+      if (!g_quiet) {
+        g_log<<Logger::Error<<"Ignoring too-short ("<<std::to_string(len)<<") query from "<<fromaddr.toString()<<endl;
+      }
+      return;
+    }
+
     if(t_remotes)
       t_remotes->push_back(fromaddr);
 
@@ -2019,7 +2028,8 @@ static void handleNewUDPQuestion(int fd, FDMultiplexer::funcparam_t& var)
       return;
     }
     try {
-      dnsheader* dh=(dnsheader*)data;
+      data.resize(static_cast<size_t>(len));
+      dnsheader* dh=(dnsheader*)&data[0];
 
       if(dh->qr) {
         g_stats.ignoredCount++;
@@ -2032,7 +2042,6 @@ static void handleNewUDPQuestion(int fd, FDMultiplexer::funcparam_t& var)
           g_log<<Logger::Error<<"Ignoring non-query opcode "<<dh->opcode<<" from "<<fromaddr.toString()<<" on server socket!"<<endl;
       }
       else {
-        string question(data, (size_t)len);
        struct timeval tv={0,0};
        HarvestTimestamp(&msgh, &tv);
        ComboAddress dest;
@@ -2054,9 +2063,9 @@ static void handleNewUDPQuestion(int fd, FDMultiplexer::funcparam_t& var)
           }
         }
         if(g_weDistributeQueries)
-          distributeAsyncFunction(question, boost::bind(doProcessUDPQuestion, question, fromaddr, dest, tv, fd));
+          distributeAsyncFunction(data, boost::bind(doProcessUDPQuestion, data, fromaddr, dest, tv, fd));
         else
-          doProcessUDPQuestion(question, fromaddr, dest, tv, fd);
+          doProcessUDPQuestion(data, fromaddr, dest, tv, fd);
       }
     }
     catch(MOADNSException& mde) {