)
On Fri, 23 Oct 2026 at 14:57, Heinrich Schuchardt
<[email protected]> wrote:
>
> On 10/23/26 13:39, Ilias Apalodimas wrote:
> > On Fri, 23 Oct 2026 at 14:19, Heinrich Schuchardt
> > <[email protected]> wrote:
> >>
> >> On 10/23/26 09:25, Ilias Apalodimas wrote:
> >>> Hi Heinrich
> >>>
> >>> On Fri, 23 Oct 2026 at 02:56, Heinrich Schuchardt
> >>> <[email protected]> wrote:
> >>>>
> >>>> * Add missing parameter checks required by the UEFI spec.
> >>>> * Return EFI_INVALID_LANGUAGE if a string does not exist in the requested
> >>>> language.
> >>>> * Handle querying the string size with *string_size == 0 and string =
> >>>> NULL.
> >>>>
> >>>> Fixes: c9bfb22296b0 ("efi_loader: Initial HII database protocols")
> >>>> Signed-off-by: Heinrich Schuchardt <[email protected]>
> >>>> ---
> >>>> v3:
> >>>> Update commit message to indicate that parameter checks are
> >>>> added.
> >>>> Correct a misspelled variable.
> >>>> v2:
> >>>> string_id == 0 is not used by our code. Return EFI_NOT_FOUND.
> >>>> ---
> >>>> lib/efi_loader/efi_hii.c | 34 ++++++++++++++++++++++++----------
> >>>> 1 file changed, 24 insertions(+), 10 deletions(-)
> >>>>
> >>>> diff --git a/lib/efi_loader/efi_hii.c b/lib/efi_loader/efi_hii.c
> >>>> index 90dff91e5d4..47325f7d8aa 100644
> >>>> --- a/lib/efi_loader/efi_hii.c
> >>>> +++ b/lib/efi_loader/efi_hii.c
> >>>> @@ -910,41 +910,55 @@ get_string(const struct efi_hii_string_protocol
> >>>> *this,
> >>>> {
> >>>> struct efi_hii_packagelist *hii = package_list;
> >>>> struct efi_string_table *stbl;
> >>>> + efi_status_t ret;
> >>>>
> >>>> EFI_ENTRY("%p, \"%s\", %p, %u, %p, %p, %p", this, language,
> >>>> package_list, string_id, string, string_size,
> >>>> string_font_info);
> >>>>
> >>>> - if (!package_list || !efi_hii_packagelist_exists(package_list))
> >>>> - return EFI_EXIT(EFI_NOT_FOUND);
> >>>> + if (!language || !string_size || (*string_size && !string)) {
> >>>> + ret = EFI_INVALID_PARAMETER;
> >>>> + goto out;
> >>>> + }
> >>>> +
> >>>> + if (!package_list ||
> >>>> + !efi_hii_packagelist_exists(package_list) ||
> >>>> + !string_id ||
> >>>> + string_id > hii->max_string_id) {
> >>>> + ret = EFI_NOT_FOUND;
> >>>> + goto out;
> >>>> + }
> >>>>
> >>>> + ret = EFI_INVALID_LANGUAGE;
> >>>> list_for_each_entry(stbl, &hii->string_tables, link) {
> >>>> if (language_match((char *)language, stbl->language)) {
> >>>> efi_string_t str;
> >>>> size_t len;
> >>>>
> >>>> if (stbl->nstrings < string_id)
> >>>> - return EFI_EXIT(EFI_NOT_FOUND);
> >>>> + goto out;
> >>>>
> >>>> str = stbl->strings[string_id - 1].string;
> >>>> if (str) {
> >>>> len = u16_strsize(str);
> >>>> if (*string_size < len) {
> >>>> *string_size = len;
> >>>> -
> >>>> - return
> >>>> EFI_EXIT(EFI_BUFFER_TOO_SMALL);
> >>>> + ret = EFI_BUFFER_TOO_SMALL;
> >>>> + goto out;
> >>>> }
> >>>> - memcpy(string, str, len);
> >>>> *string_size = len;
> >>>> + if (string)
> >>>
> >>> This is always going to be true since u16_strsize() include the
> >>> terminator. It's a nit so I am fine fixing it during the merge
> >>>
> >>> Reviewed-by: Ilias Apalodimas <[email protected]>
> >>
> >> string is the pointer variable passed into GetString().
> >> The value of string is not changed by our implementation.
> >>
> >> The UEFI specification allows to call the GetString() service with
> >>
> >> String == NULL && StringLength == 0
> >>
> >> to retrieve the length of the buffer before allocating a buffer for it.
> >> We must not call memcpy() if string is NULL.
> >
> > I am not sure I follow you here. If string is NULL, aren't we exiting
> > really early at the beginning of the function?
> >
> > Thanks
> > /Ilias
> >>
>
> For String == NULL && *StringLength == 0 (I forgot the * above) the term
>
> (*string_size && !string)
>
> is not true and we don't quit with EFI_INVALID_PARAMETER. Instead we
> reach the loop where we look for a string matching the string ID.
But in the case you are describing
len = u16_strsize(str); <---- len is 2
The next if check will succeed since *string_size is 0 and we will
exit with EFI_BUFFER_TOO_SMALL.
Thanks
/Ilias
>
> We even have a test for this in
> lib/efi_selftest/efi_selftest_hii.c:766ff.
>
> Best regards
>
> Heinrich
>
> >>>
> >>>> + memcpy(string, str, len);
> >>>> + ret = EFI_SUCCESS;
> >>>> + goto out;
> >>>> } else {
> >>>> - return EFI_EXIT(EFI_NOT_FOUND);
> >>>> + goto out;
> >>>> }
> >>>> -
> >>>> - return EFI_EXIT(EFI_SUCCESS);
> >>>> }
> >>>> }
> >>>>
> >>>> - return EFI_EXIT(EFI_NOT_FOUND);
> >>>> +out:
> >>>> + return EFI_EXIT(ret);
> >>>> }
> >>>>
> >>>> static efi_status_t EFIAPI
> >>>> --
> >>>> 2.53.0
> >>>>
> >>
>