* @t: the binder transaction that failed
* @data_size: the user provided data size for the transaction
* @error: enum binder_driver_return_protocol returned to sender
+ *
+ * Note that t->buffer is not safe to access here, as it may have been
+ * released (or not yet allocated). Callers should guarantee all the
+ * transaction items used here are safe to access.
*/
static void binder_netlink_report(struct binder_proc *proc,
struct binder_transaction *t,
goto err_dead_proc_or_thread;
}
} else {
+ /*
+ * Make a transaction copy. It is not safe to access 't' after
+ * binder_proc_transaction() reported a pending frozen. The
+ * target could thaw and consume the transaction at any point.
+ * Instead, use a safe 't_copy' for binder_netlink_report().
+ */
+ struct binder_transaction t_copy = *t;
+
BUG_ON(target_node == NULL);
BUG_ON(t->buffer->async_transaction != 1);
return_error = binder_proc_transaction(t, target_proc, NULL);
*/
if (return_error == BR_TRANSACTION_PENDING_FROZEN) {
tcomplete->type = BINDER_WORK_TRANSACTION_PENDING;
- binder_netlink_report(proc, t, tr->data_size,
+ binder_netlink_report(proc, &t_copy, tr->data_size,
return_error);
}
binder_enqueue_thread_work(thread, tcomplete);