summaryrefslogtreecommitdiffstats
path: root/NetworkPkg
diff options
context:
space:
mode:
Diffstat (limited to 'NetworkPkg')
-rw-r--r--NetworkPkg/DnsDxe/DnsImpl.c77
-rw-r--r--NetworkPkg/DnsDxe/DnsImpl.h2
2 files changed, 69 insertions, 10 deletions
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
@@ -1192,21 +1207,37 @@ ParseDnsResponse (
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;
+
//
- // Get query section
+ // Check whether the remaining packet length is avaiable or not.
//
- QuerySection = (DNS_QUERY_SECTION *) (QueryName + AsciiStrLen (QueryName) + 1);
- QuerySection->Type = NTOHS (QuerySection->Type);
- QuerySection->Class = NTOHS (QuerySection->Class);
+ if (RemainingLength <= QueryNameLen + sizeof (DNS_QUERY_SECTION)) {
+ *Completed = FALSE;
+ return EFI_ABORTED;
+ } else {
+ RemainingLength -= (QueryNameLen + sizeof (DNS_QUERY_SECTION));
+ }
//
- // Get Answer name
+ // Get query section
//
- AnswerName = (CHAR8 *) QuerySection + sizeof (*QuerySection);
+ QuerySection = (DNS_QUERY_SECTION *) (QueryName + QueryNameLen);
+ QuerySection->Type = NTOHS (QuerySection->Type);
+ QuerySection->Class = NTOHS (QuerySection->Class);
OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
@@ -1342,10 +1373,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.
//
if ((*(UINT8 *) AnswerName & 0xC0) != 0xC0) {
@@ -1363,6 +1410,17 @@ ParseDnsResponse (
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.
//
if (Instance->Service->IpVersion == IP_VERSION_4 && Dns4TokenEntry->GeneralLookUp) {
@@ -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
);