[PATCH 1/1] efi_loader: fix efi_initrd_deregister()
Heinrich Schuchardt
heinrich.schuchardt at canonical.com
Fri Sep 30 09:18:50 CEST 2022
On 9/30/22 08:54, Ilias Apalodimas wrote:
> Akashi-san
>
> On Fri, 30 Sept 2022 at 09:41, AKASHI Takahiro
> <takahiro.akashi at linaro.org> wrote:
>>
>> Ilias,
>>
>> On Fri, Sep 30, 2022 at 09:18:35AM +0300, Ilias Apalodimas wrote:
>>> Akashi-san
>>>
>>> On Fri, 30 Sept 2022 at 04:47, AKASHI Takahiro
>>> <takahiro.akashi at linaro.org> wrote:
>>>>
>>>> On Fri, Sep 30, 2022 at 01:57:48AM +0200, Heinrich Schuchardt wrote:
>>>>> Don't try to delete a non-existent handle.
>>>>
>>>> It is okay as a safe guard, but it doesn't fix underlying issues.
>>>
>>> I dont think we safeguard anything. That code path won't try to delete
>>> anything regardless?
I don't like to see a message
"Can't remove invalid handle %p\n"
whenever I return from an EFI binary.
Best regards
Heinrich
>>>
>>>>
>>>> efi_initrd_register() is called only in efi_bootmgr_load(), and so
>>>> efi_initrd_deregister() should be called only at the paired location.
>>>
>>> There's a reason for that.
>>>>
>>>> - Remove efi_initrd_deregister() from do_bootefi_exec()
>>>> - do_efibootmgr() should look like
>>>> efi_bootmgr_load()
>>>> do_bootefi_exec()
>>>> efi_initrd_deregister()
>>>> Otherwise, do_bootefi_exec() always tries to free a handle in
>>>> the other cases (i.e. bootefi <addr>).
>>>>
>>>> Another issue is there in try_load_entry() called by efi_bootmgr_load().
>>>> (after efi_initrd_register())
>>>> if (size) {
>>>> *load_options = malloc(size);
>>>> if (!*load_options) {
>>>> ret = EFI_OUT_OF_RESOURCES;
>>>> goto error;
>>>> }
>>>> ...
>>>>
>>>> If malloc() fails, we should call efi_initrd_deregister() within
>>>> try_load_entry().
>>>>
>>>> Should I submit a patch?
>>>
>>> The whole implementation on the *kernel* assumes the protocol is
>>> present if the file it's pointing is real and existing. You also need
>>> to have a single instance of the protocol installed. IOW if you
>>> install the protocol and the initrd is not there, the kernel won't
>>> fallback on the dt /chosen/ node or the initrd= in the cmdline.
>>
>> Yes, I confirmed that before I made my comment.
>>
>>> The
>>> whole initrd loading logic depends on BootCurrnent, which iirc is not
>>> set yet on the flow you are proposing.
>>
>> I don't get your point.
>>
>> In do_efibootmgr(), what I suggested above is:
>> - efi_bootmgr_load() installs LOAD_FILE2_PROTOCOL if initrd file exists,
>> and if this function fails, LOAD_FILE2_PROTOCOL must be uninstalled any way.
>> - after returning from UEFI app invoked by do_bootefi_exec(),
>> - we should simply uninstall LOAD_FILE2_RPTOCOL by calling efi_initrd_deregister().
>
> You are saying efi_bootmgr_load() installs the protocol., but the
> point here is it's try_load_entry() which installs the protocol,
> because we need BootCurrent to have a valid value before we do that.
>
>>
>> In "bootefi <addr>" case, efi_bootmgr_load() is not called, so
>> LOAD_FILE2_PROTOCOL won't be installed for loading initrd file.
>> Why do we have to call efi_initrd_deregister() in that case?
>
> We don't. FWIW I am not against the cleanup. I am just trying to
> make sure you have all the details in your head before you move
> forward.
>
>>
>> Regarding BootCurrent, I don't think it has nothing to do with the discussion above.
>
> The whole initrd loading and checking code depends on BootCurrent
> being set, so unless the protocol installation is called after
> BootCurrent being set in try_load_entry() it will fail. What that
> code path does is check BootCurrent's LoadOptions. The initrd DP is
> encoded in the FIlePathList (iirc it's on position [1] of that array)
> and that's how it tries to reason about the file being there or not.
>
> Thanks
> /Ilias
>
>> Anyhow it *is* set before reaching "if (size) ...".
>>
>> -Takahiro Akashi
>>
>>
>>> Regards
>>> /Ilias
>>>>
>>>> -Takahiro Akashi
>>>>
>>>>> Signed-off-by: Heinrich Schuchardt <heinrich.schuchardt at canonical.com>
>>>>> ---
>>>>> lib/efi_loader/efi_load_initrd.c | 3 +++
>>>>> 1 file changed, 3 insertions(+)
>>>>>
>>>>> diff --git a/lib/efi_loader/efi_load_initrd.c b/lib/efi_loader/efi_load_initrd.c
>>>>> index c5e6652e66..3d6044f760 100644
>>>>> --- a/lib/efi_loader/efi_load_initrd.c
>>>>> +++ b/lib/efi_loader/efi_load_initrd.c
>>>>> @@ -230,6 +230,9 @@ efi_status_t efi_initrd_register(void)
>>>>> */
>>>>> void efi_initrd_deregister(void)
>>>>> {
>>>>> + if (!efi_initrd_handle)
>>>>> + return;
>>>>> +
>>>>> efi_delete_handle(efi_initrd_handle);
>>>>> efi_initrd_handle = NULL;
>>>>> }
>>>>> --
>>>>> 2.37.2
>>>>>
More information about the U-Boot
mailing list