TianoCore EDK2 master
Loading...
Searching...
No Matches
Defer3rdPartyImageLoad.c
Go to the documentation of this file.
1
9
10//
11// The structure to save the deferred 3rd party image information.
12//
13typedef struct {
14 EFI_DEVICE_PATH_PROTOCOL *ImageDevicePath;
15 BOOLEAN BootOption;
16 BOOLEAN Loaded;
18
19//
20// The table to save the deferred 3rd party image item.
21//
22typedef struct {
26
27BOOLEAN mImageLoadedAfterEndOfDxe = FALSE;
28BOOLEAN mEndOfDxe = FALSE;
29DEFERRED_3RD_PARTY_IMAGE_TABLE mDeferred3rdPartyImage = {
30 0, // Deferred image count
31 NULL // The deferred image info
32};
33
34EFI_DEFERRED_IMAGE_LOAD_PROTOCOL mDeferredImageLoad = {
36};
37
47BOOLEAN
50 )
51{
52 EFI_STATUS Status;
53 EFI_HANDLE DeviceHandle;
54 EFI_DEVICE_PATH_PROTOCOL *TempDevicePath;
55
56 //
57 // First check to see if File is from a Firmware Volume
58 //
59 DeviceHandle = NULL;
60 TempDevicePath = (EFI_DEVICE_PATH_PROTOCOL *)File;
61 Status = gBS->LocateDevicePath (
62 &gEfiFirmwareVolume2ProtocolGuid,
63 &TempDevicePath,
64 &DeviceHandle
65 );
66 if (!EFI_ERROR (Status)) {
67 Status = gBS->OpenProtocol (
68 DeviceHandle,
69 &gEfiFirmwareVolume2ProtocolGuid,
70 NULL,
71 NULL,
72 NULL,
73 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
74 );
75 if (!EFI_ERROR (Status)) {
76 return TRUE;
77 }
78 }
79
80 return FALSE;
81}
82
93 IN CONST EFI_DEVICE_PATH_PROTOCOL *ImageDevicePath,
94 IN BOOLEAN BootOption
95 )
96{
97 UINTN Index;
98 UINTN DevicePathSize;
99
100 DevicePathSize = GetDevicePathSize (ImageDevicePath);
101
102 for (Index = 0; Index < mDeferred3rdPartyImage.Count; Index++) {
103 if (CompareMem (ImageDevicePath, mDeferred3rdPartyImage.ImageInfo[Index].ImageDevicePath, DevicePathSize) == 0) {
104 ASSERT (mDeferred3rdPartyImage.ImageInfo[Index].BootOption == BootOption);
105 return &mDeferred3rdPartyImage.ImageInfo[Index];
106 }
107 }
108
109 return NULL;
110}
111
119VOID
121 IN CONST EFI_DEVICE_PATH_PROTOCOL *ImageDevicePath,
122 IN BOOLEAN BootOption
123 )
124{
126
127 //
128 // Expand memory for the new deferred image.
129 //
130 ImageInfo = ReallocatePool (
131 mDeferred3rdPartyImage.Count * sizeof (DEFERRED_3RD_PARTY_IMAGE_INFO),
132 (mDeferred3rdPartyImage.Count + 1) * sizeof (DEFERRED_3RD_PARTY_IMAGE_INFO),
133 mDeferred3rdPartyImage.ImageInfo
134 );
135 if (ImageInfo == NULL) {
136 return;
137 }
138
139 mDeferred3rdPartyImage.ImageInfo = ImageInfo;
140
141 //
142 // Save the deferred image information.
143 //
144 ImageInfo = &mDeferred3rdPartyImage.ImageInfo[mDeferred3rdPartyImage.Count];
145 ImageInfo->ImageDevicePath = DuplicateDevicePath (ImageDevicePath);
146 if (ImageInfo->ImageDevicePath == NULL) {
147 return;
148 }
149
150 ImageInfo->BootOption = BootOption;
151 ImageInfo->Loaded = FALSE;
152 mDeferred3rdPartyImage.Count++;
153}
154
183EFIAPI
186 IN UINTN ImageIndex,
187 OUT EFI_DEVICE_PATH_PROTOCOL **ImageDevicePath,
188 OUT VOID **Image,
189 OUT UINTN *ImageSize,
190 OUT BOOLEAN *BootOption
191 )
192{
193 UINTN Index;
194 UINTN NewCount;
195
196 if ((This == NULL) || (ImageSize == NULL) || (Image == NULL)) {
197 return EFI_INVALID_PARAMETER;
198 }
199
200 if ((ImageDevicePath == NULL) || (BootOption == NULL)) {
201 return EFI_INVALID_PARAMETER;
202 }
203
204 //
205 // Remove the loaded images from the defer list in the first call.
206 //
207 if (ImageIndex == 0) {
208 NewCount = 0;
209 for (Index = 0; Index < mDeferred3rdPartyImage.Count; Index++) {
210 if (!mDeferred3rdPartyImage.ImageInfo[Index].Loaded) {
211 CopyMem (
212 &mDeferred3rdPartyImage.ImageInfo[NewCount],
213 &mDeferred3rdPartyImage.ImageInfo[Index],
215 );
216 NewCount++;
217 }
218 }
219
220 mDeferred3rdPartyImage.Count = NewCount;
221 }
222
223 if (ImageIndex >= mDeferred3rdPartyImage.Count) {
224 return EFI_NOT_FOUND;
225 }
226
227 //
228 // Get the request deferred image.
229 //
230 *ImageDevicePath = mDeferred3rdPartyImage.ImageInfo[ImageIndex].ImageDevicePath;
231 *BootOption = mDeferred3rdPartyImage.ImageInfo[ImageIndex].BootOption;
232 *Image = NULL;
233 *ImageSize = 0;
234
235 return EFI_SUCCESS;
236}
237
245VOID
246EFIAPI
248 IN EFI_EVENT Event,
249 IN VOID *Context
250 )
251{
252 mEndOfDxe = TRUE;
253}
254
267VOID
268EFIAPI
270 IN EFI_EVENT Event,
271 IN VOID *Context
272 )
273{
274 EFI_STATUS Status;
275 VOID *Interface;
276
277 Status = gBS->LocateProtocol (&gEfiDxeSmmReadyToLockProtocolGuid, NULL, &Interface);
278 if (EFI_ERROR (Status)) {
279 return;
280 }
281
282 gBS->CloseEvent (Event);
283
284 if (mImageLoadedAfterEndOfDxe) {
285 //
286 // Platform should not dispatch the 3rd party images after signaling EndOfDxe event
287 // but before publishing DxeSmmReadyToLock protocol.
288 //
289 DEBUG ((
290 DEBUG_ERROR,
291 "[Security] 3rd party images must be dispatched after DxeSmmReadyToLock Protocol installation!\n"
292 ));
294 EFI_ERROR_CODE | EFI_ERROR_UNRECOVERED,
295 (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_EC_ILLEGAL_SOFTWARE_STATE)
296 );
297 ASSERT (FALSE);
298 CpuDeadLoop ();
299 }
300}
301
316 IN BOOLEAN BootPolicy
317 )
318{
320
321 //
322 // Ignore if File is NULL.
323 //
324 if (File == NULL) {
325 return EFI_SUCCESS;
326 }
327
328 if (FileFromFv (File)) {
329 return EFI_SUCCESS;
330 }
331
332 ImageInfo = LookupImage (File, BootPolicy);
333
335 CHAR16 *DevicePathStr;
336
337 DevicePathStr = ConvertDevicePathToText (File, FALSE, FALSE);
338 DEBUG ((
339 DEBUG_INFO,
340 "[Security] 3rd party image[%p] %s EndOfDxe: %s.\n",
341 ImageInfo,
342 mEndOfDxe ? L"can be loaded after" : L"is deferred to load before",
343 DevicePathStr
344 ));
345 if (DevicePathStr != NULL) {
346 FreePool (DevicePathStr);
347 }
348
350
351 if (mEndOfDxe) {
352 mImageLoadedAfterEndOfDxe = TRUE;
353 //
354 // The image might be first time loaded after EndOfDxe,
355 // So ImageInfo can be NULL.
356 //
357 if (ImageInfo != NULL) {
358 ImageInfo->Loaded = TRUE;
359 }
360
361 return EFI_SUCCESS;
362 } else {
363 //
364 // The image might be second time loaded before EndOfDxe,
365 // So ImageInfo can be non-NULL.
366 //
367 if (ImageInfo == NULL) {
368 QueueImage (File, BootPolicy);
369 }
370
371 return EFI_ACCESS_DENIED;
372 }
373}
374
378VOID
380 VOID
381 )
382{
383 EFI_STATUS Status;
384 EFI_HANDLE Handle;
385 EFI_EVENT Event;
386 VOID *Registration;
387
388 Handle = NULL;
389 Status = gBS->InstallMultipleProtocolInterfaces (
390 &Handle,
391 &gEfiDeferredImageLoadProtocolGuid,
392 &mDeferredImageLoad,
393 NULL
394 );
395 ASSERT_EFI_ERROR (Status);
396
397 Status = gBS->CreateEventEx (
398 EVT_NOTIFY_SIGNAL,
399 TPL_CALLBACK,
400 EndOfDxe,
401 NULL,
402 &gEfiEndOfDxeEventGroupGuid,
403 &Event
404 );
405 ASSERT_EFI_ERROR (Status);
406
408 &gEfiDxeSmmReadyToLockProtocolGuid,
409 TPL_CALLBACK,
411 NULL,
412 &Registration
413 );
414}
UINT64 UINTN
VOID EFIAPI CpuDeadLoop(VOID)
Definition: CpuDeadLoop.c:25
INTN EFIAPI CompareMem(IN CONST VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
BOOLEAN mEndOfDxe
EFI_STATUS Defer3rdPartyImageLoad(IN CONST EFI_DEVICE_PATH_PROTOCOL *File, IN BOOLEAN BootPolicy)
VOID Defer3rdPartyImageLoadInitialize(VOID)
EFI_STATUS EFIAPI GetDefferedImageInfo(IN EFI_DEFERRED_IMAGE_LOAD_PROTOCOL *This, IN UINTN ImageIndex, OUT EFI_DEVICE_PATH_PROTOCOL **ImageDevicePath, OUT VOID **Image, OUT UINTN *ImageSize, OUT BOOLEAN *BootOption)
VOID QueueImage(IN CONST EFI_DEVICE_PATH_PROTOCOL *ImageDevicePath, IN BOOLEAN BootOption)
VOID EFIAPI EndOfDxe(IN EFI_EVENT Event, IN VOID *Context)
DEFERRED_3RD_PARTY_IMAGE_INFO * LookupImage(IN CONST EFI_DEVICE_PATH_PROTOCOL *ImageDevicePath, IN BOOLEAN BootOption)
BOOLEAN FileFromFv(IN CONST EFI_DEVICE_PATH_PROTOCOL *File)
VOID EFIAPI DxeSmmReadyToLock(IN EFI_EVENT Event, IN VOID *Context)
CHAR16 *EFIAPI ConvertDevicePathToText(IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath, IN BOOLEAN DisplayOnly, IN BOOLEAN AllowShortcuts)
UINTN EFIAPI GetDevicePathSize(IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath)
EFI_DEVICE_PATH_PROTOCOL *EFIAPI DuplicateDevicePath(IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath)
VOID *EFIAPI ReallocatePool(IN UINTN OldSize, IN UINTN NewSize, IN VOID *OldBuffer OPTIONAL)
VOID EFIAPI FreePool(IN VOID *Buffer)
#define NULL
Definition: Base.h:319
#define CONST
Definition: Base.h:259
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
#define ASSERT_EFI_ERROR(StatusParameter)
Definition: DebugLib.h:462
#define DEBUG_CODE_BEGIN()
Definition: DebugLib.h:564
#define DEBUG(Expression)
Definition: DebugLib.h:434
#define DEBUG_CODE_END()
Definition: DebugLib.h:578
#define REPORT_STATUS_CODE(Type, Value)
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
VOID * EFI_EVENT
Definition: UefiBaseType.h:37
VOID * EFI_HANDLE
Definition: UefiBaseType.h:33
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
EFI_BOOT_SERVICES * gBS
EFI_EVENT EFIAPI EfiCreateProtocolNotifyEvent(IN EFI_GUID *ProtocolGuid, IN EFI_TPL NotifyTpl, IN EFI_EVENT_NOTIFY NotifyFunction, IN VOID *NotifyContext OPTIONAL, OUT VOID **Registration)
Definition: UefiLib.c:134
DEFERRED_3RD_PARTY_IMAGE_INFO * ImageInfo
deferred 3rd party image item
UINTN Count
deferred 3rd party image count