Skip to content

Commit 9fc9e5a

Browse files
committed
loader-protocol: handle sub-section device path loading for UKIs
This adds support to Loader Protocol's shim_load_image() for loading from cached sub-sections. Signed-off-by: Peter Jones <pjones@redhat.com>
1 parent 49889f1 commit 9fc9e5a

File tree

1 file changed

+70
-29
lines changed

1 file changed

+70
-29
lines changed

loader-proto.c

Lines changed: 70 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,24 @@ typedef struct {
4444
bool allocated_buffer;
4545
} buffer_properties_t;
4646

47+
static EFI_STATUS
48+
try_load_from_cached_section(EFI_HANDLE parent_image_handle,
49+
EFI_DEVICE_PATH *dp,
50+
buffer_properties_t *bprop)
51+
{
52+
EFI_STATUS status;
53+
54+
status = validate_cached_section(parent_image_handle,
55+
bprop->buffer, bprop->size);
56+
if (EFI_ERROR(status))
57+
return status;
58+
59+
bprop->allocated_buffer = false;
60+
bprop->dp = dp;
61+
62+
return EFI_SUCCESS;
63+
}
64+
4765
static EFI_STATUS
4866
try_load_from_sfs(EFI_DEVICE_PATH *dp, buffer_properties_t *bprop)
4967
{
@@ -183,37 +201,60 @@ shim_load_image(BOOLEAN BootPolicy, EFI_HANDLE ParentImageHandle,
183201
if (BootPolicy)
184202
return EFI_UNSUPPORTED;
185203

186-
if (!SourceBuffer || !SourceSize) {
187-
if (!DevicePath) /* Both SourceBuffer and DevicePath are NULL */
188-
return EFI_NOT_FOUND;
189-
190-
if (try_load_from_sfs(DevicePath, &bprop) == EFI_SUCCESS)
191-
;
192-
else if (try_load_from_lf2(DevicePath, &bprop) == EFI_SUCCESS)
193-
;
194-
else
195-
/* no buffer given and we cannot load from this device */
204+
/*
205+
* First we're checking if it's cached - since that is quite fast
206+
* unless we have a match, and any match is okay, we don't need to
207+
* do anything more complicated.
208+
*/
209+
if (SourceSize && SourceBuffer) {
210+
bprop.buffer = SourceBuffer;
211+
bprop.size = SourceSize;
212+
efi_status = try_load_from_cached_section(ParentImageHandle,
213+
DevicePath, &bprop);
214+
if (!EFI_ERROR(efi_status)) {
215+
parent_verified = true;
216+
} else if (efi_status != EFI_NOT_FOUND) {
196217
return EFI_LOAD_ERROR;
218+
}
219+
}
197220

198-
SourceBuffer = bprop.buffer;
199-
SourceSize = bprop.size;
200-
} else {
201-
bprop.buffer = NULL;
202-
/*
203-
* Even if we are using a buffer, try populating the
204-
* device_handle and file_path fields the best we can
205-
*/
206-
207-
bprop.dp = DevicePath;
208-
209-
if (bprop.dp) {
210-
efi_status = BS->LocateDevicePath(&gEfiDevicePathProtocolGuid,
211-
&bprop.dp,
212-
&bprop.hnd);
213-
if (efi_status != EFI_SUCCESS) {
214-
/* can't seem to pull apart this DP */
215-
bprop.dp = DevicePath;
216-
bprop.hnd = NULL;
221+
/*
222+
* If we don't already have a cached, verified copy of the object
223+
* being loaded, go about it the old way.
224+
*/
225+
if (!parent_verified) {
226+
if (!SourceBuffer || !SourceSize) {
227+
if (!DevicePath) /* Both SourceBuffer and DevicePath are NULL */
228+
return EFI_NOT_FOUND;
229+
230+
if (try_load_from_sfs(DevicePath, &bprop) == EFI_SUCCESS)
231+
;
232+
else if (try_load_from_lf2(DevicePath, &bprop) == EFI_SUCCESS)
233+
;
234+
else
235+
/* no buffer given and we cannot load from this device */
236+
return EFI_LOAD_ERROR;
237+
238+
SourceBuffer = bprop.buffer;
239+
SourceSize = bprop.size;
240+
} else {
241+
bprop.buffer = NULL;
242+
/*
243+
* Even if we are using a buffer, try populating the
244+
* device_handle and file_path fields the best we can
245+
*/
246+
247+
bprop.dp = DevicePath;
248+
249+
if (bprop.dp) {
250+
efi_status = BS->LocateDevicePath(&gEfiDevicePathProtocolGuid,
251+
&bprop.dp,
252+
&bprop.hnd);
253+
if (efi_status != EFI_SUCCESS) {
254+
/* can't seem to pull apart this DP */
255+
bprop.dp = DevicePath;
256+
bprop.hnd = NULL;
257+
}
217258
}
218259
}
219260
}

0 commit comments

Comments
 (0)