summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorTom Rini <[email protected]>2020-08-24 17:28:18 -0400
committerTom Rini <[email protected]>2020-08-24 17:28:18 -0400
commit3c0cec035e5b06b638fb52ccd7383bbd5bcede35 (patch)
tree5dfb658a5a4376ab257dfccdbc51f2e301fd0256 /lib
parent1aa3966173fe92fa3c46638ee8eb8b8491f521d6 (diff)
parent2b3fbcb59f4174e455a6285eaddf1426ed3e76c5 (diff)
Merge tag 'efi-2020-10-rc3-3' of https://gitlab.denx.de/u-boot/custodians/u-boot-efi
Pull request for UEFI sub-system for efi-2020-10-rc3 (3) The following bug fixes are contained in this pull-request: * ResetSystem() should no hang if not implemented. * Device paths in Bootxxxx variables should be verified. * Use ':' as separator for command setenv -e -i instead of ','. * Correct comments for functions. * Update UEFI documentation.
Diffstat (limited to 'lib')
-rw-r--r--lib/efi_loader/efi_bootmgr.c6
-rw-r--r--lib/efi_loader/efi_device_path.c33
-rw-r--r--lib/efi_loader/efi_runtime.c7
-rw-r--r--lib/efi_selftest/Makefile1
-rw-r--r--lib/efi_selftest/efi_selftest.c10
-rw-r--r--lib/efi_selftest/efi_selftest_reset.c58
6 files changed, 106 insertions, 9 deletions
diff --git a/lib/efi_loader/efi_bootmgr.c b/lib/efi_loader/efi_bootmgr.c
index 1e06e609639..61dc72a23da 100644
--- a/lib/efi_loader/efi_bootmgr.c
+++ b/lib/efi_loader/efi_bootmgr.c
@@ -105,10 +105,8 @@ efi_status_t efi_deserialize_load_option(struct efi_load_option *lo, u8 *data,
if (*size < len)
return EFI_INVALID_PARAMETER;
lo->file_path = (struct efi_device_path *)data;
- /*
- * TODO: validate device path. There should be an end node within
- * the indicated file_path_length.
- */
+ if (efi_dp_check_length(lo->file_path, len) < 0)
+ return EFI_INVALID_PARAMETER;
data += len;
*size -= len;
diff --git a/lib/efi_loader/efi_device_path.c b/lib/efi_loader/efi_device_path.c
index 7ae14f34239..8a5c13c4241 100644
--- a/lib/efi_loader/efi_device_path.c
+++ b/lib/efi_loader/efi_device_path.c
@@ -1127,3 +1127,36 @@ efi_status_t efi_dp_from_name(const char *dev, const char *devnr,
return EFI_SUCCESS;
}
+
+/**
+ * efi_dp_check_length() - check length of a device path
+ *
+ * @dp: pointer to device path
+ * @maxlen: maximum length of the device path
+ * Return:
+ * * length of the device path if it is less or equal @maxlen
+ * * -1 if the device path is longer then @maxlen
+ * * -1 if a device path node has a length of less than 4
+ * * -EINVAL if maxlen exceeds SSIZE_MAX
+ */
+ssize_t efi_dp_check_length(const struct efi_device_path *dp,
+ const size_t maxlen)
+{
+ ssize_t ret = 0;
+ u16 len;
+
+ if (maxlen > SSIZE_MAX)
+ return -EINVAL;
+ for (;;) {
+ len = dp->length;
+ if (len < 4)
+ return -1;
+ ret += len;
+ if (ret > maxlen)
+ return -1;
+ if (dp->type == DEVICE_PATH_TYPE_END &&
+ dp->sub_type == DEVICE_PATH_SUB_TYPE_END)
+ return ret;
+ dp = (const struct efi_device_path *)((const u8 *)dp + len);
+ }
+}
diff --git a/lib/efi_loader/efi_runtime.c b/lib/efi_loader/efi_runtime.c
index 78fd8014d90..dea2b4e5eea 100644
--- a/lib/efi_loader/efi_runtime.c
+++ b/lib/efi_loader/efi_runtime.c
@@ -365,7 +365,9 @@ out:
* efi_reset_system() - reset system
*
* This function implements the ResetSystem() runtime service after
- * SetVirtualAddressMap() is called. It only executes an endless loop.
+ * SetVirtualAddressMap() is called. As this placeholder cannot reset the
+ * system it simply return to the caller.
+ *
* Boards may override the helpers below to implement reset functionality.
*
* See the Unified Extensible Firmware Interface (UEFI) specification for
@@ -381,8 +383,7 @@ void __weak __efi_runtime EFIAPI efi_reset_system(
efi_status_t reset_status,
unsigned long data_size, void *reset_data)
{
- /* Nothing we can do */
- while (1) { }
+ return;
}
/**
diff --git a/lib/efi_selftest/Makefile b/lib/efi_selftest/Makefile
index 45ce6859b86..85fe8e1216a 100644
--- a/lib/efi_selftest/Makefile
+++ b/lib/efi_selftest/Makefile
@@ -31,6 +31,7 @@ efi_selftest_mem.o \
efi_selftest_memory.o \
efi_selftest_open_protocol.o \
efi_selftest_register_notify.o \
+efi_selftest_reset.o \
efi_selftest_set_virtual_address_map.o \
efi_selftest_textinput.o \
efi_selftest_textinputex.o \
diff --git a/lib/efi_selftest/efi_selftest.c b/lib/efi_selftest/efi_selftest.c
index 5b01610eca1..6eec8ae2a7c 100644
--- a/lib/efi_selftest/efi_selftest.c
+++ b/lib/efi_selftest/efi_selftest.c
@@ -5,6 +5,7 @@
* Copyright (c) 2017 Heinrich Schuchardt <[email protected]>
*/
+#include <command.h>
#include <efi_selftest.h>
#include <vsprintf.h>
@@ -309,8 +310,13 @@ efi_status_t EFIAPI efi_selftest(efi_handle_t image_handle,
/* Reset system */
efi_st_printf("Preparing for reset. Press any key...\n");
efi_st_get_key();
- runtime->reset_system(EFI_RESET_WARM, EFI_NOT_READY,
- sizeof(reset_message), reset_message);
+
+ if (IS_ENABLED(CONFIG_EFI_HAVE_RUNTIME_RESET))
+ runtime->reset_system(EFI_RESET_WARM, EFI_NOT_READY,
+ sizeof(reset_message), reset_message);
+ else
+ do_reset(NULL, 0, 0, NULL);
+
efi_st_printf("\n");
efi_st_error("Reset failed\n");
diff --git a/lib/efi_selftest/efi_selftest_reset.c b/lib/efi_selftest/efi_selftest_reset.c
new file mode 100644
index 00000000000..8b6ac24cb15
--- /dev/null
+++ b/lib/efi_selftest/efi_selftest_reset.c
@@ -0,0 +1,58 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * efi_selftest_reset
+ *
+ * Copyright (c) 2020 Heinrich Schuchardt <[email protected]>
+ *
+ * This test checks the following service at boot time or runtime:
+ * ResetSystem()
+ */
+
+#include <efi_selftest.h>
+
+static struct efi_runtime_services *runtime;
+
+/*
+ * Setup unit test.
+ *
+ * @handle: handle of the loaded image
+ * @systable: system table
+ * @return: EFI_ST_SUCCESS for success
+ */
+static int setup(const efi_handle_t handle,
+ const struct efi_system_table *systable)
+{
+ runtime = systable->runtime;
+ return EFI_ST_SUCCESS;
+}
+
+/*
+ * Execute unit test.
+ *
+ * @return: EFI_ST_SUCCESS for success
+ */
+static int execute(void)
+{
+ u16 reset_data[] = L"Reset by selftest";
+
+ runtime->reset_system(EFI_RESET_COLD, EFI_SUCCESS,
+ sizeof(reset_data), reset_data);
+ efi_st_error("Reset failed.\n");
+ return EFI_ST_FAILURE;
+}
+
+EFI_UNIT_TEST(reset) = {
+ .name = "reset system",
+ .phase = EFI_EXECUTE_BEFORE_BOOTTIME_EXIT,
+ .setup = setup,
+ .execute = execute,
+ .on_request = true,
+};
+
+EFI_UNIT_TEST(resetrt) = {
+ .name = "reset system runtime",
+ .phase = EFI_SETUP_BEFORE_BOOTTIME_EXIT,
+ .setup = setup,
+ .execute = execute,
+ .on_request = true,
+};