Skip to content

Commit 97cee9b

Browse files
committed
ipxe: Allow next loader path to be derived from shim path
Allow loader path to be constructed from the path used to load the shim itself, e.g.: ipxe-shimx64.efi -> ipxe.efi ipxe-shimaa64.efi -> ipxe.efi snponly-shimx64.efi -> snponly.efi snponly-shimaa64.efi -> snponly.efi This reduces the complexity of using a signed shim binary to load iPXE, which (unlike GRUB) has a variety of possible binary names depending on the requested driver set. For example, if a site uses all three of ipxe.efi, intel.efi, and snponly.efi then symlinks can be used to provide the appropriate shim files: # iPXE binaries /var/lib/tftpboot/ipxe.efi /var/lib/tftpboot/intel.efi /var/lib/tftpboot/snponly.efi # shim binary (from this repository) /var/lib/tftpboot/ipxe-shimx64.efi # shim symlinks /var/lib/tftpboot/intel-shimx64.efi -> ipxe-shimx64.efi /var/lib/tftpboot/snponly-shimx64.efi -> ipxe-shimx64.efi Unlike the shim binary names, iPXE binary names do not conventionally include a CPU architecture suffix such as "x64" or "aa64": the expectation is that if multiple architectures are in use at a site, then there will be one directory per architecture. For example: /var/lib/tftpboot/x86_64/ipxe.efi /var/lib/tftpboot/x86_64/ipxe-shimx64.efi /var/lib/tftpboot/arm64/ipxe.efi /var/lib/tftpboot/arm64/ipxe-shimaa64.efi Signed-off-by: Michael Brown <[email protected]>
1 parent ff35d64 commit 97cee9b

File tree

4 files changed

+72
-0
lines changed

4 files changed

+72
-0
lines changed

httpboot.c

+3
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,9 @@ generate_next_uri (CONST CHAR8 *current_uri, CONST CHAR8 *next_loader,
175175
ptr++;
176176
}
177177

178+
if((*uri = automatic_next_path(current_uri, 0, next_loader)))
179+
return EFI_SUCCESS;
180+
178181
*uri = AllocatePool(sizeof(CHAR8) * (path_len + next_len + 1));
179182
if (!*uri)
180183
return EFI_OUT_OF_RESOURCES;

netboot.c

+10
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,10 @@ static BOOLEAN extract_tftp_info(CHAR8 *url, CHAR8 *name)
210210
FreePool(template);
211211
return FALSE;
212212
}
213+
if ((full_path = automatic_next_path(end, 0, name))) {
214+
FreePool(template);
215+
return TRUE;
216+
}
213217
full_path = AllocateZeroPool(strlen(end)+strlen(template)+1);
214218
if (!full_path) {
215219
FreePool(template);
@@ -276,6 +280,12 @@ static EFI_STATUS parseDhcp4(CHAR8 *name)
276280
INTN i;
277281
UINT8 *dir = pkt_v4->BootpBootFile;
278282

283+
if ((full_path = automatic_next_path((CHAR8 *)dir, dir_len, name))) {
284+
memcpy(&tftp_addr.v4, pkt_v4->BootpSiAddr, 4);
285+
FreePool(template);
286+
return EFI_SUCCESS;
287+
}
288+
279289
for (i = dir_len; i >= 0; i--) {
280290
if ((dir[i] == '/') || (dir[i] == '\\'))
281291
break;

shim.c

+56
Original file line numberDiff line numberDiff line change
@@ -2004,3 +2004,59 @@ efi_main (EFI_HANDLE passed_image_handle, EFI_SYSTEM_TABLE *passed_systab)
20042004
devel_egress(EFI_ERROR(efi_status) ? EXIT_FAILURE : EXIT_SUCCESS);
20052005
return efi_status;
20062006
}
2007+
2008+
/*
2009+
* If we are attempting to download the default loader, then construct
2010+
* the path by changing "-shim[arch].efi" to ".efi", if possible.
2011+
*
2012+
* This code is maintained as a patch separate from the shim codebase,
2013+
* and so is deliberately optimised for minimal intrusiveness rather
2014+
* than elegance.
2015+
*
2016+
*/
2017+
CHAR8 *automatic_next_path(CONST CHAR8 *path, UINTN path_len,
2018+
CONST CHAR8 *maybe_loader)
2019+
{
2020+
CHAR8 *filename;
2021+
CHAR8 *hyphen;
2022+
CHAR8 *dot;
2023+
CHAR8 *next;
2024+
2025+
/* Check if this request is for the default loader */
2026+
if (strcmp(maybe_loader, DEFAULT_LOADER_CHAR) != 0) {
2027+
/* Not the default loader: use normal shim code path */
2028+
return NULL;
2029+
}
2030+
2031+
/* Copy and NUL-terminate the path */
2032+
if (!path_len)
2033+
path_len = strlen(path);
2034+
next = AllocateZeroPool(path_len + 1);
2035+
if (!next)
2036+
return NULL;
2037+
memcpy(next, path, path_len);
2038+
next[path_len] = '\0';
2039+
2040+
/* Locate filename portion of path */
2041+
filename = strrchr(next, '/');
2042+
if (filename) {
2043+
filename++;
2044+
} else {
2045+
filename = next;
2046+
}
2047+
2048+
/* Check for "-shim[arch].efi" suffix */
2049+
if ((hyphen = strrchr(filename, '-')) &&
2050+
(strncasecmp(hyphen, "-shim", 5) == 0) &&
2051+
(dot = strrchr(hyphen, '.')) &&
2052+
(strcasecmp(dot, ".efi") == 0) &&
2053+
(dot - hyphen <= 9)) {
2054+
/* Suffix is present: replace "-shim[arch]" with ".efi" */
2055+
strcpy(hyphen, dot);
2056+
return next;
2057+
}
2058+
2059+
/* Suffix not found: use normal shim code path */
2060+
FreePool(next);
2061+
return NULL;
2062+
}

shim.h

+3
Original file line numberDiff line numberDiff line change
@@ -324,4 +324,7 @@ verify_buffer (char *data, int datasize,
324324

325325
char *translate_slashes(char *out, const char *str);
326326

327+
extern CHAR8 *automatic_next_path(CONST CHAR8 *path, UINTN path_len,
328+
CONST CHAR8 *maybe_loader);
329+
327330
#endif /* SHIM_H_ */

0 commit comments

Comments
 (0)