All of lore.kernel.org
 help / color / mirror / Atom feed
From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: stable@vger.kernel.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	patches@lists.linux.dev, Zi Fan Tan <zifantan@google.com>,
	Carlos Llamas <cmllamas@google.com>, Todd Kjos <tkjos@google.com>
Subject: [PATCH 5.4 14/16] binder: fix UAF caused by faulty buffer cleanup
Date: Thu,  1 Jun 2023 14:21:09 +0100	[thread overview]
Message-ID: <20230601131932.611327463@linuxfoundation.org> (raw)
In-Reply-To: <20230601131931.947241286@linuxfoundation.org>

From: Carlos Llamas <cmllamas@google.com>

commit bdc1c5fac982845a58d28690cdb56db8c88a530d upstream.

In binder_transaction_buffer_release() the 'failed_at' offset indicates
the number of objects to clean up. However, this function was changed by
commit 44d8047f1d87 ("binder: use standard functions to allocate fds"),
to release all the objects in the buffer when 'failed_at' is zero.

This introduced an issue when a transaction buffer is released without
any objects having been processed so far. In this case, 'failed_at' is
indeed zero yet it is misinterpreted as releasing the entire buffer.

This leads to use-after-free errors where nodes are incorrectly freed
and subsequently accessed. Such is the case in the following KASAN
report:

  ==================================================================
  BUG: KASAN: slab-use-after-free in binder_thread_read+0xc40/0x1f30
  Read of size 8 at addr ffff4faf037cfc58 by task poc/474

  CPU: 6 PID: 474 Comm: poc Not tainted 6.3.0-12570-g7df047b3f0aa #5
  Hardware name: linux,dummy-virt (DT)
  Call trace:
   dump_backtrace+0x94/0xec
   show_stack+0x18/0x24
   dump_stack_lvl+0x48/0x60
   print_report+0xf8/0x5b8
   kasan_report+0xb8/0xfc
   __asan_load8+0x9c/0xb8
   binder_thread_read+0xc40/0x1f30
   binder_ioctl+0xd9c/0x1768
   __arm64_sys_ioctl+0xd4/0x118
   invoke_syscall+0x60/0x188
  [...]

  Allocated by task 474:
   kasan_save_stack+0x3c/0x64
   kasan_set_track+0x2c/0x40
   kasan_save_alloc_info+0x24/0x34
   __kasan_kmalloc+0xb8/0xbc
   kmalloc_trace+0x48/0x5c
   binder_new_node+0x3c/0x3a4
   binder_transaction+0x2b58/0x36f0
   binder_thread_write+0x8e0/0x1b78
   binder_ioctl+0x14a0/0x1768
   __arm64_sys_ioctl+0xd4/0x118
   invoke_syscall+0x60/0x188
  [...]

  Freed by task 475:
   kasan_save_stack+0x3c/0x64
   kasan_set_track+0x2c/0x40
   kasan_save_free_info+0x38/0x5c
   __kasan_slab_free+0xe8/0x154
   __kmem_cache_free+0x128/0x2bc
   kfree+0x58/0x70
   binder_dec_node_tmpref+0x178/0x1fc
   binder_transaction_buffer_release+0x430/0x628
   binder_transaction+0x1954/0x36f0
   binder_thread_write+0x8e0/0x1b78
   binder_ioctl+0x14a0/0x1768
   __arm64_sys_ioctl+0xd4/0x118
   invoke_syscall+0x60/0x188
  [...]
  ==================================================================

In order to avoid these issues, let's always calculate the intended
'failed_at' offset beforehand. This is renamed and wrapped in a helper
function to make it clear and convenient.

Fixes: 32e9f56a96d8 ("binder: don't detect sender/target during buffer cleanup")
Reported-by: Zi Fan Tan <zifantan@google.com>
Cc: stable@vger.kernel.org
Signed-off-by: Carlos Llamas <cmllamas@google.com>
Acked-by: Todd Kjos <tkjos@google.com>
Link: https://lore.kernel.org/r/20230505203020.4101154-1-cmllamas@google.com
[cmllamas: resolve trivial conflict due to missing commit 9864bb4801331]
Signed-off-by: Carlos Llamas <cmllamas@google.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/android/binder.c |   26 ++++++++++++++++++++------
 1 file changed, 20 insertions(+), 6 deletions(-)

--- a/drivers/android/binder.c
+++ b/drivers/android/binder.c
@@ -2270,24 +2270,23 @@ static void binder_deferred_fd_close(int
 static void binder_transaction_buffer_release(struct binder_proc *proc,
 					      struct binder_thread *thread,
 					      struct binder_buffer *buffer,
-					      binder_size_t failed_at,
+					      binder_size_t off_end_offset,
 					      bool is_failure)
 {
 	int debug_id = buffer->debug_id;
-	binder_size_t off_start_offset, buffer_offset, off_end_offset;
+	binder_size_t off_start_offset, buffer_offset;
 
 	binder_debug(BINDER_DEBUG_TRANSACTION,
 		     "%d buffer release %d, size %zd-%zd, failed at %llx\n",
 		     proc->pid, buffer->debug_id,
 		     buffer->data_size, buffer->offsets_size,
-		     (unsigned long long)failed_at);
+		     (unsigned long long)off_end_offset);
 
 	if (buffer->target_node)
 		binder_dec_node(buffer->target_node, 1, 0);
 
 	off_start_offset = ALIGN(buffer->data_size, sizeof(void *));
-	off_end_offset = is_failure && failed_at ? failed_at :
-				off_start_offset + buffer->offsets_size;
+
 	for (buffer_offset = off_start_offset; buffer_offset < off_end_offset;
 	     buffer_offset += sizeof(binder_size_t)) {
 		struct binder_object_header *hdr;
@@ -2447,6 +2446,21 @@ static void binder_transaction_buffer_re
 	}
 }
 
