summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorHeinrich Schuchardt <xypron.glpk@gmx.de>2018-10-19 07:51:26 +0200
committerAlexander Graf <agraf@suse.de>2018-12-02 21:59:37 +0100
commit4c174394caa814a185121e7b06a41dc4be5c774a (patch)
tree462434baa564d79739f93451ec7afe017ab280a0 /lib
parent81ea00838c682da06637bcf208549095181df337 (diff)
efi_selftest: do not write to linker generated array
Linker generated arrays may be stored in code sections of memory that are not writable. So let's allocate setup_ok as an array at runtime. This avoids an illegal memory access observed in the sandbox. Reported-by: Simon Glass <sjg@chromium.org> Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de> Signed-off-by: Alexander Graf <agraf@suse.de>
Diffstat (limited to 'lib')
-rw-r--r--lib/efi_selftest/efi_selftest.c31
1 files changed, 22 insertions, 9 deletions
diff --git a/lib/efi_selftest/efi_selftest.c b/lib/efi_selftest/efi_selftest.c
index dd338db687..fc7866365d 100644
--- a/lib/efi_selftest/efi_selftest.c
+++ b/lib/efi_selftest/efi_selftest.c
@@ -18,6 +18,7 @@ static const struct efi_boot_services *boottime;
static const struct efi_runtime_services *runtime;
static efi_handle_t handle;
static u16 reset_message[] = L"Selftest completed";
+static int *setup_ok;
/*
* Exit the boot services.
@@ -74,20 +75,20 @@ void efi_st_exit_boot_services(void)
*/
static int setup(struct efi_unit_test *test, unsigned int *failures)
{
- if (!test->setup) {
- test->setup_ok = EFI_ST_SUCCESS;
+ int ret;
+
+ if (!test->setup)
return EFI_ST_SUCCESS;
- }
efi_st_printc(EFI_LIGHTBLUE, "\nSetting up '%s'\n", test->name);
- test->setup_ok = test->setup(handle, systable);
- if (test->setup_ok != EFI_ST_SUCCESS) {
+ ret = test->setup(handle, systable);
+ if (ret != EFI_ST_SUCCESS) {
efi_st_error("Setting up '%s' failed\n", test->name);
++*failures;
} else {
efi_st_printc(EFI_LIGHTGREEN,
"Setting up '%s' succeeded\n", test->name);
}
- return test->setup_ok;
+ return ret;
}
/*
@@ -186,18 +187,20 @@ static void list_all_tests(void)
void efi_st_do_tests(const u16 *testname, unsigned int phase,
unsigned int steps, unsigned int *failures)
{
+ int i = 0;
struct efi_unit_test *test;
for (test = ll_entry_start(struct efi_unit_test, efi_unit_test);
- test < ll_entry_end(struct efi_unit_test, efi_unit_test); ++test) {
+ test < ll_entry_end(struct efi_unit_test, efi_unit_test);
+ ++test, ++i) {
if (testname ?
efi_st_strcmp_16_8(testname, test->name) : test->on_request)
continue;
if (test->phase != phase)
continue;
if (steps & EFI_ST_SETUP)
- setup(test, failures);
- if (steps & EFI_ST_EXECUTE && test->setup_ok == EFI_ST_SUCCESS)
+ setup_ok[i] = setup(test, failures);
+ if (steps & EFI_ST_EXECUTE && setup_ok[i] == EFI_ST_SUCCESS)
execute(test, failures);
if (steps & EFI_ST_TEARDOWN)
teardown(test, failures);
@@ -271,6 +274,16 @@ efi_status_t EFIAPI efi_selftest(efi_handle_t image_handle,
ll_entry_count(struct efi_unit_test,
efi_unit_test));
+ /* Allocate buffer for setup results */
+ ret = boottime->allocate_pool(EFI_RUNTIME_SERVICES_DATA, sizeof(int) *
+ ll_entry_count(struct efi_unit_test,
+ efi_unit_test),
+ (void **)&setup_ok);
+ if (ret != EFI_SUCCESS) {
+ efi_st_error("Allocate pool failed\n");
+ return ret;
+ }
+
/* Execute boottime tests */
efi_st_do_tests(testname, EFI_EXECUTE_BEFORE_BOOTTIME_EXIT,
EFI_ST_SETUP | EFI_ST_EXECUTE | EFI_ST_TEARDOWN,