From patchwork Sun Mar 22 09:57:30 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Heinrich Schuchardt X-Patchwork-Id: 244082 List-Id: U-Boot discussion From: xypron.glpk at gmx.de (Heinrich Schuchardt) Date: Sun, 22 Mar 2020 10:57:30 +0100 Subject: [PATCH v2 1/2] efi_loader: correct reported length in GetNextVariable() In-Reply-To: <20200322095731.76982-1-xypron.glpk@gmx.de> References: <20200322095731.76982-1-xypron.glpk@gmx.de> Message-ID: <20200322095731.76982-2-xypron.glpk@gmx.de> The runtime service GetNextVariable() returns the length of the next variable including the closing 0x0000. This length should be in bytes. Comparing the output of EDK2 and U-Boot shows that this is currently not correctly implemented: EDK2: OsIndicationsSupported: 46 PlatformLang: 26 PlatformLangCodes: 36 U-Boot: OsIndicationsSupported: 23 PlatformLang: 13 PlatformLangCodes: 18 Provide correct length in GetNextVariable(). Fixes: d99a87f84b75 ("efi_loader: implement GetNextVariableName()") Signed-off-by: Heinrich Schuchardt --- v2: correct return value of the initial call too --- lib/efi_loader/efi_variable.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) -- 2.25.1 diff --git a/lib/efi_loader/efi_variable.c b/lib/efi_loader/efi_variable.c index 99d2f01f57..3bec2d0d17 100644 --- a/lib/efi_loader/efi_variable.c +++ b/lib/efi_loader/efi_variable.c @@ -273,7 +273,8 @@ static efi_status_t parse_uboot_variable(char *variable, u32 *attributes) { char *guid, *name, *end, c; - unsigned long name_len; + size_t name_len; + efi_uintn_t old_variable_name_size; u16 *p; guid = strchr(variable, '_'); @@ -289,17 +290,17 @@ static efi_status_t parse_uboot_variable(char *variable, return EFI_INVALID_PARAMETER; name_len = end - name; - if (*variable_name_size < (name_len + 1)) { - *variable_name_size = name_len + 1; + old_variable_name_size = *variable_name_size; + *variable_name_size = sizeof(u16) * (name_len + 1); + if (old_variable_name_size < *variable_name_size) return EFI_BUFFER_TOO_SMALL; - } + end++; /* point to value */ /* variable name */ p = variable_name; utf8_utf16_strncpy(&p, name, name_len); variable_name[name_len] = 0; - *variable_name_size = name_len + 1; /* guid */ c = *(name - 1); From patchwork Sun Mar 22 09:57:31 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Heinrich Schuchardt X-Patchwork-Id: 244084 List-Id: U-Boot discussion From: xypron.glpk at gmx.de (Heinrich Schuchardt) Date: Sun, 22 Mar 2020 10:57:31 +0100 Subject: [PATCH v2 2/2] efi_selftest: check length report by GetNextVariableName() In-Reply-To: <20200322095731.76982-1-xypron.glpk@gmx.de> References: <20200322095731.76982-1-xypron.glpk@gmx.de> Message-ID: <20200322095731.76982-3-xypron.glpk@gmx.de> GetNextVariableName should report the length of the variable including the final 0x0000 in bytes. Check this in the unit test. Increase the buffer size for variable names. 40 bytes is too short. Signed-off-by: Heinrich Schuchardt --- v2: Increase the buffer size for variable names. --- lib/efi_selftest/efi_selftest_variables.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) -- 2.25.1 diff --git a/lib/efi_selftest/efi_selftest_variables.c b/lib/efi_selftest/efi_selftest_variables.c index 5d98c029b8..2c16f3db6c 100644 --- a/lib/efi_selftest/efi_selftest_variables.c +++ b/lib/efi_selftest/efi_selftest_variables.c @@ -11,7 +11,7 @@ #include #define EFI_ST_MAX_DATA_SIZE 16 -#define EFI_ST_MAX_VARNAME_SIZE 40 +#define EFI_ST_MAX_VARNAME_SIZE 80 static struct efi_boot_services *boottime; static struct efi_runtime_services *runtime; @@ -155,8 +155,14 @@ static int execute(void) return EFI_ST_FAILURE; } if (!memcmp(&guid, &guid_vendor0, sizeof(efi_guid_t)) && - !efi_st_strcmp_16_8(varname, "efi_st_var0")) + !efi_st_strcmp_16_8(varname, "efi_st_var0")) { flag |= 1; + if (len != 24) { + efi_st_error("GetNextVariableName report wrong length %u, expected 24\n", + (unsigned int)len); + return EFI_ST_FAILURE; + } + } if (!memcmp(&guid, &guid_vendor1, sizeof(efi_guid_t)) && !efi_st_strcmp_16_8(varname, "efi_st_var1")) flag |= 2;