From bf334513b3eb02ef98e5b38e0b7b5d7408492fdd Mon Sep 17 00:00:00 2001 From: Ray Ni Date: Thu, 14 Jul 2022 16:03:11 +0800 Subject: CpuPageTableLib: Fix a bug when a bit is 1 in Attribute, 0 in Mask To reproduce the issue: UINTN PageTable; VOID *Buffer; UINTN PageTableBufferSize; IA32_MAP_ATTRIBUTE Attribute; IA32_MAP_ATTRIBUTE Mask; RETURN_STATUS Status; Attribute.Uint64 = 0; Mask.Uint64 = 0; PageTableBufferSize = 0; PageTable = 0; Buffer = NULL; Attribute.Bits.Present = 1; Attribute.Bits.Nx = 1; Mask.Bits.Present = 1; Mask.Uint64 = MAX_UINT64; // // Create page table to cover [0, 10M) // Status = PageTableMap ( &PageTable, PagingMode, Buffer, &PageTableBufferSize, 0, (UINT64)SIZE_2MB * 5, &Attribute, &Mask ); ASSERT (Status == RETURN_BUFFER_TOO_SMALL); Buffer = AllocatePages (EFI_SIZE_TO_PAGES (PageTableBufferSize)); Status = PageTableMap ( &PageTable, PagingMode, Buffer, &PageTableBufferSize, 0, (UINT64)SIZE_2MB * 5, &Attribute, &Mask ); ASSERT (Status == RETURN_SUCCESS); // // Change the mapping for [0, 4KB) // No change actually. Just clear Nx bit in Mask. // Mask.Bits.Nx = 0; PageTableBufferSize = 0; Status = PageTableMap ( &PageTable, PagingMode, NULL, &PageTableBufferSize, 0, (UINT64)SIZE_4KB, &Attribute, &Mask ); ASSERT (Status == RETURN_SUCCESS); // FAIL!! The root cause is when comparing the existing mapping attributes against the requested one, Mask is not used but it should be used. Signed-off-by: Zhiguang Liu Reviewed-by: Ray Ni Reviewed-by: Eric Dong --- UefiCpuPkg/Library/CpuPageTableLib/CpuPageTableMap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'UefiCpuPkg/Library/CpuPageTableLib/CpuPageTableMap.c') diff --git a/UefiCpuPkg/Library/CpuPageTableLib/CpuPageTableMap.c b/UefiCpuPkg/Library/CpuPageTableLib/CpuPageTableMap.c index a0e1309462..e23158c17e 100644 --- a/UefiCpuPkg/Library/CpuPageTableLib/CpuPageTableMap.c +++ b/UefiCpuPkg/Library/CpuPageTableLib/CpuPageTableMap.c @@ -308,7 +308,7 @@ PageTableLibMapInLevel ( // PleBAttribute.Uint64 = PageTableLibGetPleBMapAttribute (&ParentPagingEntry->PleB, &NopAttribute); if ((IA32_MAP_ATTRIBUTE_ATTRIBUTES (&PleBAttribute) & IA32_MAP_ATTRIBUTE_ATTRIBUTES (Mask)) - == IA32_MAP_ATTRIBUTE_ATTRIBUTES (Attribute)) + == (IA32_MAP_ATTRIBUTE_ATTRIBUTES (Attribute) & IA32_MAP_ATTRIBUTE_ATTRIBUTES (Mask))) { // // This function is called when the memory length is less than the region length of the parent level. -- cgit v1.2.3