RAVENPLAT 2652: RAVEN - Android Security Bulletin - September 2019-09 - Kernel compon...
authorTodd Kjos <tkjos@android.com>
Wed, 24 Apr 2019 19:31:18 +0000 (12:31 -0700)
committerJianxin Pan <jianxin.pan@amlogic.com>
Wed, 18 Sep 2019 06:30:30 +0000 (23:30 -0700)
PD#OTT-5999

[Problem]
In binder_transaction of binder.c, there is a possible out of bounds
write due to an integer overflow. This could lead to local escalation of
privilege with noadditional execution privileges needed. User interaction
is needed for exploitation.
The fix is designed to check for the integer overflow.

[Solution]
UPSTREAM: binder: check for overflow when alloc for security context

commit 0b0509508beff65c1d50541861bc0d4973487dc5 upstream.

When allocating space in the target buffer for the security context,
make sure the extra_buffers_size doesn't overflow. This can only
happen if the given size is invalid, but an overflow can turn it
into a valid size. Fail the transaction if an overflow is detected.

Bug: 130571081
Change-Id: Ibaec652d2073491cc426a4a24004a848348316bf
Signed-off-by: Todd Kjos <tkjos@google.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Hanjie Lin <hanjie.lin@amlogic.com>
drivers/android/binder.c

index 5b5bf21..fe5ba67 100644 (file)
@@ -3231,6 +3231,7 @@ static void binder_transaction(struct binder_proc *proc,
 
        if (target_node && target_node->txn_security_ctx) {
                u32 secid;
+               size_t added_size;
 
                security_task_getsecid(proc->tsk, &secid);
                ret = security_secid_to_secctx(secid, &secctx, &secctx_sz);
@@ -3240,7 +3241,15 @@ static void binder_transaction(struct binder_proc *proc,
                        return_error_line = __LINE__;
                        goto err_get_secctx_failed;
                }
-               extra_buffers_size += ALIGN(secctx_sz, sizeof(u64));
+               added_size = ALIGN(secctx_sz, sizeof(u64));
+               extra_buffers_size += added_size;
+               if (extra_buffers_size < added_size) {
+                       /* integer overflow of extra_buffers_size */
+                       return_error = BR_FAILED_REPLY;
+                       return_error_param = EINVAL;
+                       return_error_line = __LINE__;
+                       goto err_bad_extra_size;
+               }
        }
 
        trace_binder_transaction(reply, t, target_node);
@@ -3597,6 +3606,7 @@ err_copy_data_failed:
        t->buffer->transaction = NULL;
        binder_alloc_free_buf(&target_proc->alloc, t->buffer);
 err_binder_alloc_buf_failed:
+err_bad_extra_size:
        if (secctx)
                security_release_secctx(secctx, secctx_sz);
 err_get_secctx_failed: