static int binder_fixup_parent()

in binder.c [2539:2587]


static int binder_fixup_parent(struct list_head *pf_head,
			       struct binder_transaction *t,
			       struct binder_thread *thread,
			       struct binder_buffer_object *bp,
			       binder_size_t off_start_offset,
			       binder_size_t num_valid,
			       binder_size_t last_fixup_obj_off,
			       binder_size_t last_fixup_min_off)
{
	struct binder_buffer_object *parent;
	struct binder_buffer *b = t->buffer;
	struct binder_proc *proc = thread->proc;
	struct binder_proc *target_proc = t->to_proc;
	struct binder_object object;
	binder_size_t buffer_offset;
	binder_size_t parent_offset;

	if (!(bp->flags & BINDER_BUFFER_FLAG_HAS_PARENT))
		return 0;

	parent = binder_validate_ptr(target_proc, b, &object, bp->parent,
				     off_start_offset, &parent_offset,
				     num_valid);
	if (!parent) {
		binder_user_error("%d:%d got transaction with invalid parent offset or type\n",
				  proc->pid, thread->pid);
		return -EINVAL;
	}

	if (!binder_validate_fixup(target_proc, b, off_start_offset,
				   parent_offset, bp->parent_offset,
				   last_fixup_obj_off,
				   last_fixup_min_off)) {
		binder_user_error("%d:%d got transaction with out-of-order buffer fixup\n",
				  proc->pid, thread->pid);
		return -EINVAL;
	}

	if (parent->length < sizeof(binder_uintptr_t) ||
	    bp->parent_offset > parent->length - sizeof(binder_uintptr_t)) {
		/* No space for a pointer here! */
		binder_user_error("%d:%d got transaction with invalid parent offset\n",
				  proc->pid, thread->pid);
		return -EINVAL;
	}
	buffer_offset = bp->parent_offset +
			(uintptr_t)parent->buffer - (uintptr_t)b->user_data;
	return binder_add_fixup(pf_head, buffer_offset, bp->buffer, 0);
}