diff options
author | Arve Hjønnevåg <arve@android.com> | 2009-04-06 18:12:56 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2009-04-17 14:06:26 -0400 |
commit | ea5c4cc68e2b5f4ec41d666376d3606d4d5c3426 (patch) | |
tree | 3d6a9b0ceca8d1f0583bda79bfc05d09f887b073 /drivers | |
parent | 4ddfc911e39a01f95ad9765d3b9e6f43e14eeff4 (diff) |
Staging: binder: Add more offset validation.
Check that datasize is not smaller than one flat_binder_object.
Check that offsets are aligned.
Check that offsets_size is aligned.
Signed-off-by: Arve Hjønnevåg <arve@android.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/staging/android/binder.c | 15 |
1 files changed, 13 insertions, 2 deletions
diff --git a/drivers/staging/android/binder.c b/drivers/staging/android/binder.c index 761f5d6a9cf2..64f95ee8a704 100644 --- a/drivers/staging/android/binder.c +++ b/drivers/staging/android/binder.c | |||
@@ -1430,10 +1430,19 @@ binder_transaction(struct binder_proc *proc, struct binder_thread *thread, | |||
1430 | return_error = BR_FAILED_REPLY; | 1430 | return_error = BR_FAILED_REPLY; |
1431 | goto err_copy_data_failed; | 1431 | goto err_copy_data_failed; |
1432 | } | 1432 | } |
1433 | if (!IS_ALIGNED(tr->offsets_size, sizeof(size_t))) { | ||
1434 | binder_user_error("binder: %d:%d got transaction with " | ||
1435 | "invalid offsets size, %zd\n", | ||
1436 | proc->pid, thread->pid, tr->offsets_size); | ||
1437 | return_error = BR_FAILED_REPLY; | ||
1438 | goto err_bad_offset; | ||
1439 | } | ||
1433 | off_end = (void *)offp + tr->offsets_size; | 1440 | off_end = (void *)offp + tr->offsets_size; |
1434 | for (; offp < off_end; offp++) { | 1441 | for (; offp < off_end; offp++) { |
1435 | struct flat_binder_object *fp; | 1442 | struct flat_binder_object *fp; |
1436 | if (*offp > t->buffer->data_size - sizeof(*fp)) { | 1443 | if (*offp > t->buffer->data_size - sizeof(*fp) || |
1444 | t->buffer->data_size < sizeof(*fp) || | ||
1445 | !IS_ALIGNED(*offp, sizeof(void *))) { | ||
1437 | binder_user_error("binder: %d:%d got transaction with " | 1446 | binder_user_error("binder: %d:%d got transaction with " |
1438 | "invalid offset, %zd\n", | 1447 | "invalid offset, %zd\n", |
1439 | proc->pid, thread->pid, *offp); | 1448 | proc->pid, thread->pid, *offp); |
@@ -1651,7 +1660,9 @@ binder_transaction_buffer_release(struct binder_proc *proc, struct binder_buffer | |||
1651 | off_end = (void *)offp + buffer->offsets_size; | 1660 | off_end = (void *)offp + buffer->offsets_size; |
1652 | for (; offp < off_end; offp++) { | 1661 | for (; offp < off_end; offp++) { |
1653 | struct flat_binder_object *fp; | 1662 | struct flat_binder_object *fp; |
1654 | if (*offp > buffer->data_size - sizeof(*fp)) { | 1663 | if (*offp > buffer->data_size - sizeof(*fp) || |
1664 | buffer->data_size < sizeof(*fp) || | ||
1665 | !IS_ALIGNED(*offp, sizeof(void *))) { | ||
1655 | printk(KERN_ERR "binder: transaction release %d bad" | 1666 | printk(KERN_ERR "binder: transaction release %d bad" |
1656 | "offset %zd, size %zd\n", debug_id, *offp, buffer->data_size); | 1667 | "offset %zd, size %zd\n", debug_id, *offp, buffer->data_size); |
1657 | continue; | 1668 | continue; |