in binder.c [1765:1805]
static bool binder_validate_fixup(struct binder_proc *proc,
struct binder_buffer *b,
binder_size_t objects_start_offset,
binder_size_t buffer_obj_offset,
binder_size_t fixup_offset,
binder_size_t last_obj_offset,
binder_size_t last_min_offset)
{
if (!last_obj_offset) {
/* Nothing to fix up in */
return false;
}
while (last_obj_offset != buffer_obj_offset) {
unsigned long buffer_offset;
struct binder_object last_object;
struct binder_buffer_object *last_bbo;
size_t object_size = binder_get_object(proc, NULL, b,
last_obj_offset,
&last_object);
if (object_size != sizeof(*last_bbo))
return false;
last_bbo = &last_object.bbo;
/*
* Safe to retrieve the parent of last_obj, since it
* was already previously verified by the driver.
*/
if ((last_bbo->flags & BINDER_BUFFER_FLAG_HAS_PARENT) == 0)
return false;
last_min_offset = last_bbo->parent_offset + sizeof(uintptr_t);
buffer_offset = objects_start_offset +
sizeof(binder_size_t) * last_bbo->parent;
if (binder_alloc_copy_from_buffer(&proc->alloc,
&last_obj_offset,
b, buffer_offset,
sizeof(last_obj_offset)))
return false;
}
return (fixup_offset >= last_min_offset);
}