discover/event: Ensure event struct exists for async callers
diff mbox

Message ID 20160901052842.22680-1-sam@mendozajonas.com
State Accepted
Headers show

Commit Message

Samuel Mendoza-Jonas Sept. 1, 2016, 5:28 a.m. UTC
When handling an event, user_event_handle_message() creates an event
struct with relevant parameters. Once user_event_handle_message() is
finished it frees the struct.
However in the case of a dhcp or add_url event, asynchronous jobs may be
spawned that will later reference the event struct. In particular this
becomes a problem when pxe_process_pair() handles an IPAPPEND name/value
pair and tries to access event->device.

In the case of dhcp and add_url events, we avoid this by changing the
event struct's talloc parent to the discover_context struct which
persists until all async pxe jobs have completed.

Signed-off-by: Samuel Mendoza-Jonas <sam@mendozajonas.com>
---
 discover/device-handler.c | 2 ++
 discover/user-event.c     | 8 +++++---
 2 files changed, 7 insertions(+), 3 deletions(-)

Patch
diff mbox

diff --git a/discover/device-handler.c b/discover/device-handler.c
index f6b6d22..346cb02 100644
--- a/discover/device-handler.c
+++ b/discover/device-handler.c
@@ -900,6 +900,7 @@  int device_handler_dhcp(struct device_handler *handler,
 
 	/* create our context */
 	ctx = device_handler_discover_context_create(handler, dev);
+	talloc_steal(ctx, event);
 	ctx->event = event;
 
 	iterate_parsers(ctx);
@@ -1171,6 +1172,7 @@  void device_handler_process_url(struct device_handler *handler,
 	if (pb_url->scheme == pb_url_file)
 		dev->device->type = DEVICE_TYPE_ANY;
 	ctx = device_handler_discover_context_create(handler, dev);
+	talloc_steal(ctx, event);
 	ctx->event = event;
 
 	iterate_parsers(ctx);
diff --git a/discover/user-event.c b/discover/user-event.c
index 6ea754f..3ccac90 100644
--- a/discover/user-event.c
+++ b/discover/user-event.c
@@ -513,13 +513,13 @@  static void user_event_handle_message(struct user_event *uev, char *buf,
 		break;
 	case EVENT_ACTION_URL:
 		result = user_event_url(uev, event);
-		break;
+		goto out;
 	case EVENT_ACTION_CONF:
 		result = user_event_conf(uev, event);
 		break;
 	case EVENT_ACTION_DHCP:
 		result = user_event_dhcp(uev, event);
-		break;
+		goto out;
 	case EVENT_ACTION_BOOT:
 		result = user_event_boot(uev, event);
 		break;
@@ -530,8 +530,10 @@  static void user_event_handle_message(struct user_event *uev, char *buf,
 		break;
 	}
 
+	/* user_event_url() and user_event_dhcp() will steal the event context,
+	 * but all others still need to free */
 	talloc_free(event);
-
+out:
 	return;
 }