Skip to content

Commit eb0d20b

Browse files
committed
loader-protocol: handle sub-section loading for UKIs
This adds support to Loader Protocol's shim_load_image() for loading from cached sub-sections. Resolves issue #741 Signed-off-by: Peter Jones <pjones@redhat.com>
1 parent 774f226 commit eb0d20b

File tree

1 file changed

+69
-29
lines changed

1 file changed

+69
-29
lines changed

loader-proto.c

Lines changed: 69 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,23 @@ 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, buffer_properties_t *bprop)
50+
{
51+
EFI_STATUS status;
52+
53+
status = validate_cached_section(parent_image_handle,
54+
bprop->buffer, bprop->size);
55+
if (EFI_ERROR(status))
56+
return status;
57+
58+
bprop->allocated_buffer = false;
59+
bprop->dp = dp;
60+
61+
return EFI_SUCCESS;
62+
}
63+
4764
static EFI_STATUS
4865
try_load_from_sfs(EFI_DEVICE_PATH *dp, buffer_properties_t *bprop)
4966
{
@@ -179,37 +196,60 @@ shim_load_image(BOOLEAN BootPolicy, EFI_HANDLE ParentImageHandle,
179196
if (BootPolicy)
180197
return EFI_UNSUPPORTED;
181198

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

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

0 commit comments

Comments
 (0)