最近在看爆出来的水滴cve-2019-2025的利用,发现内核写的这个思路时间窗口太小了,而且并不好控制,代码如下:
t->buffer = binder_alloc_new_buf(&target_proc->alloc, tr->data_size,
tr->offsets_size, extra_buffers_size,
!reply && (t->flags & TF_ONE_WAY));
if (IS_ERR(t->buffer)) {
/*
* -ESRCH indicates VMA cleared. The target is dying.
*/
return_error_param = PTR_ERR(t->buffer);
return_error = return_error_param == -ESRCH ?
BR_DEAD_REPLY : BR_FAILED_REPLY;
return_error_line = __LINE__;
t->buffer = NULL;
goto err_binder_alloc_buf_failed;
}
//msleep(10);
t->buffer->allow_user_free = 0;
//t->buffer->tmp = 111;
t->buffer->debug_id = t->debug_id;
t->buffer->transaction = t;
t->buffer->target_node = target_node;
基本上就是从binder_alloc_new_buf出来之后就直接到allow_user_free=0处了,这个时间窗口很短。不过,实际上,race的情况是会出现的,只要进行free 目标binder_buffer的线程多一点,cpu分散一些,很大概率能够race进去。
race进去了之后,其实并不会直接把目标binder_buffer给kfree掉,想要成功kfree必须保证前面的相邻binder_buffer是一个free的,这个就很难满足,因为如果前面的binder_buffer是一个free的话,那在binder_alloc_new_buf的时候自然会去分配到前面的binder_buffer,而不是这个目标binder_buffer。。。之前想通过不同的buffer_size来做一些事情,但是都没成功,感觉陷入了一个矛盾的循环。。。
现在假设已经成功的把目标binder_buffer给free掉了,那还需要在时间窗口期间把堆喷给做了。
一直搞不明白这块是如何成功利用的,感觉自己的思路可能是受限制了,不知道有什么其他的思路大家可以一起讨论一下。
t->buffer = binder_alloc_new_buf(&target_proc->alloc, tr->data_size,
tr->offsets_size, extra_buffers_size,
!reply && (t->flags & TF_ONE_WAY));
if (IS_ERR(t->buffer)) {
/*
* -ESRCH indicates VMA cleared. The target is dying.
*/
return_error_param = PTR_ERR(t->buffer);
return_error = return_error_param == -ESRCH ?
BR_DEAD_REPLY : BR_FAILED_REPLY;
return_error_line = __LINE__;
t->buffer = NULL;
goto err_binder_alloc_buf_failed;
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!