Akashi-san

On Fri, 30 Sept 2022 at 09:41, AKASHI Takahiro
<[email protected]> 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
> > <[email protected]> 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?
> >
> > >
> > > 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 <[email protected]>
> > > > ---
> > > >  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
> > > >

Reply via email to