+/* Clean up all the objects in the buffer */
+static inline void binder_release_entire_buffer(struct binder_proc *proc,
+						struct binder_thread *thread,
+						struct binder_buffer *buffer,
+						bool is_failure)
+{
+	binder_size_t off_end_offset;
+
+	off_end_offset = ALIGN(buffer->data_size, sizeof(void *));
+	off_end_offset += buffer->offsets_size;
+
+	binder_transaction_buffer_release(proc, thread, buffer,
+					  off_end_offset, is_failure);
+}
+
 static int binder_translate_binder(struct flat_binder_object *fp,
 				   struct binder_transaction *t,
 				   struct binder_thread *thread)
@@ -3930,7 +3944,7 @@ binder_free_buf(struct binder_proc *proc
 		binder_node_inner_unlock(buf_node);
 	}
 	trace_binder_transaction_buffer_release(buffer);
-	binder_transaction_buffer_release(proc, thread, buffer, 0, is_failure);
+	binder_release_entire_buffer(proc, thread, buffer, is_failure);
 	binder_alloc_free_buf(&proc->alloc, buffer);
 }
 



  parent reply	other threads:[~2023-06-01 13:22 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-06-01 13:20 [PATCH 5.4 00/16] 5.4.245-rc1 review Greg Kroah-Hartman
2023-06-01 13:20 ` [PATCH 5.4 01/16] cdc_ncm: Implement the 32-bit version of NCM Transfer Block Greg Kroah-Hartman
2023-06-01 13:20 ` [PATCH 5.4 02/16] net: cdc_ncm: Deal with too low values of dwNtbOutMaxSize Greg Kroah-Hartman
2023-06-01 13:20 ` [PATCH 5.4 03/16] power: supply: bq27xxx: After charger plug in/out wait 0.5s for things to stabilize Greg Kroah-Hartman
2023-06-01 13:20 ` [PATCH 5.4 04/16] power: supply: core: Refactor power_supply_set_input_current_limit_from_supplier() Greg Kroah-Hartman
2023-06-01 13:21 ` [PATCH 5.4 05/16] power: supply: bq24190: Call power_supply_changed() after updating input current Greg Kroah-Hartman
2023-06-01 13:21 ` [PATCH 5.4 06/16] fs: fix undefined behavior in bit shift for SB_NOUSER Greg Kroah-Hartman
2023-06-01 13:21 ` [PATCH 5.4 07/16] net/mlx5: devcom only supports 2 ports Greg Kroah-Hartman
2023-06-01 13:21 ` [PATCH 5.4 08/16] net/mlx5: Devcom, serialize devcom registration Greg Kroah-Hartman
2023-06-01 13:21 ` [PATCH 5.4 09/16] cdc_ncm: Fix the build warning Greg Kroah-Hartman
2023-06-01 13:21 ` [PATCH 5.4 10/16] io_uring: always grab lock in io_cancel_async_work() Greg Kroah-Hartman
2023-06-01 13:21 ` [PATCH 5.4 11/16] io_uring: dont drop completion lock before timer is fully initialized Greg Kroah-Hartman
2023-06-01 13:21 ` [PATCH 5.4 12/16] io_uring: have io_kill_timeout() honor the request references Greg Kroah-Hartman
2023-06-01 13:21 ` [PATCH 5.4 13/16] bluetooth: Add cmd validity checks at the start of hci_sock_ioctl() Greg Kroah-Hartman
2023-06-01 13:21 ` Greg Kroah-Hartman [this message]
2023-06-01 13:21 ` [PATCH 5.4 15/16] ipv{4,6}/raw: fix output xfrm lookup wrt protocol Greg Kroah-Hartman
2023-06-01 13:21 ` [PATCH 5.4 16/16] netfilter: ctnetlink: Support offloaded conntrack entry deletion Greg Kroah-Hartman
2023-06-01 15:58 ` [PATCH 5.4 00/16] 5.4.245-rc1 review Florian Fainelli
2023-06-01 20:53 ` Shuah Khan
2023-06-02  8:45 ` Jon Hunter
2023-06-02 10:10 ` Naresh Kamboju
2023-06-02 15:47 ` Harshit Mogalapalli
2023-06-02 22:33 ` Guenter Roeck
2023-06-05  9:16 ` Chris Paterson

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20230601131932.611327463@linuxfoundation.org \
    --to=gregkh@linuxfoundation.org \
    --cc=cmllamas@google.com \
    --cc=patches@lists.linux.dev \
    --cc=stable@vger.kernel.org \
    --cc=tkjos@google.com \
    --cc=zifantan@google.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.