[PATCH 06/10] mDNSResponder: Update to v878.240.1

Sebastian Huber sebastian.huber at embedded-brains.de
Fri Jun 19 11:02:20 UTC 2020


The sources can be obtained via:

https://opensource.apple.com/tarballs/mDNSResponder/mDNSResponder-878.240.1.tar.gz

Update #4010.
---
 mDNSResponder/Makefile             |  2 +-
 mDNSResponder/mDNSCore/DNSCommon.c |  4 ++--
 mDNSResponder/mDNSCore/DNSCommon.h |  7 +++++++
 mDNSResponder/mDNSCore/mDNS.c      | 33 ++++++++++++++++++++++--------
 mDNSResponder/mDNSCore/uDNS.c      | 18 ++++++++--------
 mDNSResponder/mDNSCore/uDNS.h      |  2 ++
 mDNSResponder/mDNSShared/dns_sd.h  |  2 +-
 7 files changed, 47 insertions(+), 21 deletions(-)

diff --git a/mDNSResponder/Makefile b/mDNSResponder/Makefile
index 8b97eacc..78adbd5e 100644
--- a/mDNSResponder/Makefile
+++ b/mDNSResponder/Makefile
@@ -17,7 +17,7 @@
 
 include $(MAKEFILEPATH)/pb_makefiles/platform.make
 
-MVERS = "mDNSResponder-878.230.2"
+MVERS = "mDNSResponder-878.240.1"
 
 VER =
 ifneq ($(strip $(GCC_VERSION)),)
