Commit 7f1b67cd authored by Johan Hovold's avatar Johan Hovold Committed by Greg Kroah-Hartman

greybus: connection: fix protocol tear-down race

Make sure to cancel all active operations before calling protocol
connection_exit to prevent use-after-free issues when the protocol state
is being deallocated (e.g. late processing of already-queued requests or
completions).

Note that already-queued requests or completions will be processed as
part of cancellation.
Signed-off-by: default avatarJohan Hovold <johan@hovoldconsulting.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@google.com>
parent 008974cb
...@@ -232,9 +232,6 @@ static void gb_connection_cancel_operations(struct gb_connection *connection, ...@@ -232,9 +232,6 @@ static void gb_connection_cancel_operations(struct gb_connection *connection,
struct gb_operation *operation; struct gb_operation *operation;
spin_lock_irq(&connection->lock); spin_lock_irq(&connection->lock);
WARN_ON(!list_empty(&connection->operations));
while (!list_empty(&connection->operations)) { while (!list_empty(&connection->operations)) {
operation = list_last_entry(&connection->operations, operation = list_last_entry(&connection->operations,
struct gb_operation, links); struct gb_operation, links);
...@@ -259,8 +256,6 @@ void gb_connection_destroy(struct gb_connection *connection) ...@@ -259,8 +256,6 @@ void gb_connection_destroy(struct gb_connection *connection)
if (WARN_ON(!connection)) if (WARN_ON(!connection))
return; return;
gb_connection_cancel_operations(connection, -ESHUTDOWN);
spin_lock_irq(&gb_connections_lock); spin_lock_irq(&gb_connections_lock);
list_del(&connection->bundle_links); list_del(&connection->bundle_links);
list_del(&connection->hd_links); list_del(&connection->hd_links);
...@@ -334,6 +329,8 @@ void gb_connection_exit(struct gb_connection *connection) ...@@ -334,6 +329,8 @@ void gb_connection_exit(struct gb_connection *connection)
connection->state = GB_CONNECTION_STATE_DESTROYING; connection->state = GB_CONNECTION_STATE_DESTROYING;
spin_unlock_irq(&connection->lock); spin_unlock_irq(&connection->lock);
gb_connection_cancel_operations(connection, -ESHUTDOWN);
connection->protocol->connection_exit(connection); connection->protocol->connection_exit(connection);
/* /*
......
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