discover/boot: Safely cleanup after failed load
authorSam Mendoza-Jonas <sam@mendozajonas.com>
Tue, 15 Mar 2016 02:35:21 +0000 (13:35 +1100)
committerSamuel Mendoza-Jonas <sam@mendozajonas.com>
Tue, 22 Mar 2016 22:02:35 +0000 (09:02 +1100)
If a call to load_url_async() fails immediately, boot() will free the
boot task and return. If other jobs started by load_url_async()
are still running they will attempt to free their task struct in
load_url_process_exit(), however the original boot task is the parent
context of this process task, resulting in a double-free.

Instead call cleanup_cancellations if an error immediately occurs to
cancel any pending load operations safely before freeing the boot task.

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

index 7778b3fd02bc21f588e260e08cb888d20b4a266a..0d3491fd6cb4a61ece94b3bb5c700ff36cb69841 100644 (file)
@@ -486,9 +486,10 @@ struct boot_task *boot(void *ctx, struct discover_boot_option *opt,
          || start_url_load(boot_task, "initrd", initrd, &boot_task->initrd)
          || start_url_load(boot_task, "dtb", dtb, &boot_task->dtb);
 
-       /* If all URLs are local, we may be done. */
        if (rc) {
-               talloc_free(boot_task);
+               /* Don't call boot_cancel() to preserve the status update */
+               boot_task->cancelled = true;
+               cleanup_cancellations(boot_task, NULL);
                return NULL;
        }