From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from linux.microsoft.com (linux.microsoft.com [13.77.154.182]) by mx.groups.io with SMTP id smtpd.web10.12289.1688608665977771861 for ; Wed, 05 Jul 2023 18:57:46 -0700 Authentication-Results: mx.groups.io; dkim=fail reason="body hash did not verify" header.i=@linux.microsoft.com header.s=default header.b=piCTf41t; spf=pass (domain: linux.microsoft.com, ip: 13.77.154.182, mailfrom: mikuback@linux.microsoft.com) Received: from localhost.localdomain (unknown [47.201.8.94]) by linux.microsoft.com (Postfix) with ESMTPSA id ED50920AECAD; Wed, 5 Jul 2023 18:57:43 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com ED50920AECAD DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1688608664; bh=DwDnVfPYBrzEjTGvyZVLPgjxsvElzBDmrtHDvuZHmMk=; h=From:To:Cc:Subject:Date:From; b=piCTf41tzkauAA7qvPDuH5BR3+bkItskhtdJxJE/gTTCsmbNUnE25wBt243kxfj76 VqVAXU70e3SPiMHiXO2PetcKLmuxzaylVVE6h4fJtB/DiwkKP5vHWiokrFQLPXSQbj 2oH36Jv2HzwS3u4zwaoMaoYX8yK6LQbKes7RvJxw= From: "Michael Kubacki" To: devel@edk2.groups.io Cc: Chasel Chiu , Nate DeSimone , Isaac Oram , Liming Gao , Eric Dong , Ken Lautner Subject: [edk2-platforms][PATCH v1 1/1] MinPlatformPkg: Add Mem Type Info variable validity checks Date: Wed, 5 Jul 2023 21:57:26 -0400 Message-ID: <20230706015726.269-1-mikuback@linux.microsoft.com> X-Mailer: git-send-email 2.41.0.windows.1 MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable From: Michael Kubacki Adds some sanity checks around the Memory Type Information data restored from the `EFI_MEMORY_TYPE_INFORMATION_VARIABLE_NAME` UEFI variable. This is particularly useful when the structures that the data was saved against have changed in the latest firmware image. For example, `EfiUnacceptedMemoryType` was added to `EFI_MEMORY_TYPE` in edk2 commit `502c01c`. This incremented `EfiMaxMemoryType` by `1`. That change was first released in the `edk2-stable202211` stable tag. Firmware performing an update across those stable tags may encounter issues depending on code implementation for handling `EfiMaxMemoryType` as a terminating loop value. This change checks the size and max memory type saved in the UEFI variable to determine whether it is better to start from the defaults and rebuild the UEFI variable data on the current boot. Cc: Chasel Chiu Cc: Nate DeSimone Cc: Isaac Oram Cc: Liming Gao Cc: Eric Dong Co-authored-by: Ken Lautner Signed-off-by: Michael Kubacki --- Platform/Intel/MinPlatformPkg/PlatformInit/PlatformInitPei/PlatformInitP= reMem.c | 32 +++++++++++++++++--- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/Platform/Intel/MinPlatformPkg/PlatformInit/PlatformInitPei/P= latformInitPreMem.c b/Platform/Intel/MinPlatformPkg/PlatformInit/Platform= InitPei/PlatformInitPreMem.c index d8c96b52f4b3..bc97711a02f6 100644 --- a/Platform/Intel/MinPlatformPkg/PlatformInit/PlatformInitPei/Platform= InitPreMem.c +++ b/Platform/Intel/MinPlatformPkg/PlatformInit/PlatformInitPei/Platform= InitPreMem.c @@ -164,18 +164,22 @@ BuildMemoryTypeInformation ( EFI_STATUS Status; EFI_PEI_READ_ONLY_VARIABLE2_PPI *VariableServices; UINTN DataSize; + UINTN Index; EFI_MEMORY_TYPE_INFORMATION MemoryData[EfiMaxMemoryType + 1]; =20 // // Locate system configuration variable // - Status =3D PeiServicesLocatePpi( + Status =3D PeiServicesLocatePpi ( &gEfiPeiReadOnlyVariable2PpiGuid, // GUID 0, // INSTANCE NULL, // EFI_PEI_PPI_DESCRIPTOR (VOID **) &VariableServices // PPI ); - ASSERT_EFI_ERROR(Status); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return; + } =20 DataSize =3D sizeof (MemoryData); Status =3D VariableServices->GetVariable ( @@ -186,9 +190,29 @@ BuildMemoryTypeInformation ( &DataSize, &MemoryData ); - if (EFI_ERROR(Status)) { + if (!EFI_ERROR (Status)) { + if (DataSize % sizeof (EFI_MEMORY_TYPE_INFORMATION) !=3D 0) { + DEBUG ((DEBUG_ERROR, "The UEFI Memory Type Information variable si= ze is inconsistent with this build.\n")); + Status =3D EFI_COMPROMISED_DATA; + } else { + // Loop through all except the last one and make sure it seems rea= sonable + for (Index =3D 0; Index < ((DataSize / sizeof (EFI_MEMORY_TYPE_INF= ORMATION)) - 1); Index++) { + if (MemoryData[Index].Type >=3D EfiMaxMemoryType) { + DEBUG ((DEBUG_ERROR, "UEFI Memory Type Information variable ha= s an invalid memory type.\n")); + Status =3D EFI_COMPROMISED_DATA; + } + } + // The last entry must be MaxMemoryType with size 0 + if ((MemoryData[Index].Type !=3D EfiMaxMemoryType) || (MemoryData[= Index].NumberOfPages !=3D 0)) { + DEBUG ((DEBUG_ERROR, "UEFI Memory Type Information variable cont= ains an invalid last entry.\n")); + Status =3D EFI_COMPROMISED_DATA; + } + } + } + + if (EFI_ERROR (Status)) { DataSize =3D sizeof (mDefaultMemoryTypeInformation); - CopyMem(MemoryData, mDefaultMemoryTypeInformation, DataSize); + CopyMem (MemoryData, mDefaultMemoryTypeInformation, DataSize); } =20 /// --=20 2.41.0.windows.1