kdbus: fix async reply refcount leaks
authorKonrad Lipinski <konrad.l@samsung.com>
Thu, 17 Nov 2016 13:53:22 +0000 (14:53 +0100)
committerAdrian Szyndela <adrian.s@samsung.com>
Wed, 7 Aug 2019 14:32:42 +0000 (16:32 +0200)
ipc/kdbus/connection.c
ipc/kdbus/domain.c
ipc/kdbus/queue.c

index 1a2d9fe7fb4796ae5f477335003f3941f1b52ed2..03c26a31f5bb8bbc0b9de2d1158fc33d1cd969ca 100644 (file)
@@ -2106,7 +2106,10 @@ int kdbus_cmd_recv(struct kdbus_conn *conn, void __user *argp)
        if (!entry) {
                mutex_unlock(&conn->lock);
                ret = -EAGAIN;
-       } else if (cmd->flags & KDBUS_RECV_DROP) {
+               goto exit;
+       }
+
+       if (cmd->flags & KDBUS_RECV_DROP) {
                var(reply_state, entry->reply_state);
                bool freeReply = true;
                kdbus_queue_entry_destroy(entry, conn);
index 493b5ce0e278b121fa61e3479e16184e64929929..ea669e8f5c48324d1629cd5aed74567540e7b08c 100644 (file)
@@ -250,8 +250,8 @@ static void __kdbus_user_free(struct kref *kref)
 {
        struct kdbus_user *user = container_of(kref, struct kdbus_user, kref);
 
-       kdbus_assert(atomic_read(&user->buses) <= 0);
-       kdbus_assert(atomic_read(&user->connections) <= 0);
+       kdbus_assert(!atomic_read(&user->buses));
+       kdbus_assert(!atomic_read(&user->connections));
 
        mutex_lock(&user->domain->lock);
        ida_simple_remove(&user->domain->user_ida, user->id);
index 902f68787e8bb1669b46b9766960ba7d18d869b6..6bac1f5bd0e4719247d3c394941da242f28aa5af 100644 (file)
@@ -283,7 +283,7 @@ void kdbus_queue_entry_free(struct kdbus_queue_entry *__restrict__ entry, struct
        if (0 > (reply_state = entry->reply_state)) /* never had a reply */
                kmem_cache_free(queue_entry_cachep, entry);
        else if (!reply_state) /* finalized reply */
-               kmem_cache_free(kdbus_reply_cachep, container_of(entry, struct kdbus_reply, queue_entry));
+               kdbus_reply_free(container_of(entry, struct kdbus_reply, queue_entry));
        else { /* just dequeued a message requiring reply -> move it to dequeued_reply_list */
                var(r, container_of(entry, struct kdbus_reply, queue_entry));
                if (!entry->sync)