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 <johan@hovoldconsulting.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
This commit is contained in:
Johan Hovold 2015-07-14 15:43:33 +02:00 committed by Greg Kroah-Hartman
parent 7f1b67cd53
commit 3325a4ad71

View File

@ -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;