|
@@ -1321,6 +1321,7 @@ static void binder_transaction(struct binder_proc *proc,
|
|
|
struct binder_transaction *t;
|
|
|
struct binder_work *tcomplete;
|
|
|
binder_size_t *offp, *off_end;
|
|
|
+ binder_size_t off_min;
|
|
|
struct binder_proc *target_proc;
|
|
|
struct binder_thread *target_thread = NULL;
|
|
|
struct binder_node *target_node = NULL;
|
|
@@ -1522,18 +1523,24 @@ static void binder_transaction(struct binder_proc *proc,
|
|
|
goto err_bad_offset;
|
|
|
}
|
|
|
off_end = (void *)offp + tr->offsets_size;
|
|
|
+ off_min = 0;
|
|
|
for (; offp < off_end; offp++) {
|
|
|
struct flat_binder_object *fp;
|
|
|
|
|
|
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\n",
|
|
|
- proc->pid, thread->pid, (u64)*offp);
|
|
|
+ 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)));
|
|
|
return_error = BR_FAILED_REPLY;
|
|
|
goto err_bad_offset;
|
|
|
}
|
|
|
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: {
|