Skip to content

Commit 5e8a3d0

Browse files
Carlos Llamasgregkh
authored andcommitted
binder: fix UAF in binder_netlink_report()
Oneway transactions sent to frozen targets via binder_proc_transaction() return a BR_TRANSACTION_PENDING_FROZEN error but they are still treated as successful since the target is expected to thaw at some point. It is then not safe to access 't' after BR_TRANSACTION_PENDING_FROZEN errors as the transaction could have been consumed by the now thawed target. This is the case for binder_netlink_report() which derreferences 't' after a pending frozen error, as pointed out by the following KASAN report: ================================================================== BUG: KASAN: slab-use-after-free in binder_netlink_report.isra.0+0x694/0x6c8 Read of size 8 at addr ffff00000f98ba38 by task binder-util/522 CPU: 4 UID: 0 PID: 522 Comm: binder-util Not tainted 6.19.0-rc6-00015-gc03e9c42ae8f #1 PREEMPT Hardware name: linux,dummy-virt (DT) Call trace: binder_netlink_report.isra.0+0x694/0x6c8 binder_transaction+0x66e4/0x79b8 binder_thread_write+0xab4/0x4440 binder_ioctl+0x1fd4/0x2940 [...] Allocated by task 522: __kmalloc_cache_noprof+0x17c/0x50c binder_transaction+0x584/0x79b8 binder_thread_write+0xab4/0x4440 binder_ioctl+0x1fd4/0x2940 [...] Freed by task 488: kfree+0x1d0/0x420 binder_free_transaction+0x150/0x234 binder_thread_read+0x2d08/0x3ce4 binder_ioctl+0x488/0x2940 [...] ================================================================== Instead, make a transaction copy so the data can be safely accessed by binder_netlink_report() after a pending frozen error. While here, add a comment about not using t->buffer in binder_netlink_report(). Cc: stable@vger.kernel.org Fixes: 6374034 ("binder: introduce transaction reports via netlink") Signed-off-by: Carlos Llamas <cmllamas@google.com> Reviewed-by: Alice Ryhl <aliceryhl@google.com> Link: https://patch.msgid.link/20260122180203.1502637-1-cmllamas@google.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent 8f589c9 commit 5e8a3d0

1 file changed

Lines changed: 13 additions & 1 deletion

File tree

drivers/android/binder.c

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2991,6 +2991,10 @@ static void binder_set_txn_from_error(struct binder_transaction *t, int id,
29912991
* @t: the binder transaction that failed
29922992
* @data_size: the user provided data size for the transaction
29932993
* @error: enum binder_driver_return_protocol returned to sender
2994+
*
2995+
* Note that t->buffer is not safe to access here, as it may have been
2996+
* released (or not yet allocated). Callers should guarantee all the
2997+
* transaction items used here are safe to access.
29942998
*/
29952999
static void binder_netlink_report(struct binder_proc *proc,
29963000
struct binder_transaction *t,
@@ -3780,6 +3784,14 @@ static void binder_transaction(struct binder_proc *proc,
37803784
goto err_dead_proc_or_thread;
37813785
}
37823786
} else {
3787+
/*
3788+
* Make a transaction copy. It is not safe to access 't' after
3789+
* binder_proc_transaction() reported a pending frozen. The
3790+
* target could thaw and consume the transaction at any point.
3791+
* Instead, use a safe 't_copy' for binder_netlink_report().
3792+
*/
3793+
struct binder_transaction t_copy = *t;
3794+
37833795
BUG_ON(target_node == NULL);
37843796
BUG_ON(t->buffer->async_transaction != 1);
37853797
return_error = binder_proc_transaction(t, target_proc, NULL);
@@ -3790,7 +3802,7 @@ static void binder_transaction(struct binder_proc *proc,
37903802
*/
37913803
if (return_error == BR_TRANSACTION_PENDING_FROZEN) {
37923804
tcomplete->type = BINDER_WORK_TRANSACTION_PENDING;
3793-
binder_netlink_report(proc, t, tr->data_size,
3805+
binder_netlink_report(proc, &t_copy, tr->data_size,
37943806
return_error);
37953807
}
37963808
binder_enqueue_thread_work(thread, tcomplete);

0 commit comments

Comments
 (0)