]> granicus.if.org Git - pdns/commitdiff
dnsdist: Prevent a dangling DOHUnit pointer when send() failed
authorRemi Gacogne <remi.gacogne@powerdns.com>
Mon, 22 Jul 2019 08:38:51 +0000 (10:38 +0200)
committerRemi Gacogne <remi.gacogne@powerdns.com>
Mon, 22 Jul 2019 08:38:51 +0000 (10:38 +0200)
pdns/dnsdistdist/doh.cc

index d667aad7729ecdd772358abcdf6cec5c303a18af..55ed64059466ad3a0bba37506478d6e653074339 100644 (file)
@@ -289,14 +289,21 @@ static int processDOHQuery(DOHUnit* du)
     /* you can't touch du after this line, because it might already have been freed */
     ssize_t ret = udpClientSendRequestToBackend(ss, fd, query, dq.len);
 
-    vinfolog("Got query for %s|%s from %s (https), relayed to %s", ids->qname.toString(), QType(ids->qtype).getName(), remote.toStringWithPort(), ss->getName());
-
     if(ret < 0) {
+      /* we are about to handle the error, make sure that
+         this pointer is not accessed when the state is cleaned,
+         but first check that it still belongs to us */
+      if (ids->origFD == 0 && ids->origFD.exchange(-1) == 0) {
+        ids->du = nullptr;
+        --ss->outstanding;
+      }
       ++ss->sendErrors;
       ++g_stats.downstreamSendErrors;
       du->status_code = 502;
       return -1;
     }
+
+    vinfolog("Got query for %s|%s from %s (https), relayed to %s", ids->qname.toString(), QType(ids->qtype).getName(), remote.toStringWithPort(), ss->getName());
   }
   catch(const std::exception& e) {
     vinfolog("Got an error in DOH question thread while parsing a query from %s, id %d: %s", remote.toStringWithPort(), queryId, e.what());