[PATCH] discover/boot: Fix stale boot cancellation code

Samuel Mendoza-Jonas sam at mendozajonas.com
Tue Mar 6 16:44:44 AEDT 2018


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 at mendozajonas.com>
---
 discover/boot.c | 14 +++++---------
 discover/boot.h |  7 -------
 2 files changed, 5 insertions(+), 16 deletions(-)

diff --git a/discover/boot.c b/discover/boot.c
index 1e010ab..0da40e3 100644
--- a/discover/boot.c
+++ b/discover/boot.c
@@ -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) {
diff --git a/discover/boot.h b/discover/boot.h
index 0f3dcf7..7fe285b 100644
--- a/discover/boot.h
+++ b/discover/boot.h
@@ -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;
-- 
2.16.2



More information about the Petitboot mailing list