android: binder: More offset validation
Make sure offsets don't point to overlapping flat_binder_object structs. Cc: Colin Cross <ccross@android.com> Cc: Arve Hjønnevåg <arve@android.com> Cc: Dmitry Shmidt <dimitrysh@google.com> Cc: Rom Lemarchand <romlem@google.com> Cc: Serban Constantinescu <serban.constantinescu@arm.com> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Cc: Android Kernel Team <kernel-team@android.com> Signed-off-by: Dmitry Shmidt <dimitrysh@google.com> Signed-off-by: John Stultz <john.stultz@linaro.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
46d83a8782
commit
212265e5ad
|
@ -1321,6 +1321,7 @@ static void binder_transaction(struct binder_proc *proc,
|
||||||
struct binder_transaction *t;
|
struct binder_transaction *t;
|
||||||
struct binder_work *tcomplete;
|
struct binder_work *tcomplete;
|
||||||
binder_size_t *offp, *off_end;
|
binder_size_t *offp, *off_end;
|
||||||
|
binder_size_t off_min;
|
||||||
struct binder_proc *target_proc;
|
struct binder_proc *target_proc;
|
||||||
struct binder_thread *target_thread = NULL;
|
struct binder_thread *target_thread = NULL;
|
||||||
struct binder_node *target_node = NULL;
|
struct binder_node *target_node = NULL;
|
||||||
|
@ -1522,18 +1523,24 @@ static void binder_transaction(struct binder_proc *proc,
|
||||||
goto err_bad_offset;
|
goto err_bad_offset;
|
||||||
}
|
}
|
||||||
off_end = (void *)offp + tr->offsets_size;
|
off_end = (void *)offp + tr->offsets_size;
|
||||||
|
off_min = 0;
|
||||||
for (; offp < off_end; offp++) {
|
for (; offp < off_end; offp++) {
|
||||||
struct flat_binder_object *fp;
|
struct flat_binder_object *fp;
|
||||||
|
|
||||||
if (*offp > t->buffer->data_size - sizeof(*fp) ||
|
if (*offp > t->buffer->data_size - sizeof(*fp) ||
|
||||||
|
*offp < off_min ||
|
||||||
t->buffer->data_size < sizeof(*fp) ||
|
t->buffer->data_size < sizeof(*fp) ||
|
||||||
!IS_ALIGNED(*offp, sizeof(u32))) {
|
!IS_ALIGNED(*offp, sizeof(u32))) {
|
||||||
binder_user_error("%d:%d got transaction with invalid offset, %lld\n",
|
binder_user_error("%d:%d got transaction with invalid offset, %lld (min %lld, max %lld)\n",
|
||||||
proc->pid, thread->pid, (u64)*offp);
|
proc->pid, thread->pid, (u64)*offp,
|
||||||
|
(u64)off_min,
|
||||||
|
(u64)(t->buffer->data_size -
|
||||||
|
sizeof(*fp)));
|
||||||
return_error = BR_FAILED_REPLY;
|
return_error = BR_FAILED_REPLY;
|
||||||
goto err_bad_offset;
|
goto err_bad_offset;
|
||||||
}
|
}
|
||||||
fp = (struct flat_binder_object *)(t->buffer->data + *offp);
|
fp = (struct flat_binder_object *)(t->buffer->data + *offp);
|
||||||
|
off_min = *offp + sizeof(struct flat_binder_object);
|
||||||
switch (fp->type) {
|
switch (fp->type) {
|
||||||
case BINDER_TYPE_BINDER:
|
case BINDER_TYPE_BINDER:
|
||||||
case BINDER_TYPE_WEAK_BINDER: {
|
case BINDER_TYPE_WEAK_BINDER: {
|
||||||
|
|
Loading…
Reference in New Issue