diff options
author | Johan Hovold <johan@hovoldconsulting.com> | 2015-07-09 15:18:00 +0200 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@google.com> | 2015-07-13 15:29:27 -0700 |
commit | 048a7ffe274280c27fc572ba3ec7150eba6efc40 (patch) | |
tree | 7e6c096e6fee721bf8af089389377c2d7e7affe6 /drivers/staging/greybus/operation.c | |
parent | 0581f28efb86d8eb7e7f6baf712578477f7c868e (diff) |
greybus: operation: fix outgoing-response corruption
Fix potential corruption of outgoing responses by verifying that the
operations is indeed outgoing when receiving a response.
Failure to do so could lead to an incoming response corrupting an
outgoing response that uses the same operation id.
Reported-by: Viresh Kumar <viresh.kumar@linaro.org>
Reviewed-by: Viresh Kumar <viresh.kumar@linaro.org>
Signed-off-by: Johan Hovold <johan@hovoldconsulting.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
Diffstat (limited to 'drivers/staging/greybus/operation.c')
-rw-r--r-- | drivers/staging/greybus/operation.c | 11 |
1 files changed, 6 insertions, 5 deletions
diff --git a/drivers/staging/greybus/operation.c b/drivers/staging/greybus/operation.c index 8f99c8e17d70..85394624395e 100644 --- a/drivers/staging/greybus/operation.c +++ b/drivers/staging/greybus/operation.c @@ -115,11 +115,11 @@ int gb_operation_result(struct gb_operation *operation) EXPORT_SYMBOL_GPL(gb_operation_result); /* - * Looks up an operation on a connection and returns a refcounted pointer if - * found, or NULL otherwise. + * Looks up an outgoing operation on a connection and returns a refcounted + * pointer if found, or NULL otherwise. */ static struct gb_operation * -gb_operation_find(struct gb_connection *connection, u16 operation_id) +gb_operation_find_outgoing(struct gb_connection *connection, u16 operation_id) { struct gb_operation *operation; unsigned long flags; @@ -127,7 +127,8 @@ gb_operation_find(struct gb_connection *connection, u16 operation_id) spin_lock_irqsave(&gb_operations_lock, flags); list_for_each_entry(operation, &connection->operations, links) - if (operation->id == operation_id) { + if (operation->id == operation_id && + !gb_operation_is_incoming(operation)) { gb_operation_get(operation); found = true; break; @@ -778,7 +779,7 @@ static void gb_connection_recv_response(struct gb_connection *connection, int errno = gb_operation_status_map(result); size_t message_size; - operation = gb_operation_find(connection, operation_id); + operation = gb_operation_find_outgoing(connection, operation_id); if (!operation) { dev_err(&connection->dev, "operation not found\n"); return; |