\r
@param Instance The DNS instance\r
@param RxString Received buffer.\r
+ @param Length Received buffer length.\r
@param Completed Flag to indicate that Dns response is valid.\r
\r
@retval EFI_SUCCESS Parse Dns Response successfully.\r
ParseDnsResponse (\r
IN OUT DNS_INSTANCE *Instance,\r
IN UINT8 *RxString,\r
+ IN UINT32 Length,\r
OUT BOOLEAN *Completed\r
)\r
{\r
DNS_HEADER *DnsHeader;\r
\r
CHAR8 *QueryName;\r
+ UINT32 QueryNameLen;\r
DNS_QUERY_SECTION *QuerySection;\r
\r
CHAR8 *AnswerName;\r
DNS6_RESOURCE_RECORD *Dns6RR;\r
\r
EFI_STATUS Status;\r
+ UINT32 RemainingLength;\r
\r
EFI_TPL OldTpl;\r
\r
\r
*Completed = TRUE;\r
Status = EFI_SUCCESS;\r
+ RemainingLength = Length;\r
+\r
+ //\r
+ // Check whether the remaining packet length is avaiable or not.\r
+ //\r
+ if (RemainingLength <= sizeof (DNS_HEADER)) {\r
+ *Completed = FALSE;\r
+ return EFI_ABORTED;\r
+ } else {\r
+ RemainingLength -= sizeof (DNS_HEADER);\r
+ }\r
\r
//\r
// Get header\r
DnsHeader->AuthorityNum = NTOHS (DnsHeader->AuthorityNum);\r
DnsHeader->AditionalNum = NTOHS (DnsHeader->AditionalNum);\r
\r
+ //\r
+ // There is always one QuestionsNum in DNS message. The capability to handle more\r
+ // than one requires to redesign the message format. Currently, it's not supported.\r
+ //\r
+ if (DnsHeader->QuestionsNum > 1) {\r
+ *Completed = FALSE;\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
//\r
// Get Query name\r
//\r
QueryName = (CHAR8 *) (RxString + sizeof (*DnsHeader));\r
\r
+ QueryNameLen = (UINT32) AsciiStrLen (QueryName) + 1;\r
+\r
//\r
- // Get query section\r
+ // Check whether the remaining packet length is avaiable or not.\r
//\r
- QuerySection = (DNS_QUERY_SECTION *) (QueryName + AsciiStrLen (QueryName) + 1);\r
- QuerySection->Type = NTOHS (QuerySection->Type);\r
- QuerySection->Class = NTOHS (QuerySection->Class);\r
+ if (RemainingLength <= QueryNameLen + sizeof (DNS_QUERY_SECTION)) {\r
+ *Completed = FALSE;\r
+ return EFI_ABORTED;\r
+ } else {\r
+ RemainingLength -= (QueryNameLen + sizeof (DNS_QUERY_SECTION));\r
+ }\r
\r
//\r
- // Get Answer name\r
+ // Get query section\r
//\r
- AnswerName = (CHAR8 *) QuerySection + sizeof (*QuerySection);\r
+ QuerySection = (DNS_QUERY_SECTION *) (QueryName + QueryNameLen);\r
+ QuerySection->Type = NTOHS (QuerySection->Type);\r
+ QuerySection->Class = NTOHS (QuerySection->Class);\r
\r
OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
\r
\r
Status = EFI_NOT_FOUND;\r
\r
+ //\r
+ // Get Answer name\r
+ //\r
+ AnswerName = (CHAR8 *) QuerySection + sizeof (*QuerySection);\r
+\r
//\r
// Processing AnswerSection.\r
//\r
while (AnswerSectionNum < DnsHeader->AnswersNum) {\r
+ //\r
+ // Check whether the remaining packet length is avaiable or not.\r
+ //\r
+ if (RemainingLength <= sizeof (UINT16) + sizeof (DNS_ANSWER_SECTION)) {\r
+ *Completed = FALSE;\r
+ Status = EFI_ABORTED;\r
+ goto ON_EXIT;\r
+ } else {\r
+ RemainingLength -= (sizeof (UINT16) + sizeof (DNS_ANSWER_SECTION));\r
+ }\r
+\r
//\r
// Answer name should be PTR, else EFI_UNSUPPORTED returned.\r
//\r
AnswerSection->Ttl = NTOHL (AnswerSection->Ttl);\r
AnswerSection->DataLength = NTOHS (AnswerSection->DataLength);\r
\r
+ //\r
+ // Check whether the remaining packet length is avaiable or not.\r
+ //\r
+ if (RemainingLength < AnswerSection->DataLength) {\r
+ *Completed = FALSE;\r
+ Status = EFI_ABORTED;\r
+ goto ON_EXIT;\r
+ } else {\r
+ RemainingLength -= AnswerSection->DataLength;\r
+ }\r
+\r
//\r
// Check whether it's the GeneralLookUp querying.\r
//\r
DNS_INSTANCE *Instance;\r
\r
UINT8 *RcvString;\r
+ UINT32 Len;\r
\r
BOOLEAN Completed;\r
\r
\r
ASSERT (Packet != NULL);\r
\r
- if (Packet->TotalSize <= sizeof (DNS_HEADER)) {\r
- goto ON_EXIT;\r
- }\r
+ Len = Packet->TotalSize;\r
\r
RcvString = NetbufGetByte (Packet, 0, NULL);\r
ASSERT (RcvString != NULL);\r
//\r
// Parse Dns Response\r
//\r
- ParseDnsResponse (Instance, RcvString, &Completed);\r
+ ParseDnsResponse (Instance, RcvString, Len, &Completed);\r
\r
ON_EXIT:\r
\r