binder: fix use-after-free discovered with KASAN

In binder_transaction() it is unsafe to dereference the
transaction pointer after enqueing the request since it
can be consumed and freed immediately. t->flags was being
dereferenced after the enqueue. The code was changed to
do this flag check prior to enqueuing the transaction.

Bug: 35843398
Change-Id: I3c015859eaf1ff87015dedd8f8cb7cd1a9a9a2e4
Test: Verified fixed using KASAN kernel
Signed-off-by: Todd Kjos <tkjos@google.com>
This commit is contained in:
Todd Kjos
2017-02-28 16:07:08 -08:00
committed by Thierry Strudel
parent b31b594bd1
commit 8b8d920edd

View File

@@ -1770,6 +1770,7 @@ static void binder_transaction(struct binder_proc *proc,
struct binder_buffer_object *last_fixup_obj = NULL;
binder_size_t last_fixup_min_off = 0;
struct binder_context *context = proc->context;
bool oneway;
e = binder_transaction_log_add(&binder_transaction_log);
e->call_type = reply ? 2 : !!(tr->flags & TF_ONE_WAY);
@@ -2122,6 +2123,7 @@ static void binder_transaction(struct binder_proc *proc,
t->work.type = BINDER_WORK_TRANSACTION;
tcomplete->type = BINDER_WORK_TRANSACTION_COMPLETE;
binder_enqueue_work(tcomplete, &thread->todo, __LINE__);
oneway = !!(t->flags & TF_ONE_WAY);
if (reply) {
BUG_ON(t->buffer->async_transaction != 0);
@@ -2164,7 +2166,7 @@ static void binder_transaction(struct binder_proc *proc,
READ_ONCE(target_thread->waiting_for_proc_work)))
wake_up_interruptible_all(&target_proc->wait);
if (reply || !(t->flags & TF_ONE_WAY))
if (reply || !oneway)
wake_up_interruptible_sync(target_wait);
else
wake_up_interruptible(target_wait);