diff --git a/mDNSResponder/mDNSCore/DNSCommon.c b/mDNSResponder/mDNSCore/DNSCommon.c
index a249b967..f3150762 100644
--- a/mDNSResponder/mDNSCore/DNSCommon.c
+++ b/mDNSResponder/mDNSCore/DNSCommon.c
@@ -3467,8 +3467,8 @@ mDNSexport const mDNSu8 *GetLargeResourceRecord(mDNS *const m, const DNSMessage
     rr->resrec.rrtype            = (mDNSu16) ((mDNSu16)ptr[0] <<  8 | ptr[1]);
     rr->resrec.rrclass           = (mDNSu16)(((mDNSu16)ptr[2] <<  8 | ptr[3]) & kDNSClass_Mask);
     rr->resrec.rroriginalttl     = (mDNSu32) ((mDNSu32)ptr[4] << 24 | (mDNSu32)ptr[5] << 16 | (mDNSu32)ptr[6] << 8 | ptr[7]);
-    if (rr->resrec.rroriginalttl > 0x70000000UL / mDNSPlatformOneSecond && (mDNSs32)rr->resrec.rroriginalttl != -1)
-        rr->resrec.rroriginalttl = 0x70000000UL / mDNSPlatformOneSecond;
+    if (rr->resrec.rroriginalttl > mDNSMaximumTTLSeconds && (mDNSs32)rr->resrec.rroriginalttl != -1)
+        rr->resrec.rroriginalttl = mDNSMaximumTTLSeconds;
     // Note: We don't have to adjust m->NextCacheCheck here -- this is just getting a record into memory for
     // us to look at. If we decide to copy it into the cache, then we'll update m->NextCacheCheck accordingly.
     pktrdlength           = (mDNSu16)((mDNSu16)ptr[8] <<  8 | ptr[9]);
diff --git a/mDNSResponder/mDNSCore/DNSCommon.h b/mDNSResponder/mDNSCore/DNSCommon.h
index b100a400..48dfe102 100644
--- a/mDNSResponder/mDNSCore/DNSCommon.h
+++ b/mDNSResponder/mDNSCore/DNSCommon.h
@@ -110,6 +110,13 @@ extern mDNSu32 mDNSRandom(mDNSu32 max);     // Returns pseudo-random result from
 #define mDNSIsUpperCase(X) ((X) >= 'A' && (X) <= 'Z')
 #define mDNSIsLowerCase(X) ((X) >= 'a' && (X) <= 'z')
 #define mDNSIsLetter(X)    (mDNSIsUpperCase(X) || mDNSIsLowerCase(X))
+    
+// We believe we have adequate safeguards to protect against cache poisoning.
+// In the event that someone does find a workable cache poisoning attack, we want to limit the lifetime of the poisoned entry.
+// We set the maximum allowable TTL to one hour.
+// With the 25% correction factor to avoid the DNS Zeno's paradox bug, that gives us an actual maximum lifetime of 75 minutes.
+
+#define mDNSMaximumTTLSeconds (mDNSu32)3600
 
 #define mDNSValidHostChar(X, notfirst, notlast) (mDNSIsLetter(X) || mDNSIsDigit(X) || ((notfirst) && (notlast) && (X) == '-') )
 
diff --git a/mDNSResponder/mDNSCore/mDNS.c b/mDNSResponder/mDNSCore/mDNS.c
index 10504d09..9e1ac506 100755
--- a/mDNSResponder/mDNSCore/mDNS.c
+++ b/mDNSResponder/mDNSCore/mDNS.c
@@ -7171,7 +7171,7 @@ mDNSlocal mDNSu8 *GenerateUnicastResponse(const DNSMessage *const query, const m
     const mDNSu8    *const limit     = response->data + sizeof(response->data);
     const mDNSu8    *ptr             = query->data;
     AuthRecord  *rr;
-    mDNSu32 maxttl = 0x70000000;
+    mDNSu32 maxttl = mDNSMaximumTTLSeconds;
     int i;
 
     // Initialize the response fields so we can answer the questions
@@ -8075,19 +8075,25 @@ struct UDPSocket_struct
     mDNSIPPort port; // MUST BE FIRST FIELD -- mDNSCoreReceive expects every UDPSocket_struct to begin with mDNSIPPort port
 };
 
-mDNSlocal DNSQuestion *ExpectingUnicastResponseForQuestion(const mDNS *const m, const mDNSIPPort port, const mDNSOpaque16 id, const DNSQuestion *const question, mDNSBool tcp)
+mDNSlocal DNSQuestion *ExpectingUnicastResponseForQuestion(const mDNS *const m, const mDNSIPPort port, const mDNSOpaque16 id, const DNSQuestion *const question, mDNSBool tcp, DNSQuestion ** suspiciousQ)
 {
     DNSQuestion *q;
     for (q = m->Questions; q; q=q->next)
     {
         if (!tcp && !q->LocalSocket) continue;
-        if (mDNSSameIPPort(tcp ? q->tcpSrcPort : q->LocalSocket->port, port)     &&
-            mDNSSameOpaque16(q->TargetQID,         id)       &&
+        if (mDNSSameIPPort(tcp ? q->tcpSrcPort : q->LocalSocket->port, port)       &&
             q->qtype                  == question->qtype     &&
             q->qclass                 == question->qclass    &&
             q->qnamehash              == question->qnamehash &&
             SameDomainName(&q->qname, &question->qname))
-            return(q);
+        {
+            if (mDNSSameOpaque16(q->TargetQID, id)) return(q);
+            else
+            {
+                if (!tcp && suspiciousQ) *suspiciousQ = q;
+                return(mDNSNULL);
+            }
+        }
     }
     return(mDNSNULL);
 }
@@ -8413,7 +8419,7 @@ mDNSlocal void mDNSCoreReceiveNoDNSSECAnswers(mDNS *const m, const DNSMessage *c
         DNSQuestion pktq;
         DNSQuestion *qptr = mDNSNULL;
         ptr = getQuestion(response, ptr, end, InterfaceID, &pktq);
-        if (ptr && (qptr = ExpectingUnicastResponseForQuestion(m, dstport, response->h.id, &pktq, !dstaddr)) &&
+        if (ptr && (qptr = ExpectingUnicastResponseForQuestion(m, dstport, response->h.id, &pktq, !dstaddr, mDNSNULL)) &&
             qptr->ValidatingResponse)
         {
             DNSQuestion *next, *q;
@@ -8457,7 +8463,7 @@ mDNSlocal void mDNSCoreReceiveNoUnicastAnswers(mDNS *const m, const DNSMessage *
         DNSQuestion q;
         DNSQuestion *qptr = mDNSNULL;
         ptr = getQuestion(response, ptr, end, InterfaceID, &q);
-        if (ptr && (qptr = ExpectingUnicastResponseForQuestion(m, dstport, response->h.id, &q, !dstaddr)))
+        if (ptr && (qptr = ExpectingUnicastResponseForQuestion(m, dstport, response->h.id, &q, !dstaddr, mDNSNULL)))
         {
             CacheRecord *rr, *neg = mDNSNULL;
             CacheGroup *cg = CacheGroupForName(m, q.qnamehash, &q.qname);
@@ -9037,9 +9043,9 @@ mDNSlocal void mDNSCoreReceiveResponse(mDNS *const m,
         // packet number, then we deduce they are old and delete them
         for (i = 0; i < response->h.numQuestions && ptr && ptr < end; i++)
         {
-            DNSQuestion q, *qptr = mDNSNULL;
+            DNSQuestion q, *qptr = mDNSNULL, *suspiciousForQ = mDNSNULL;
             ptr = getQuestion(response, ptr, end, InterfaceID, &q);
-            if (ptr && (qptr = ExpectingUnicastResponseForQuestion(m, dstport, response->h.id, &q, !dstaddr)))
+            if (ptr && (qptr = ExpectingUnicastResponseForQuestion(m, dstport, response->h.id, &q, !dstaddr, &suspiciousForQ)))
             {
                 if (!failure)
                 {
@@ -9102,6 +9108,15 @@ mDNSlocal void mDNSCoreReceiveResponse(mDNS *const m,
                     returnEarly = mDNStrue;
                 }
             }
+            else if (!InterfaceID && suspiciousForQ)
+            {
+                // If a response is suspicious for a question, then reissue the question via TCP
+                LogInfo("mDNSCoreReceiveResponse: Server %p responded suspiciously to query %##s (%s) qID %d != rID: %d",
+                        suspiciousForQ->qDNSServer, q.qname.c, DNSTypeName(q.qtype),
+                        mDNSVal16(suspiciousForQ->TargetQID), mDNSVal16(response->h.id));
+                uDNS_RestartQuestionAsTCP(m, suspiciousForQ, srcaddr, srcport);
+                return;
+            }
         }
         if (returnEarly)
         {
diff --git a/mDNSResponder/mDNSCore/uDNS.c b/mDNSResponder/mDNSCore/uDNS.c
index 2d6d14e9..1f9b1543 100755
--- a/mDNSResponder/mDNSCore/uDNS.c
+++ b/mDNSResponder/mDNSCore/uDNS.c
@@ -3925,14 +3925,7 @@ mDNSexport void uDNS_ReceiveMsg(mDNS *const m, DNSMessage *const msg, const mDNS
             if (msg->h.flags.b[0] & kDNSFlag0_TC && mDNSSameOpaque16(qptr->TargetQID, msg->h.id) && m->timenow - qptr->LastQTime < RESPONSE_WINDOW)
             {
                 if (!srcaddr) LogMsg("uDNS_ReceiveMsg: TCP DNS response had TC bit set: ignoring");
-                else
-                {
-                    // Don't reuse TCP connections. We might have failed over to a different DNS server
-                    // while the first TCP connection is in progress. We need a new TCP connection to the
-                    // new DNS server. So, always try to establish a new connection.
-                    if (qptr->tcp) { DisposeTCPConn(qptr->tcp); qptr->tcp = mDNSNULL; }
-                    qptr->tcp = MakeTCPConn(m, mDNSNULL, mDNSNULL, kTCPSocketFlags_Zero, srcaddr, srcport, mDNSNULL, qptr, mDNSNULL);
-                }
+                else          uDNS_RestartQuestionAsTCP(m, qptr, srcaddr, srcport);
             }
     }
 
@@ -5745,6 +5738,15 @@ mDNSexport domainname  *uDNS_GetNextSearchDomain(mDNSInterfaceID InterfaceID, mD
     return mDNSNULL;
 }
 
+mDNSexport void uDNS_RestartQuestionAsTCP(mDNS *m, DNSQuestion *const q, const mDNSAddr *const srcaddr, const mDNSIPPort srcport)
+{
+    // Don't reuse TCP connections. We might have failed over to a different DNS server
+    // while the first TCP connection is in progress. We need a new TCP connection to the
+    // new DNS server. So, always try to establish a new connection.
+    if (q->tcp) { DisposeTCPConn(q->tcp); q->tcp = mDNSNULL; }
+    q->tcp = MakeTCPConn(m, mDNSNULL, mDNSNULL, kTCPSocketFlags_Zero, srcaddr, srcport, mDNSNULL, q, mDNSNULL);
+}
+
 mDNSlocal void FlushAddressCacheRecords(mDNS *const m)
 {
     mDNSu32 slot;
diff --git a/mDNSResponder/mDNSCore/uDNS.h b/mDNSResponder/mDNSCore/uDNS.h
index 27b7acee..d3141dd5 100755
--- a/mDNSResponder/mDNSCore/uDNS.h
+++ b/mDNSResponder/mDNSCore/uDNS.h
@@ -129,6 +129,8 @@ extern void uDNS_SetupWABQueries(mDNS *const m);
 extern void uDNS_StartWABQueries(mDNS *const m, int queryType);
 extern void uDNS_StopWABQueries(mDNS *const m, int queryType);
 extern domainname      *uDNS_GetNextSearchDomain(mDNSInterfaceID InterfaceID, mDNSs8 *searchIndex, mDNSBool ignoreDotLocal);
+    
+extern void uDNS_RestartQuestionAsTCP(mDNS *m, DNSQuestion *const q, const mDNSAddr *const srcaddr, const mDNSIPPort srcport);
 
 typedef enum
 {
diff --git a/mDNSResponder/mDNSShared/dns_sd.h b/mDNSResponder/mDNSShared/dns_sd.h
index 2f530917..3495c6e6 100644
--- a/mDNSResponder/mDNSShared/dns_sd.h
+++ b/mDNSResponder/mDNSShared/dns_sd.h
@@ -66,7 +66,7 @@
  */
 
 #ifndef _DNS_SD_H
-#define _DNS_SD_H 8803002
+#define _DNS_SD_H 8804001
 
 #ifdef  __cplusplus
 extern "C" {
-- 
2.26.2



More information about the devel mailing list