efi_loader: avoid pointer access after calling efi_delete_handle
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. This commit also removes the container_of() calls, and adds the TODO comment of missing efi_close_protocol() call for the parent EFI_BLOCK_IO_PROTOCOL. Signed-off-by: Masahisa Kojima <masahisa.kojima@linaro.org> Reviewed-by: Ilias Apalodimas <ilias.apalodimas@linaro.org>
This commit is contained in:
committed by
Heinrich Schuchardt
parent
3f7822bf9f
commit
f674a2f9a9
@@ -707,7 +707,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))
|
||||
@@ -718,24 +720,30 @@ int efi_disk_remove(void *ctx, struct event *event)
|
||||
case UCLASS_BLK:
|
||||
desc = dev_get_uclass_plat(dev);
|
||||
if (desc && desc->uclass_id != UCLASS_EFI_LOADER)
|
||||
diskobj = container_of(handle, struct efi_disk_obj,
|
||||
header);
|
||||
diskobj = (struct efi_disk_obj *)handle;
|
||||
break;
|
||||
case UCLASS_PARTITION:
|
||||
diskobj = container_of(handle, struct efi_disk_obj, header);
|
||||
diskobj = (struct efi_disk_obj *)handle;
|
||||
|
||||
/* TODO: closing the parent EFI_BLOCK_IO_PROTOCOL is missing. */
|
||||
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (diskobj) {
|
||||
dp = diskobj->dp;
|
||||
volume = diskobj->volume;
|
||||
}
|
||||
|
||||
ret = efi_delete_handle(handle);
|
||||
/* 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;
|
||||
|
||||
Reference in New Issue
Block a user