discover/boot: Fix stale boot cancellation code v1.7.1
authorSamuel Mendoza-Jonas <sam@mendozajonas.com>
Tue, 6 Mar 2018 05:44:44 +0000 (16:44 +1100)
committerSamuel Mendoza-Jonas <sam@mendozajonas.com>
Wed, 7 Mar 2018 05:24:31 +0000 (16:24 +1100)
In dc85de97 "Allow load_async_url() to call callback for local paths"
several load_url_result fields of the boot_task struct were deprecated
but were accidentally left in the struct. This caused the now out of
date code in cleanup_cancellations() to go unnoticed since it can return
safely if these fields are NULL. However freeing the boot task can free
the memory associated with each load before it is complete, resulting in
a confusing segfault.

This brings cleanup_cancellations() up to date and along the way
implicitly includes the signature resources in cleanup which were missed
originally.

Signed-off-by: Samuel Mendoza-Jonas <sam@mendozajonas.com>
discover/boot.c
discover/boot.h

index 1e010ab1ebc316e6a13a0ef588abe4ff9ed9330d..0da40e3d8f4b11d6f13b20c2147ef5a3dfd521a3 100644 (file)
@@ -362,15 +362,14 @@ static void cleanup_load(struct load_url_result *result)
 static void cleanup_cancellations(struct boot_task *task,
                struct load_url_result *cur_result)
 {
-       struct load_url_result *result, **results[] = {
-               &task->image, &task->initrd, &task->dtb,
-       };
+       struct boot_resource *resource;
+       struct load_url_result *result;
        bool pending = false;
-       unsigned int i;
 
-       for (i = 0; i < ARRAY_SIZE(results); i++) {
-               result = *results[i];
+       list_for_each_entry(&task->resources, resource, list) {
+               result = resource->result;
 
+               /* Nothing to do if a load hasn't actually started yet */
                if (!result)
                        continue;
 
@@ -378,9 +377,6 @@ static void cleanup_cancellations(struct boot_task *task,
                if (result == cur_result || result->status == LOAD_OK
                                || result->status == LOAD_ERROR) {
                        cleanup_load(result);
-                       talloc_free(result);
-                       *results[i] = NULL;
-
                /* ... and cancel any pending loads, which we'll free in
                 * the completion callback */
                } else if (result->status == LOAD_ASYNC) {
index 0f3dcf7cdbf246ebd04da62f29c736dc487b5cea..7fe285b7b831c3c5ec7e33ea7474e7b48287c4a3 100644 (file)
@@ -16,9 +16,6 @@ struct boot_task *boot(void *ctx, struct discover_boot_option *opt,
 void boot_cancel(struct boot_task *task);
 
 struct boot_task {
-       struct load_url_result *image;
-       struct load_url_result *initrd;
-       struct load_url_result *dtb;
        const char *local_image;
        const char *local_initrd;
        const char *local_dtb;
@@ -33,10 +30,6 @@ struct boot_task {
        bool cancelled;
        bool verify_signature;
        bool decrypt_files;
-       struct load_url_result *image_signature;
-       struct load_url_result *initrd_signature;
-       struct load_url_result *dtb_signature;
-       struct load_url_result *cmdline_signature;
        const char *local_image_signature;
        const char *local_initrd_signature;
        const char *local_dtb_signature;