]> git.saurik.com Git - apple/mdnsresponder.git/commitdiff
mDNSResponder-878.240.1.tar.gz macos-10143 v878.240.1
authorApple <opensource@apple.com>
Mon, 17 Jun 2019 20:59:16 +0000 (20:59 +0000)
committerApple <opensource@apple.com>
Mon, 17 Jun 2019 20:59:16 +0000 (20:59 +0000)
Makefile
mDNSCore/DNSCommon.c
mDNSCore/DNSCommon.h
mDNSCore/mDNS.c
mDNSCore/uDNS.c
mDNSCore/uDNS.h
mDNSShared/dns_sd.h

index 8b97eaccbe6f053a5af26d31ff7e09b600ca7ce6..78adbd5ec5afe38200a1658e012bf575a03c7114 100644 (file)
--- a/Makefile
+++ b/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)),)
index a249b967a96e14e9ff392721009c88c6e9b4961a..f3150762227df8250094943ff2c9a9da5575bde6 100644 (file)
@@ -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]);
index b100a400f87d9c4c57c43ebbe38f117e2945a991..48dfe1020a2ef2f2bc8f527f078af286d3409582 100644 (file)
@@ -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) == '-') )
 
index 10504d0918d691c6118b412fff72ba5f430e3e40..9e1ac506dcb3270b6c45558985d7e090bf182ac9 100755 (executable)
@@ -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)
         {
index 2d6d14e96a48a107de8d0f2bd9046bd3e0605a48..1f9b154325c012306c171b1ae81df7b94c12ae0c 100755 (executable)
@@ -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;
index 27b7acee737f2bfd966fd0d2db8a386255650faa..d3141dd5b25943db7d5e4d8c19c4ced541b6eb52 100755 (executable)
@@ -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
 {
index 2f530917506db56e432ef59ebb9a021a44375bb7..3495c6e6da2e616249063a57c3d78e0dd54bbbd8 100644 (file)
@@ -66,7 +66,7 @@
  */
 
 #ifndef _DNS_SD_H
-#define _DNS_SD_H 8803002
+#define _DNS_SD_H 8804001
 
 #ifdef  __cplusplus
 extern "C" {