From c8c61f78d0583acedcde0ba69b57936bf27337ca Mon Sep 17 00:00:00 2001 From: Samuel Mendoza-Jonas Date: Thu, 1 Sep 2016 14:32:03 +1000 Subject: discover/event: Ensure event struct exists for async callers 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 (cherry picked from commit a50d5fe279db71cf85fabeb675c99b167ec63dcb) --- discover/device-handler.c | 2 ++ discover/user-event.c | 8 +++++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/discover/device-handler.c b/discover/device-handler.c index c31fcea..364b412 100644 --- a/discover/device-handler.c +++ b/discover/device-handler.c @@ -894,6 +894,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); @@ -1165,6 +1166,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 7350b6c..d9f5bd4 100644 --- a/discover/user-event.c +++ b/discover/user-event.c @@ -503,13 +503,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; @@ -520,8 +520,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; } -- cgit v1.2.1