diff --git a/NetworkPkg/DnsDxe/DnsImpl.c b/NetworkPkg/DnsDxe/DnsImpl.c index 89ea755cb2..26a718987c 100644 --- a/NetworkPkg/DnsDxe/DnsImpl.c +++ b/NetworkPkg/DnsDxe/DnsImpl.c @@ -1114,6 +1114,7 @@ IsValidDnsResponse ( @param Instance The DNS instance @param RxString Received buffer. + @param Length Received buffer length. @param Completed Flag to indicate that Dns response is valid. @retval EFI_SUCCESS Parse Dns Response successfully. @@ -1124,12 +1125,14 @@ EFI_STATUS ParseDnsResponse ( IN OUT DNS_INSTANCE *Instance, IN UINT8 *RxString, + IN UINT32 Length, OUT BOOLEAN *Completed ) { DNS_HEADER *DnsHeader; CHAR8 *QueryName; + UINT32 QueryNameLen; DNS_QUERY_SECTION *QuerySection; CHAR8 *AnswerName; @@ -1155,6 +1158,7 @@ ParseDnsResponse ( DNS6_RESOURCE_RECORD *Dns6RR; EFI_STATUS Status; + UINT32 RemainingLength; EFI_TPL OldTpl; @@ -1178,6 +1182,17 @@ ParseDnsResponse ( *Completed = TRUE; Status = EFI_SUCCESS; + RemainingLength = Length; + + // + // Check whether the remaining packet length is avaiable or not. + // + if (RemainingLength <= sizeof (DNS_HEADER)) { + *Completed = FALSE; + return EFI_ABORTED; + } else { + RemainingLength -= sizeof (DNS_HEADER); + } // // Get header @@ -1191,23 +1206,39 @@ ParseDnsResponse ( DnsHeader->AuthorityNum = NTOHS (DnsHeader->AuthorityNum); DnsHeader->AditionalNum = NTOHS (DnsHeader->AditionalNum); + // + // There is always one QuestionsNum in DNS message. The capability to handle more + // than one requires to redesign the message format. Currently, it's not supported. + // + if (DnsHeader->QuestionsNum > 1) { + *Completed = FALSE; + return EFI_UNSUPPORTED; + } + // // Get Query name // QueryName = (CHAR8 *) (RxString + sizeof (*DnsHeader)); + QueryNameLen = (UINT32) AsciiStrLen (QueryName) + 1; + + // + // Check whether the remaining packet length is avaiable or not. + // + if (RemainingLength <= QueryNameLen + sizeof (DNS_QUERY_SECTION)) { + *Completed = FALSE; + return EFI_ABORTED; + } else { + RemainingLength -= (QueryNameLen + sizeof (DNS_QUERY_SECTION)); + } + // // Get query section // - QuerySection = (DNS_QUERY_SECTION *) (QueryName + AsciiStrLen (QueryName) + 1); + QuerySection = (DNS_QUERY_SECTION *) (QueryName + QueryNameLen); QuerySection->Type = NTOHS (QuerySection->Type); QuerySection->Class = NTOHS (QuerySection->Class); - // - // Get Answer name - // - AnswerName = (CHAR8 *) QuerySection + sizeof (*QuerySection); - OldTpl = gBS->RaiseTPL (TPL_CALLBACK); // @@ -1341,10 +1372,26 @@ ParseDnsResponse ( Status = EFI_NOT_FOUND; + // + // Get Answer name + // + AnswerName = (CHAR8 *) QuerySection + sizeof (*QuerySection); + // // Processing AnswerSection. // while (AnswerSectionNum < DnsHeader->AnswersNum) { + // + // Check whether the remaining packet length is avaiable or not. + // + if (RemainingLength <= sizeof (UINT16) + sizeof (DNS_ANSWER_SECTION)) { + *Completed = FALSE; + Status = EFI_ABORTED; + goto ON_EXIT; + } else { + RemainingLength -= (sizeof (UINT16) + sizeof (DNS_ANSWER_SECTION)); + } + // // Answer name should be PTR, else EFI_UNSUPPORTED returned. // @@ -1362,6 +1409,17 @@ ParseDnsResponse ( AnswerSection->Ttl = NTOHL (AnswerSection->Ttl); AnswerSection->DataLength = NTOHS (AnswerSection->DataLength); + // + // Check whether the remaining packet length is avaiable or not. + // + if (RemainingLength < AnswerSection->DataLength) { + *Completed = FALSE; + Status = EFI_ABORTED; + goto ON_EXIT; + } else { + RemainingLength -= AnswerSection->DataLength; + } + // // Check whether it's the GeneralLookUp querying. // @@ -1733,6 +1791,7 @@ DnsOnPacketReceived ( DNS_INSTANCE *Instance; UINT8 *RcvString; + UINT32 Len; BOOLEAN Completed; @@ -1748,9 +1807,7 @@ DnsOnPacketReceived ( ASSERT (Packet != NULL); - if (Packet->TotalSize <= sizeof (DNS_HEADER)) { - goto ON_EXIT; - } + Len = Packet->TotalSize; RcvString = NetbufGetByte (Packet, 0, NULL); ASSERT (RcvString != NULL); @@ -1758,7 +1815,7 @@ DnsOnPacketReceived ( // // Parse Dns Response // - ParseDnsResponse (Instance, RcvString, &Completed); + ParseDnsResponse (Instance, RcvString, Len, &Completed); ON_EXIT: diff --git a/NetworkPkg/DnsDxe/DnsImpl.h b/NetworkPkg/DnsDxe/DnsImpl.h index 90dc054903..45feca2160 100644 --- a/NetworkPkg/DnsDxe/DnsImpl.h +++ b/NetworkPkg/DnsDxe/DnsImpl.h @@ -583,6 +583,7 @@ IsValidDnsResponse ( @param Instance The DNS instance @param RxString Received buffer. + @param Length Received buffer length. @param Completed Flag to indicate that Dns response is valid. @retval EFI_SUCCESS Parse Dns Response successfully. @@ -593,6 +594,7 @@ EFI_STATUS ParseDnsResponse ( IN OUT DNS_INSTANCE *Instance, IN UINT8 *RxString, + IN UINT32 Length, OUT BOOLEAN *Completed );