in binder.c [1624:1672]
static size_t binder_get_object(struct binder_proc *proc,
const void __user *u,
struct binder_buffer *buffer,
unsigned long offset,
struct binder_object *object)
{
size_t read_size;
struct binder_object_header *hdr;
size_t object_size = 0;
read_size = min_t(size_t, sizeof(*object), buffer->data_size - offset);
if (offset > buffer->data_size || read_size < sizeof(*hdr))
return 0;
if (u) {
if (copy_from_user(object, u + offset, read_size))
return 0;
} else {
if (binder_alloc_copy_from_buffer(&proc->alloc, object, buffer,
offset, read_size))
return 0;
}
/* Ok, now see if we read a complete object. */
hdr = &object->hdr;
switch (hdr->type) {
case BINDER_TYPE_BINDER:
case BINDER_TYPE_WEAK_BINDER:
case BINDER_TYPE_HANDLE:
case BINDER_TYPE_WEAK_HANDLE:
object_size = sizeof(struct flat_binder_object);
break;
case BINDER_TYPE_FD:
object_size = sizeof(struct binder_fd_object);
break;
case BINDER_TYPE_PTR:
object_size = sizeof(struct binder_buffer_object);
break;
case BINDER_TYPE_FDA:
object_size = sizeof(struct binder_fd_array_object);
break;
default:
return 0;
}
if (offset <= buffer->data_size - object_size &&
buffer->data_size >= object_size)
return object_size;
else
return 0;
}