From 3325a4ad7122acdbfae5360cafc7152b32eefd57 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Tue, 14 Jul 2015 15:43:33 +0200 Subject: [PATCH] greybus: operation: fix operation look-up race Make sure to fully initialise the operation before adding it to the active list when sending a request. The operation should be fully initialised before adding it to the active list to avoid racing with operation look up when receiving a response, something which could potentially lead to a match against some earlier (or intermediate) value of the id field. Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/staging/greybus/operation.c | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/drivers/staging/greybus/operation.c b/drivers/staging/greybus/operation.c index 5cd4665c645c..f7b0aa970bbc 100644 --- a/drivers/staging/greybus/operation.c +++ b/drivers/staging/greybus/operation.c @@ -642,16 +642,6 @@ int gb_operation_request_send(struct gb_operation *operation, if (!callback) return -EINVAL; - - /* - * First, get an extra reference on the operation. - * It'll be dropped when the operation completes. - */ - gb_operation_get(operation); - ret = gb_operation_get_active(operation); - if (ret) - goto err_put; - /* * Record the callback function, which is executed in * non-atomic (workqueue) context when the final result @@ -668,9 +658,17 @@ int gb_operation_request_send(struct gb_operation *operation, header = operation->request->header; header->operation_id = cpu_to_le16(operation->id); - /* All set, send the request */ gb_operation_result_set(operation, -EINPROGRESS); + /* + * Get an extra reference on the operation. It'll be dropped when the + * operation completes. + */ + gb_operation_get(operation); + ret = gb_operation_get_active(operation); + if (ret) + goto err_put; + ret = gb_message_send(operation->request, gfp); if (ret) goto err_put_active;