[PATCH 2/3] efi_loader: avoid pointer access after calling efi_delete_handle

Masahisa Kojima masahisa.kojima at linaro.org
Tue Dec 26 02:13:08 CET 2023


Hi Heinrich,

On Mon, 25 Dec 2023 at 19:05, Heinrich Schuchardt <xypron.glpk at gmx.de> wrote:
>
> On 12/25/23 05:43, Masahisa Kojima wrote:
> > efi_delete_handle() calls efi_purge_handle(), then it finally
> > frees the efi handle.
> > Both diskobj and handle variables in efi_disk_remove() have
> > the same pointer, we can not access diskobj->dp after calling
> > efi_delete_handle().
> >
> > This commit saves the struct efi_device_path pointer before
> > calling efi_delete_handle(). This commit also fixes the
> > missing free for volume member in struct efi_disk_obj.
> >
> > Signed-off-by: Masahisa Kojima <masahisa.kojima at linaro.org>
> > ---
> >   lib/efi_loader/efi_disk.c | 12 +++++++++---
> >   1 file changed, 9 insertions(+), 3 deletions(-)
> >
> > diff --git a/lib/efi_loader/efi_disk.c b/lib/efi_loader/efi_disk.c
> > index a2f8b531a3..415d8601ba 100644
> > --- a/lib/efi_loader/efi_disk.c
> > +++ b/lib/efi_loader/efi_disk.c
> > @@ -701,7 +701,9 @@ int efi_disk_remove(void *ctx, struct event *event)
> >       struct udevice *dev = event->data.dm.dev;
> >       efi_handle_t handle;
> >       struct blk_desc *desc;
> > +     struct efi_device_path *dp = NULL;
> >       struct efi_disk_obj *diskobj = NULL;
> > +     struct efi_simple_file_system_protocol *volume = NULL;
> >       efi_status_t ret;
> >
> >       if (dev_tag_get_ptr(dev, DM_TAG_EFI, (void **)&handle))
> > @@ -722,14 +724,18 @@ int efi_disk_remove(void *ctx, struct event *event)
> >               return 0;
> >       }
> >
> > +     if (diskobj) {
>
>
>    diskobj = container_of(handle, struct efi_disk_obj, header);
>
> can be replaced by
>
>    diskobj = handle
>
> We should check the handle immediately after dev_tag_get_ptr() and
> return 0 if the handle == NULL.

OK, I will try to improve the efi_disk_remove() function.

>
> > +             dp = diskobj->dp;
> > +             volume = diskobj->volume;
> > +     }
> > +
> >       ret = efi_delete_handle(handle);
>
> We must not delete the handle in case of UCLASS_EFI_LOADER.
>
> Instead of calling efi_delete_handle we should uninstall all protocols
> that we have installed. If no protocol is left the handle will go away.
>
> To make the protocols to delete tractable they should be opened with
> BY_DRIVER.

efi_delete_handle() calls efi_remove_all_protocols(), and frees the efi handle
if no protocol is left on the handle.
So I think efi_delete_handle() does all the required processes mentioned above.

>
> When a partition is removed we must close the protocol interfaces opened
> with EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER (cf. efi_disk_add_dev()).

OK, I will fix this.

Thanks,
Masahisa Kojima

>
> Best regards
>
> Heinrich
>
> >       /* Do not delete DM device if there are still EFI drivers attached. */
> >       if (ret != EFI_SUCCESS)
> >               return -1;
> >
> > -     if (diskobj)
> > -             efi_free_pool(diskobj->dp);
> > -
> > +     efi_free_pool(dp);
> > +     free(volume);
> >       dev_tag_del(dev, DM_TAG_EFI);
> >
> >       return 0;
>


More information about the U-Boot mailing list