Commit 048a7ffe authored by Johan Hovold's avatar Johan Hovold Committed by Greg Kroah-Hartman

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: default avatarViresh Kumar <viresh.kumar@linaro.org>
Reviewed-by: default avatarViresh Kumar <viresh.kumar@linaro.org>
Signed-off-by: default avatarJohan Hovold <johan@hovoldconsulting.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@google.com>
parent 0581f28e
...@@ -115,11 +115,11 @@ int gb_operation_result(struct gb_operation *operation) ...@@ -115,11 +115,11 @@ int gb_operation_result(struct gb_operation *operation)
EXPORT_SYMBOL_GPL(gb_operation_result); EXPORT_SYMBOL_GPL(gb_operation_result);
/* /*
* Looks up an operation on a connection and returns a refcounted pointer if * Looks up an outgoing operation on a connection and returns a refcounted
* found, or NULL otherwise. * pointer if found, or NULL otherwise.
*/ */
static struct gb_operation * 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; struct gb_operation *operation;
unsigned long flags; unsigned long flags;
...@@ -127,7 +127,8 @@ gb_operation_find(struct gb_connection *connection, u16 operation_id) ...@@ -127,7 +127,8 @@ gb_operation_find(struct gb_connection *connection, u16 operation_id)
spin_lock_irqsave(&gb_operations_lock, flags); spin_lock_irqsave(&gb_operations_lock, flags);
list_for_each_entry(operation, &connection->operations, links) 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); gb_operation_get(operation);
found = true; found = true;
break; break;
...@@ -778,7 +779,7 @@ static void gb_connection_recv_response(struct gb_connection *connection, ...@@ -778,7 +779,7 @@ static void gb_connection_recv_response(struct gb_connection *connection,
int errno = gb_operation_status_map(result); int errno = gb_operation_status_map(result);
size_t message_size; size_t message_size;
operation = gb_operation_find(connection, operation_id); operation = gb_operation_find_outgoing(connection, operation_id);
if (!operation) { if (!operation) {
dev_err(&connection->dev, "operation not found\n"); dev_err(&connection->dev, "operation not found\n");
return; return;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment