Pull the loop that translates the flat_binder_objects into a separate function, binder_transaction_buffer_acquire. Signed-off-by: Riley Andrews <riandrews@xxxxxxxxxxx> --- drivers/android/binder.c | 128 ++++++++++++++++++++++++++++------------------- 1 file changed, 77 insertions(+), 51 deletions(-) diff --git a/drivers/android/binder.c b/drivers/android/binder.c index a9a160a..407c1ee 100644 --- a/drivers/android/binder.c +++ b/drivers/android/binder.c @@ -1464,12 +1464,84 @@ err_fd_not_accepted: return BR_FAILED_REPLY; } +static int binder_transaction_buffer_acquire( + struct binder_transaction *t, struct binder_transaction_data *tr, + struct binder_thread *thread, struct binder_transaction *in_reply_to) +{ + struct binder_proc *proc = thread->proc; + binder_size_t *offp, *off_end, off_min; + struct flat_binder_object *fp; + uint32_t result; + + if (!IS_ALIGNED(tr->offsets_size, sizeof(binder_size_t))) { + binder_user_error("%d:%d got transaction with invalid offsets size, %lld\n", + proc->pid, thread->pid, + (u64)tr->offsets_size); + return BR_FAILED_REPLY; + } + + if (t->buffer->target_node) + binder_inc_node(t->buffer->target_node, 1, 0, NULL); + + off_min = 0; + offp = (binder_size_t *)(t->buffer->data + + ALIGN(tr->data_size, sizeof(void *))); + off_end = (void *)offp + tr->offsets_size; + for (; offp < off_end; offp++) { + if (*offp > t->buffer->data_size - sizeof(*fp) || + *offp < off_min || + t->buffer->data_size < sizeof(*fp) || + !IS_ALIGNED(*offp, sizeof(u32))) { + binder_user_error("%d:%d got transaction with invalid offset, %lld (min %lld, max %lld)\n", + proc->pid, thread->pid, (u64)*offp, + (u64)off_min, + (u64)(t->buffer->data_size - + sizeof(*fp))); + result = BR_FAILED_REPLY; + goto error; + } + fp = (struct flat_binder_object *)(t->buffer->data + *offp); + off_min = *offp + sizeof(struct flat_binder_object); + switch (fp->type) { + case BINDER_TYPE_BINDER: + case BINDER_TYPE_WEAK_BINDER: + result = binder_translate_object(fp, t, thread); + if (result != BR_OK) + goto error; + break; + case BINDER_TYPE_HANDLE: + case BINDER_TYPE_WEAK_HANDLE: + result = binder_translate_handle(fp, t, thread); + if (result != BR_OK) + goto error; + break; + case BINDER_TYPE_FD: + result = binder_translate_fd(fp, t, thread, + in_reply_to); + if (result != BR_OK) + goto error; + break; + default: + binder_user_error("got transaction with invalid object type, %x\n", + fp->type); + result = BR_FAILED_REPLY; + goto error; + } + } + return BR_OK; + +error: + trace_binder_transaction_failed_buffer_release(t->buffer); + binder_transaction_buffer_release(t->to_proc, t->buffer, offp); + return result; +} + static void binder_transaction(struct binder_thread *thread, struct binder_transaction_data *tr, int reply) { struct binder_transaction *t; struct binder_work *tcomplete; - binder_size_t *offp, *off_end; + binder_size_t *offp; struct binder_proc *target_proc; struct binder_thread *target_thread = NULL; struct binder_node *target_node = NULL; @@ -1645,8 +1717,6 @@ static void binder_transaction(struct binder_thread *thread, t->buffer->transaction = t; t->buffer->target_node = target_node; trace_binder_transaction_alloc_buf(t->buffer); - if (target_node) - binder_inc_node(target_node, 1, 0, NULL); offp = (binder_size_t *)(t->buffer->data + ALIGN(tr->data_size, sizeof(void *))); @@ -1665,51 +1735,11 @@ static void binder_transaction(struct binder_thread *thread, return_error = BR_FAILED_REPLY; goto err_copy_data_failed; } - if (!IS_ALIGNED(tr->offsets_size, sizeof(binder_size_t))) { - binder_user_error("%d:%d got transaction with invalid offsets size, %lld\n", - proc->pid, thread->pid, (u64)tr->offsets_size); - return_error = BR_FAILED_REPLY; - goto err_bad_offset; - } - off_end = (void *)offp + tr->offsets_size; - for (; offp < off_end; offp++) { - struct flat_binder_object *fp; + return_error = binder_transaction_buffer_acquire(t, tr, thread, + in_reply_to); + if (return_error != BR_OK) + goto err_translate_failed; - if (*offp > t->buffer->data_size - sizeof(*fp) || - t->buffer->data_size < sizeof(*fp) || - !IS_ALIGNED(*offp, sizeof(u32))) { - binder_user_error("%d:%d got transaction with invalid offset, %lld\n", - proc->pid, thread->pid, (u64)*offp); - return_error = BR_FAILED_REPLY; - goto err_bad_offset; - } - fp = (struct flat_binder_object *)(t->buffer->data + *offp); - switch (fp->type) { - case BINDER_TYPE_BINDER: - case BINDER_TYPE_WEAK_BINDER: - return_error = binder_translate_object(fp, t, thread); - if (return_error != BR_OK) - goto err_translate_failed; - break; - case BINDER_TYPE_HANDLE: - case BINDER_TYPE_WEAK_HANDLE: - return_error = binder_translate_handle(fp, t, thread); - if (return_error != BR_OK) - goto err_translate_failed; - break; - case BINDER_TYPE_FD: - return_error = binder_translate_fd(fp, t, thread, - in_reply_to); - if (return_error != BR_OK) - goto err_translate_failed; - break; - default: - binder_user_error("%d:%d got transaction with invalid object type, %x\n", - proc->pid, thread->pid, fp->type); - return_error = BR_FAILED_REPLY; - goto err_bad_object_type; - } - } if (reply) { BUG_ON(t->buffer->async_transaction != 0); binder_pop_transaction(target_thread, in_reply_to); @@ -1736,11 +1766,7 @@ static void binder_transaction(struct binder_thread *thread, return; err_translate_failed: -err_bad_object_type: -err_bad_offset: err_copy_data_failed: - trace_binder_transaction_failed_buffer_release(t->buffer); - binder_transaction_buffer_release(target_proc, t->buffer, offp); t->buffer->transaction = NULL; binder_free_buf(target_proc, t->buffer); err_binder_alloc_buf_failed: -- 2.2.0.rc0.207.ga3a616c _______________________________________________ devel mailing list devel@xxxxxxxxxxxxxxxxxxxxxx http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel