diff options
author | Arve Hjønnevåg <arve@android.com> | 2009-04-06 15:12:56 -0700 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2009-04-17 11:06:26 -0700 |
commit | ea5c4cc68e2b5f4ec41d666376d3606d4d5c3426 (patch) | |
tree | 3d6a9b0ceca8d1f0583bda79bfc05d09f887b073 /drivers/staging | |
parent | 4ddfc911e39a01f95ad9765d3b9e6f43e14eeff4 (diff) | |
download | talos-op-linux-ea5c4cc68e2b5f4ec41d666376d3606d4d5c3426.tar.gz talos-op-linux-ea5c4cc68e2b5f4ec41d666376d3606d4d5c3426.zip |
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/staging')
-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, return_error = BR_FAILED_REPLY; goto err_copy_data_failed; } + if (!IS_ALIGNED(tr->offsets_size, sizeof(size_t))) { + binder_user_error("binder: %d:%d got transaction with " + "invalid offsets size, %zd\n", + proc->pid, thread->pid, 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; - if (*offp > t->buffer->data_size - sizeof(*fp)) { + if (*offp > t->buffer->data_size - sizeof(*fp) || + t->buffer->data_size < sizeof(*fp) || + !IS_ALIGNED(*offp, sizeof(void *))) { binder_user_error("binder: %d:%d got transaction with " "invalid offset, %zd\n", proc->pid, thread->pid, *offp); @@ -1651,7 +1660,9 @@ binder_transaction_buffer_release(struct binder_proc *proc, struct binder_buffer off_end = (void *)offp + buffer->offsets_size; for (; offp < off_end; offp++) { struct flat_binder_object *fp; - if (*offp > buffer->data_size - sizeof(*fp)) { + if (*offp > buffer->data_size - sizeof(*fp) || + buffer->data_size < sizeof(*fp) || + !IS_ALIGNED(*offp, sizeof(void *))) { printk(KERN_ERR "binder: transaction release %d bad" "offset %zd, size %zd\n", debug_id, *offp, buffer->data_size); continue; |