Skip to content

Commit 867fad8

Browse files
os-dlgao4
authored andcommitted
MdeModulePkg: Fix Image Memory Protection Applying
Commit 5ccb5ff updated the image memory protection code to set the protection attributes through the GCD instead of directly to the page table. However, this code had an implicit assumption that each base address passed to it was the beginning of a GCD descriptor. On the virtual platforms tested, this was the case. However, on a physical platform, a scenario was encountered where the base address was not the beginning of a GCD descriptor, thus causing memory attributes to be applied incorrectly. This assumption does not need to be made and this patch updates the code to handle the case where the base address is not the beginning of a GCD descriptor. Signed-off-by: Oliver Smith-Denny <[email protected]>
1 parent 28653a1 commit 867fad8

File tree

1 file changed

+13
-8
lines changed

1 file changed

+13
-8
lines changed

MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c

+13-8
Original file line numberDiff line numberDiff line change
@@ -196,8 +196,11 @@ SetUefiImageMemoryAttributes (
196196
UINT64 FinalAttributes;
197197
UINT64 CurrentAddress;
198198
UINT64 CurrentLength;
199+
UINT64 ImageEnd;
200+
UINT64 DescEnd;
199201

200202
CurrentAddress = BaseAddress;
203+
ImageEnd = BaseAddress + Length;
201204

202205
// we loop here because we may have multiple memory space descriptors that overlap the requested range
203206
// this will definitely be the case for unprotecting an image, because that calls this function for the entire image,
@@ -216,11 +219,14 @@ SetUefiImageMemoryAttributes (
216219
return;
217220
}
218221

219-
// ensure that we only change the attributes for the range that we are interested in, not the entire descriptor
220-
if (BaseAddress + Length > CurrentAddress + Descriptor.Length) {
221-
CurrentLength = Descriptor.Length;
222+
DescEnd = Descriptor.BaseAddress + Descriptor.Length;
223+
224+
// ensure that we only change the attributes for the range that we are interested in, not the entire descriptor, we
225+
// may also be in the middle of a descriptor, so ensure our length is not larger than the descriptor length
226+
if (ImageEnd > DescEnd) {
227+
CurrentLength = DescEnd - CurrentAddress;
222228
} else {
223-
CurrentLength = BaseAddress + Length - CurrentAddress;
229+
CurrentLength = ImageEnd - CurrentAddress;
224230
}
225231

226232
// Preserve the existing caching and virtual attributes, but remove the hardware access bits
@@ -291,10 +297,9 @@ SetUefiImageMemoryAttributes (
291297
}
292298
}
293299

294-
// we have CurrentLength, also, but that is just to handle the final descriptor case where we might take only
295-
// part of a descriptor, so we can use Descriptor.Length here to move to the next descriptor, which for the final
296-
// descriptor will exit the loop, regardless of whether we truncated or not
297-
CurrentAddress += Descriptor.Length;
300+
// we may have started in the middle of a descriptor, so we need to move to the beginning of the next descriptor,
301+
// or the end of the image, whichever is smaller
302+
CurrentAddress += CurrentLength;
298303
}
299304
}
300305

0 commit comments

Comments
 (0)