CVE-2023-20938
English
漏洞分析
- client A与client B通过上下文管理器servicemanager建立Binder连接
- A创建node 0xbeef(node = binder_new_node(proc, fp);),B通过ref->target_node引用node 0xbeef
- B先正确处理target_node 0xbeef,将引用了target_node 0xbeef的事物binder_transaction存入A的事物队列(binder_enqueue_work_ilocked(&t->work, &proc->todo);),使A可以再次引用被释放的悬挂指针
- B使用未对其的offsets_size进入错误处理代码(IS_ALIGNED(tr->offsets_size, sizeof(binder_size_t))),导致还是0的buffer_offset被传入binder_transaction_buffer_release函数从而触发漏洞
- binder_transaction_buffer_release函数通过binder_dec_node调用binder_dec_node_nilocked函数,减少node 0xbeef的local_strong_refs引用计数器,但是node实例中有多个引用计数器及引用列表,只有当这些计数器都被清0时才会触发释放
- 关闭B的binder触发binder_cleanup_ref_olocked函数,此时还会调用binder_dec_node_nilocked,当binder_dec_node_nilocked返回true时,将不会把指向node(0xbeef)的指针ref->node清空
- 之后将会调用binder_free_ref,在binder_free_ref函数中会将node 0xbeef释放
- A将会在binder_thread_read函数中再次引用被释放的node 0xbeef
额外说明:
真实android环境下普通应用权限无法通过servicemanager注册服务,但可以通过ITokenManager来实现两个进程的链接,本测试用例就是用了ITokenManager