3.4-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Arve Hjønnevåg <a...@android.com>

commit 675d66b0ed5fd170d6a44cf8dbb3fa56a5347bdb upstream.

If a thread or process exited while a reply, one-way transaction or
death notification was pending, the struct holding the pending work
was leaked.

Signed-off-by: Arve Hjønnevåg <a...@android.com>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>

---
 drivers/staging/android/binder.c |   28 +++++++++++++++++++++++++++-
 1 file changed, 27 insertions(+), 1 deletion(-)

--- a/drivers/staging/android/binder.c
+++ b/drivers/staging/android/binder.c
@@ -2507,14 +2507,38 @@ static void binder_release_work(struct l
                        struct binder_transaction *t;
 
                        t = container_of(w, struct binder_transaction, work);
-                       if (t->buffer->target_node && !(t->flags & TF_ONE_WAY))
+                       if (t->buffer->target_node &&
+                           !(t->flags & TF_ONE_WAY)) {
                                binder_send_failed_reply(t, BR_DEAD_REPLY);
+                       } else {
+                               binder_debug(BINDER_DEBUG_DEAD_TRANSACTION,
+                                       "binder: undelivered transaction %d\n",
+                                       t->debug_id);
+                               t->buffer->transaction = NULL;
+                               kfree(t);
+                               binder_stats_deleted(BINDER_STAT_TRANSACTION);
+                       }
                } break;
                case BINDER_WORK_TRANSACTION_COMPLETE: {
+                       binder_debug(BINDER_DEBUG_DEAD_TRANSACTION,
+                               "binder: undelivered TRANSACTION_COMPLETE\n");
                        kfree(w);
                        binder_stats_deleted(BINDER_STAT_TRANSACTION_COMPLETE);
                } break;
+               case BINDER_WORK_DEAD_BINDER_AND_CLEAR:
+               case BINDER_WORK_CLEAR_DEATH_NOTIFICATION: {
+                       struct binder_ref_death *death;
+
+                       death = container_of(w, struct binder_ref_death, work);
+                       binder_debug(BINDER_DEBUG_DEAD_TRANSACTION,
+                               "binder: undelivered death notification, %p\n",
+                               death->cookie);
+                       kfree(death);
+                       binder_stats_deleted(BINDER_STAT_DEATH);
+               } break;
                default:
+                       pr_err("binder: unexpected work type, %d, not freed\n",
+                              w->type);
                        break;
                }
        }
@@ -2984,6 +3008,7 @@ static void binder_deferred_release(stru
                nodes++;
                rb_erase(&node->rb_node, &proc->nodes);
                list_del_init(&node->work.entry);
+               binder_release_work(&node->async_todo);
                if (hlist_empty(&node->refs)) {
                        kfree(node);
                        binder_stats_deleted(BINDER_STAT_NODE);
@@ -3022,6 +3047,7 @@ static void binder_deferred_release(stru
                binder_delete_ref(ref);
        }
        binder_release_work(&proc->todo);
+       binder_release_work(&proc->delivered_death);
        buffers = 0;
 
        while ((n = rb_first(&proc->allocated_buffers))) {


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to