summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--httpboot.c8
-rw-r--r--include/httpboot.h2
-rw-r--r--include/netboot.h2
-rw-r--r--netboot.c49
-rw-r--r--shim.c33
5 files changed, 68 insertions, 26 deletions
diff --git a/httpboot.c b/httpboot.c
index b34dd49c..ac9ea25c 100644
--- a/httpboot.c
+++ b/httpboot.c
@@ -719,18 +719,20 @@ error:
}
EFI_STATUS
-httpboot_fetch_buffer (EFI_HANDLE image, VOID **buffer, UINT64 *buf_size)
+httpboot_fetch_buffer (EFI_HANDLE image, VOID **buffer, UINT64 *buf_size,
+ CHAR8 *name)
{
EFI_STATUS efi_status;
EFI_HANDLE nic;
- CHAR8 next_loader[sizeof DEFAULT_LOADER_CHAR];
+ CHAR8 *next_loader;
CHAR8 *next_uri = NULL;
CHAR8 *hostname = NULL;
if (!uri)
return EFI_NOT_READY;
- translate_slashes(next_loader, DEFAULT_LOADER_CHAR);
+ next_loader = (CHAR8 *)AllocatePool((strlen(name) + 1) * sizeof (CHAR8));
+ translate_slashes(next_loader, name);
/* Create the URI for the next loader based on the original URI */
efi_status = generate_next_uri(uri, next_loader, &next_uri);
diff --git a/include/httpboot.h b/include/httpboot.h
index ea9c57fe..119c546d 100644
--- a/include/httpboot.h
+++ b/include/httpboot.h
@@ -12,6 +12,6 @@
extern BOOLEAN find_httpboot(EFI_HANDLE device);
extern EFI_STATUS httpboot_fetch_buffer(EFI_HANDLE image, VOID **buffer,
- UINT64 *buf_size);
+ UINT64 *buf_size, CHAR8 *name);
#endif /* SHIM_HTTPBOOT_H */
diff --git a/include/netboot.h b/include/netboot.h
index 98b174a3..a7bf6cd8 100644
--- a/include/netboot.h
+++ b/include/netboot.h
@@ -5,7 +5,7 @@
extern BOOLEAN findNetboot(EFI_HANDLE image_handle);
-extern EFI_STATUS parseNetbootinfo(EFI_HANDLE image_handle);
+extern EFI_STATUS parseNetbootinfo(EFI_HANDLE image_handle, CHAR8 *name);
extern EFI_STATUS FetchNetbootimage(EFI_HANDLE image_handle, VOID **buffer, UINT64 *bufsiz);
diff --git a/netboot.c b/netboot.c
index 832deecd..d8b10935 100644
--- a/netboot.c
+++ b/netboot.c
@@ -160,25 +160,30 @@ static CHAR8 *str2ip6(CHAR8 *str)
return (CHAR8 *)ip;
}
-static BOOLEAN extract_tftp_info(CHAR8 *url)
+static BOOLEAN extract_tftp_info(CHAR8 *url, CHAR8 *name)
{
CHAR8 *start, *end;
CHAR8 ip6str[40];
CHAR8 ip6inv[16];
- CHAR8 template[sizeof DEFAULT_LOADER_CHAR];
+ int template_len = 0;
+ CHAR8 *template;
- translate_slashes(template, DEFAULT_LOADER_CHAR);
+ while (name[template_len++] != '\0');
+ template = (CHAR8 *)AllocatePool((template_len + 1) * sizeof (CHAR8));
+ translate_slashes(template, name);
// to check against str2ip6() errors
memset(ip6inv, 0, sizeof(ip6inv));
if (strncmp((const char *)url, (const char *)"tftp://", 7)) {
console_print(L"URLS MUST START WITH tftp://\n");
+ FreePool(template);
return FALSE;
}
start = url + 7;
if (*start != '[') {
console_print(L"TFTP SERVER MUST BE ENCLOSED IN [..]\n");
+ FreePool(template);
return FALSE;
}
@@ -188,22 +193,28 @@ static BOOLEAN extract_tftp_info(CHAR8 *url)
end++;
if (end - start >= (int)sizeof(ip6str)) {
console_print(L"TFTP URL includes malformed IPv6 address\n");
+ FreePool(template);
return FALSE;
}
}
if (*end == '\0') {
console_print(L"TFTP SERVER MUST BE ENCLOSED IN [..]\n");
+ FreePool(template);
return FALSE;
}
memset(ip6str, 0, sizeof(ip6str));
memcpy(ip6str, start, end - start);
end++;
memcpy(&tftp_addr.v6, str2ip6(ip6str), 16);
- if (memcmp(&tftp_addr.v6, ip6inv, sizeof(ip6inv)) == 0)
+ if (memcmp(&tftp_addr.v6, ip6inv, sizeof(ip6inv)) == 0) {
+ FreePool(template);
return FALSE;
+ }
full_path = AllocateZeroPool(strlen(end)+strlen(template)+1);
- if (!full_path)
+ if (!full_path) {
+ FreePool(template);
return FALSE;
+ }
memcpy(full_path, end, strlen(end));
end = (CHAR8 *)strrchr((char *)full_path, '/');
if (!end)
@@ -211,10 +222,11 @@ static BOOLEAN extract_tftp_info(CHAR8 *url)
memcpy(end, template, strlen(template));
end[strlen(template)] = '\0';
+ FreePool(template);
return TRUE;
}
-static EFI_STATUS parseDhcp6()
+static EFI_STATUS parseDhcp6(CHAR8 *name)
{
EFI_PXE_BASE_CODE_DHCPV6_PACKET *packet = (EFI_PXE_BASE_CODE_DHCPV6_PACKET *)&pxe->Mode->DhcpAck.Raw;
CHAR8 *bootfile_url;
@@ -222,7 +234,7 @@ static EFI_STATUS parseDhcp6()
bootfile_url = get_v6_bootfile_url(packet);
if (!bootfile_url)
return EFI_NOT_FOUND;
- if (extract_tftp_info(bootfile_url) == FALSE) {
+ if (extract_tftp_info(bootfile_url, name) == FALSE) {
FreePool(bootfile_url);
return EFI_NOT_FOUND;
}
@@ -230,14 +242,16 @@ static EFI_STATUS parseDhcp6()
return EFI_SUCCESS;
}
-static EFI_STATUS parseDhcp4()
+static EFI_STATUS parseDhcp4(CHAR8 *name)
{
- CHAR8 template[sizeof DEFAULT_LOADER_CHAR];
- INTN template_len;
+ CHAR8 *template;
+ INTN template_len = 0;
UINTN template_ofs = 0;
EFI_PXE_BASE_CODE_DHCPV4_PACKET* pkt_v4 = (EFI_PXE_BASE_CODE_DHCPV4_PACKET *)&pxe->Mode->DhcpAck.Dhcpv4;
- translate_slashes(template, DEFAULT_LOADER_CHAR);
+ while (name[template_len++] != '\0');
+ template = (CHAR8 *)AllocatePool((template_len + 1) * sizeof (CHAR8));
+ translate_slashes(template, name);
template_len = strlen(template) + 1;
if(pxe->Mode->ProxyOfferReceived) {
@@ -270,8 +284,10 @@ static EFI_STATUS parseDhcp4()
full_path = AllocateZeroPool(dir_len + template_len);
- if (!full_path)
+ if (!full_path) {
+ FreePool(template);
return EFI_OUT_OF_RESOURCES;
+ }
if (dir_len > 0) {
strncpy(full_path, (CHAR8 *)dir, dir_len);
@@ -292,10 +308,11 @@ static EFI_STATUS parseDhcp4()
strcat(full_path, template + template_ofs);
memcpy(&tftp_addr.v4, pkt_v4->BootpSiAddr, 4);
+ FreePool(template);
return EFI_SUCCESS;
}
-EFI_STATUS parseNetbootinfo(EFI_HANDLE image_handle UNUSED)
+EFI_STATUS parseNetbootinfo(EFI_HANDLE image_handle UNUSED, CHAR8 *netbootname)
{
EFI_STATUS efi_status;
@@ -310,9 +327,9 @@ EFI_STATUS parseNetbootinfo(EFI_HANDLE image_handle UNUSED)
* if its ipv4 or ipv6
*/
if (pxe->Mode->UsingIpv6){
- efi_status = parseDhcp6();
+ efi_status = parseDhcp6(netbootname);
} else
- efi_status = parseDhcp4();
+ efi_status = parseDhcp4(netbootname);
return efi_status;
}
@@ -324,7 +341,7 @@ EFI_STATUS FetchNetbootimage(EFI_HANDLE image_handle UNUSED, VOID **buffer, UINT
BOOLEAN nobuffer = FALSE;
UINTN blksz = 512;
- console_print(L"Fetching Netboot Image\n");
+ console_print(L"Fetching Netboot Image %a\n", full_path);
if (*buffer == NULL) {
*buffer = AllocatePool(4096 * 1024);
if (!*buffer)
diff --git a/shim.c b/shim.c
index 3854fbde..fd196cd9 100644
--- a/shim.c
+++ b/shim.c
@@ -1070,6 +1070,23 @@ restore_loaded_image(VOID)
CopyMem(shim_li, &shim_li_bak, sizeof(shim_li_bak));
}
+/* If gets used on static data it probably needs boundary checking */
+void
+str16_to_str8(CHAR16 *str16, CHAR8 **str8)
+{
+ int i = 0;
+
+ while (str16[i++] != '\0');
+ *str8 = (CHAR8 *)AllocatePool((i + 1) * sizeof (CHAR8));
+
+ i = 0;
+ while (str16[i] != '\0') {
+ (*str8)[i] = (CHAR8)str16[i];
+ i++;
+ }
+ (*str8)[i] = '\0';
+}
+
/*
* Load and run an EFI executable
*/
@@ -1079,6 +1096,7 @@ EFI_STATUS read_image(EFI_HANDLE image_handle, CHAR16 *ImagePath,
EFI_STATUS efi_status;
void *sourcebuffer = NULL;
UINT64 sourcesize = 0;
+ CHAR8 *netbootname;
/*
* We need to refer to the loaded image protocol on the running
@@ -1102,11 +1120,13 @@ EFI_STATUS read_image(EFI_HANDLE image_handle, CHAR16 *ImagePath,
}
if (findNetboot(shim_li->DeviceHandle)) {
- efi_status = parseNetbootinfo(image_handle);
+ str16_to_str8(ImagePath, &netbootname);
+ efi_status = parseNetbootinfo(image_handle, netbootname);
if (EFI_ERROR(efi_status)) {
perror(L"Netboot parsing failed: %r\n", efi_status);
return EFI_PROTOCOL_ERROR;
}
+ FreePool(netbootname);
efi_status = FetchNetbootimage(image_handle, &sourcebuffer,
&sourcesize);
if (EFI_ERROR(efi_status)) {
@@ -1117,12 +1137,14 @@ EFI_STATUS read_image(EFI_HANDLE image_handle, CHAR16 *ImagePath,
*data = sourcebuffer;
*datasize = sourcesize;
} else if (find_httpboot(shim_li->DeviceHandle)) {
+ str16_to_str8(ImagePath, &netbootname);
efi_status = httpboot_fetch_buffer (image_handle,
&sourcebuffer,
- &sourcesize);
+ &sourcesize,
+ netbootname);
if (EFI_ERROR(efi_status)) {
- perror(L"Unable to fetch HTTP image: %r\n",
- efi_status);
+ perror(L"Unable to fetch HTTP image %a: %r\n",
+ netbootname, efi_status);
return efi_status;
}
*data = sourcebuffer;
@@ -1566,7 +1588,8 @@ load_unbundled_trust(EFI_HANDLE image_handle)
efi_status = gBS->HandleProtocol(device, &EFI_SIMPLE_FILE_SYSTEM_GUID,
(void **)&drive);
if (EFI_ERROR(efi_status)) {
- perror(L"Failed to find fs: %r\n", efi_status);
+ dprint(L"Failed to find fs on local drive (netboot?): %r \n",
+ efi_status);
goto done;
}