efi_loader: error handling in efi_disk_add_dev
authorHeinrich Schuchardt <heinrich.schuchardt@canonical.com>
Sun, 30 Jul 2023 12:03:53 +0000 (14:03 +0200)
committerHeinrich Schuchardt <heinrich.schuchardt@canonical.com>
Thu, 3 Aug 2023 07:21:03 +0000 (09:21 +0200)
* 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: 2a92080d8c44 ("efi_loader: add file/filesys support")
Signed-off-by: Heinrich Schuchardt <heinrich.schuchardt@canonical.com>
Reviewed-by: Ilias Apalodimas <ilias.apalodimas@linaro.org>
include/efi_loader.h
lib/efi_loader/efi_disk.c
lib/efi_loader/efi_file.c

index 3a64eb9..4a29dda 100644 (file)
@@ -696,9 +696,21 @@ void efi_signal_event(struct efi_event *event);
 /* return true if the device is removable */
 bool efi_disk_is_removable(efi_handle_t handle);
 
-/* open file system: */
-struct efi_simple_file_system_protocol *efi_simple_file_system(
-               struct blk_desc *desc, int part, struct efi_device_path *dp);
+/**
+ * efi_create_simple_file_system() - create simple file system protocol
+ *
+ * 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: */
 struct efi_file_handle *efi_file_from_path(struct efi_device_path *fp);
index 46cb570..f0d7611 100644 (file)
@@ -487,15 +487,16 @@ static efi_status_t efi_disk_add_dev(
         */
        if ((part || desc->part_type == PART_TYPE_UNKNOWN) &&
            efi_fs_exists(desc, part)) {
-               diskobj->volume = efi_simple_file_system(desc, part,
-                                                        diskobj->dp);
+               ret = efi_create_simple_file_system(desc, part, diskobj->dp,
+                                                   &diskobj->volume);
+               if (ret != EFI_SUCCESS)
+                       goto error;
+
                ret = efi_add_protocol(&diskobj->header,
                                       &efi_simple_file_system_protocol_guid,
                                       diskobj->volume);
-               if (ret != EFI_SUCCESS) {
-                       log_debug("simple FS failed\n");
-                       return ret;
-               }
+               if (ret != EFI_SUCCESS)
+                       goto error;
        }
        diskobj->ops = block_io_disk_template;
        diskobj->dev_index = dev_index;
@@ -538,6 +539,8 @@ static efi_status_t efi_disk_add_dev(
        return EFI_SUCCESS;
 error:
        efi_delete_handle(&diskobj->header);
+       free(diskobj->volume);
+       free(diskobj);
        return ret;
 }
 
index 520c730..3764a92 100644 (file)
@@ -1192,18 +1192,22 @@ efi_open_volume(struct efi_simple_file_system_protocol *this,
        return EFI_EXIT(efi_open_volume_int(this, root));
 }
 
-struct efi_simple_file_system_protocol *
-efi_simple_file_system(struct blk_desc *desc, int part,
-                      struct efi_device_path *dp)
+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)
 {
        struct file_system *fs;
 
        fs = calloc(1, sizeof(*fs));
+       if (!fs)
+               return EFI_OUT_OF_RESOURCES;
        fs->base.rev = EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_REVISION;
        fs->base.open_volume = efi_open_volume;
        fs->desc = desc;
        fs->part = part;
        fs->dp = dp;
+       *fsp = &fs->base;
 
-       return &fs->base;
+       return EFI_SUCCESS;
 }