]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
greybus: connection: fix protocol tear-down race
authorJohan Hovold <johan@hovoldconsulting.com>
Tue, 14 Jul 2015 13:43:32 +0000 (15:43 +0200)
committerGreg Kroah-Hartman <gregkh@google.com>
Wed, 15 Jul 2015 19:39:13 +0000 (12:39 -0700)
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: Johan Hovold <johan@hovoldconsulting.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
drivers/staging/greybus/connection.c

index 2d19082a7f35e8b09828c94c91d35d4a17d095f2..ac9b2d1748058317f9878962b0e4a5536e041c92 100644 (file)
@@ -232,9 +232,6 @@ static void gb_connection_cancel_operations(struct gb_connection *connection,
        struct gb_operation *operation;
 
        spin_lock_irq(&connection->lock);
-
-       WARN_ON(!list_empty(&connection->operations));
-
        while (!list_empty(&connection->operations)) {
                operation = list_last_entry(&connection->operations,
                                                struct gb_operation, links);
@@ -259,8 +256,6 @@ void gb_connection_destroy(struct gb_connection *connection)
        if (WARN_ON(!connection))
                return;
 
-       gb_connection_cancel_operations(connection, -ESHUTDOWN);
-
        spin_lock_irq(&gb_connections_lock);
        list_del(&connection->bundle_links);
        list_del(&connection->hd_links);
@@ -334,6 +329,8 @@ void gb_connection_exit(struct gb_connection *connection)
        connection->state = GB_CONNECTION_STATE_DESTROYING;
        spin_unlock_irq(&connection->lock);
 
+       gb_connection_cancel_operations(connection, -ESHUTDOWN);
+
        connection->protocol->connection_exit(connection);
 
        /*