efi_loader: error handling in efi_disk_add_dev

* If an error occurs in efi_disk_add_dev(), don't leak resources.
* If calloc() fails while creating the file system protocol interface,
  signal an error.
* Rename efi_simple_file_system() to efi_create_simple_file_system().
* Drop a little helpful debug message.

Fixes: 2a92080d8c ("efi_loader: add file/filesys support")
Signed-off-by: Heinrich Schuchardt <heinrich.schuchardt@canonical.com>
Reviewed-by: Ilias Apalodimas <ilias.apalodimas@linaro.org>
This commit is contained in:
Heinrich Schuchardt 2023-07-30 14:03:53 +02:00
parent ecae4bbf35
commit cff7700170
3 changed files with 32 additions and 13 deletions

View file

@ -696,9 +696,21 @@ void efi_signal_event(struct efi_event *event);
/* return true if the device is removable */ /* return true if the device is removable */
bool efi_disk_is_removable(efi_handle_t handle); bool efi_disk_is_removable(efi_handle_t handle);
/* open file system: */ /**
struct efi_simple_file_system_protocol *efi_simple_file_system( * efi_create_simple_file_system() - create simple file system protocol
struct blk_desc *desc, int part, struct efi_device_path *dp); *
* Create a simple file system protocol for a partition.
*
* @desc: block device descriptor
* @part: partition number
* @dp: device path
* @fsp: simple file system protocol
* Return: status code
*/
efi_status_t
efi_create_simple_file_system(struct blk_desc *desc, int part,
struct efi_device_path *dp,
struct efi_simple_file_system_protocol **fsp);
/* open file from device-path: */ /* open file from device-path: */
struct efi_file_handle *efi_file_from_path(struct efi_device_path *fp); struct efi_file_handle *efi_file_from_path(struct efi_device_path *fp);

View file

@ -487,15 +487,16 @@ static efi_status_t efi_disk_add_dev(
*/ */
if ((part || desc->part_type == PART_TYPE_UNKNOWN) && if ((part || desc->part_type == PART_TYPE_UNKNOWN) &&
efi_fs_exists(desc, part)) { efi_fs_exists(desc, part)) {
diskobj->volume = efi_simple_file_system(desc, part, ret = efi_create_simple_file_system(desc, part, diskobj->dp,
diskobj->dp); &diskobj->volume);
if (ret != EFI_SUCCESS)
goto error;
ret = efi_add_protocol(&diskobj->header, ret = efi_add_protocol(&diskobj->header,
&efi_simple_file_system_protocol_guid, &efi_simple_file_system_protocol_guid,
diskobj->volume); diskobj->volume);
if (ret != EFI_SUCCESS) { if (ret != EFI_SUCCESS)
log_debug("simple FS failed\n"); goto error;
return ret;
}
} }
diskobj->ops = block_io_disk_template; diskobj->ops = block_io_disk_template;
diskobj->dev_index = dev_index; diskobj->dev_index = dev_index;
@ -538,6 +539,8 @@ static efi_status_t efi_disk_add_dev(
return EFI_SUCCESS; return EFI_SUCCESS;
error: error:
efi_delete_handle(&diskobj->header); efi_delete_handle(&diskobj->header);
free(diskobj->volume);
free(diskobj);
return ret; return ret;
} }

View file

@ -1192,18 +1192,22 @@ efi_open_volume(struct efi_simple_file_system_protocol *this,
return EFI_EXIT(efi_open_volume_int(this, root)); return EFI_EXIT(efi_open_volume_int(this, root));
} }
struct efi_simple_file_system_protocol * efi_status_t
efi_simple_file_system(struct blk_desc *desc, int part, efi_create_simple_file_system(struct blk_desc *desc, int part,
struct efi_device_path *dp) struct efi_device_path *dp,
struct efi_simple_file_system_protocol **fsp)
{ {
struct file_system *fs; struct file_system *fs;
fs = calloc(1, sizeof(*fs)); fs = calloc(1, sizeof(*fs));
if (!fs)
return EFI_OUT_OF_RESOURCES;
fs->base.rev = EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_REVISION; fs->base.rev = EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_REVISION;
fs->base.open_volume = efi_open_volume; fs->base.open_volume = efi_open_volume;
fs->desc = desc; fs->desc = desc;
fs->part = part; fs->part = part;
fs->dp = dp; fs->dp = dp;
*fsp = &fs->base;
return &fs->base; return EFI_SUCCESS;
} }