LKML Archive on lore.kernel.org
help / color / mirror / Atom feed
* [PATCH 0/3] binder: Prevent untranslated sender data from being copied to target
@ 2021-11-23 19:17 Todd Kjos
  2021-11-23 19:17 ` [PATCH 1/3] binder: avoid potential data leakage when copying txn Todd Kjos
                   ` (3 more replies)
  0 siblings, 4 replies; 20+ messages in thread
From: Todd Kjos @ 2021-11-23 19:17 UTC (permalink / raw)
  To: tkjos, gregkh, christian, arve, devel, linux-kernel, maco
  Cc: joel, kernel-team

Binder copies transactions directly from the sender buffer
to the target buffer and then fixes up BINDER_TYPE_PTR and
BINDER_TYPE_FDA objects. This means there is a brief time
when sender pointers and fds are visible to the target
process.

This series reworks the the sender to target copy to
avoid leaking any untranslated sender data from being
visible in the target.

Todd Kjos (3):
  binder: defer copies of pre-patched txn data
  binder: read pre-translated fds from sender buffer
  binder: avoid potential data leakage when copying txn

 drivers/android/binder.c | 442 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------------
 1 file changed, 387 insertions(+), 55 deletions(-)

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [PATCH 1/3] binder: avoid potential data leakage when copying txn
  2021-11-23 19:17 [PATCH 0/3] binder: Prevent untranslated sender data from being copied to target Todd Kjos
@ 2021-11-23 19:17 ` Todd Kjos
  2021-11-24  7:50   ` Martijn Coenen
                     ` (3 more replies)
  2021-11-23 19:17 ` [PATCH 2/3] binder: read pre-translated fds from sender buffer Todd Kjos
                   ` (2 subsequent siblings)
  3 siblings, 4 replies; 20+ messages in thread
From: Todd Kjos @ 2021-11-23 19:17 UTC (permalink / raw)
  To: tkjos, gregkh, christian, arve, devel, linux-kernel, maco
  Cc: joel, kernel-team

Transactions are copied from the sender to the target
first and objects like BINDER_TYPE_PTR and BINDER_TYPE_FDA
are then fixed up. This means there is a short period where
the sender's version of these objects are visible to the
target prior to the fixups.

Instead of copying all of the data first, copy data only
after any needed fixups have been applied.

Signed-off-by: Todd Kjos <tkjos@google.com>
---
 drivers/android/binder.c | 95 +++++++++++++++++++++++++++++-----------
 1 file changed, 70 insertions(+), 25 deletions(-)

diff --git a/drivers/android/binder.c b/drivers/android/binder.c
index 49fb74196d02..571d3c203557 100644
--- a/drivers/android/binder.c
+++ b/drivers/android/binder.c
@@ -1608,15 +1608,21 @@ static void binder_cleanup_transaction(struct binder_transaction *t,
 /**
  * binder_get_object() - gets object and checks for valid metadata
  * @proc:	binder_proc owning the buffer
+ * @u:		sender's user pointer to base of buffer
  * @buffer:	binder_buffer that we're parsing.
  * @offset:	offset in the @buffer at which to validate an object.
  * @object:	struct binder_object to read into
  *
- * Return:	If there's a valid metadata object at @offset in @buffer, the
+ * Copy the binder object at the given offset into @object. If @u is
+ * provided then the copy is from the sender's buffer. If not, then
+ * it is copied from the target's @buffer.
+ *
+ * Return:	If there's a valid metadata object at @offset, the
  *		size of that object. Otherwise, it returns zero. The object
  *		is read into the struct binder_object pointed to by @object.
  */
 static size_t binder_get_object(struct binder_proc *proc,
+				const void __user *u,
 				struct binder_buffer *buffer,
 				unsigned long offset,
 				struct binder_object *object)
@@ -1626,10 +1632,16 @@ static size_t binder_get_object(struct binder_proc *proc,
 	size_t object_size = 0;
 
 	read_size = min_t(size_t, sizeof(*object), buffer->data_size - offset);
-	if (offset > buffer->data_size || read_size < sizeof(*hdr) ||
-	    binder_alloc_copy_from_buffer(&proc->alloc, object, buffer,
-					  offset, read_size))
+	if (offset > buffer->data_size || read_size < sizeof(*hdr))
 		return 0;
+	if (u) {
+		if (copy_from_user(object, u + offset, read_size))
+			return 0;
+	} else {
+		if (binder_alloc_copy_from_buffer(&proc->alloc, object, buffer,
+						  offset, read_size))
+			return 0;
+	}
 
 	/* Ok, now see if we read a complete object. */
 	hdr = &object->hdr;
@@ -1702,7 +1714,7 @@ static struct binder_buffer_object *binder_validate_ptr(
 					  b, buffer_offset,
 					  sizeof(object_offset)))
 		return NULL;
-	object_size = binder_get_object(proc, b, object_offset, object);
+	object_size = binder_get_object(proc, NULL, b, object_offset, object);
 	if (!object_size || object->hdr.type != BINDER_TYPE_PTR)
 		return NULL;
 	if (object_offsetp)
@@ -1767,7 +1779,8 @@ static bool binder_validate_fixup(struct binder_proc *proc,
 		unsigned long buffer_offset;
 		struct binder_object last_object;
 		struct binder_buffer_object *last_bbo;
-		size_t object_size = binder_get_object(proc, b, last_obj_offset,
+		size_t object_size = binder_get_object(proc, NULL, b,
+						       last_obj_offset,
 						       &last_object);
 		if (object_size != sizeof(*last_bbo))
 			return false;
@@ -1882,7 +1895,7 @@ static void binder_transaction_buffer_release(struct binder_proc *proc,
 		if (!binder_alloc_copy_from_buffer(&proc->alloc, &object_offset,
 						   buffer, buffer_offset,
 						   sizeof(object_offset)))
-			object_size = binder_get_object(proc, buffer,
+			object_size = binder_get_object(proc, NULL, buffer,
 							object_offset, &object);
 		if (object_size == 0) {
 			pr_err("transaction release %d bad object at offset %lld, size %zd\n",
@@ -2455,6 +2468,7 @@ static void binder_transaction(struct binder_proc *proc,
 	binder_size_t off_start_offset, off_end_offset;
 	binder_size_t off_min;
 	binder_size_t sg_buf_offset, sg_buf_end_offset;
+	binder_size_t user_offset = 0;
 	struct binder_proc *target_proc = NULL;
 	struct binder_thread *target_thread = NULL;
 	struct binder_node *target_node = NULL;
@@ -2469,6 +2483,8 @@ static void binder_transaction(struct binder_proc *proc,
 	int t_debug_id = atomic_inc_return(&binder_last_id);
 	char *secctx = NULL;
 	u32 secctx_sz = 0;
+	const void __user *user_buffer = (const void __user *)
+				(uintptr_t)tr->data.ptr.buffer;
 
 	e = binder_transaction_log_add(&binder_transaction_log);
 	e->debug_id = t_debug_id;
@@ -2692,7 +2708,7 @@ static void binder_transaction(struct binder_proc *proc,
 			     "%d:%d BC_REPLY %d -> %d:%d, data %016llx-%016llx size %lld-%lld-%lld\n",
 			     proc->pid, thread->pid, t->debug_id,
 			     target_proc->pid, target_thread->pid,
-			     (u64)tr->data.ptr.buffer,
+			     (u64)user_buffer,
 			     (u64)tr->data.ptr.offsets,
 			     (u64)tr->data_size, (u64)tr->offsets_size,
 			     (u64)extra_buffers_size);
@@ -2701,7 +2717,7 @@ static void binder_transaction(struct binder_proc *proc,
 			     "%d:%d BC_TRANSACTION %d -> %d - node %d, data %016llx-%016llx size %lld-%lld-%lld\n",
 			     proc->pid, thread->pid, t->debug_id,
 			     target_proc->pid, target_node->debug_id,
-			     (u64)tr->data.ptr.buffer,
+			     (u64)user_buffer,
 			     (u64)tr->data.ptr.offsets,
 			     (u64)tr->data_size, (u64)tr->offsets_size,
 			     (u64)extra_buffers_size);
@@ -2780,19 +2796,6 @@ static void binder_transaction(struct binder_proc *proc,
 	t->buffer->clear_on_free = !!(t->flags & TF_CLEAR_BUF);
 	trace_binder_transaction_alloc_buf(t->buffer);
 
-	if (binder_alloc_copy_user_to_buffer(
-				&target_proc->alloc,
-				t->buffer, 0,
-				(const void __user *)
-					(uintptr_t)tr->data.ptr.buffer,
-				tr->data_size)) {
-		binder_user_error("%d:%d got transaction with invalid data ptr\n",
-				proc->pid, thread->pid);
-		return_error = BR_FAILED_REPLY;
-		return_error_param = -EFAULT;
-		return_error_line = __LINE__;
-		goto err_copy_data_failed;
-	}
 	if (binder_alloc_copy_user_to_buffer(
 				&target_proc->alloc,
 				t->buffer,
@@ -2837,6 +2840,7 @@ static void binder_transaction(struct binder_proc *proc,
 		size_t object_size;
 		struct binder_object object;
 		binder_size_t object_offset;
+		binder_size_t copy_size;
 
 		if (binder_alloc_copy_from_buffer(&target_proc->alloc,
 						  &object_offset,
@@ -2848,8 +2852,27 @@ static void binder_transaction(struct binder_proc *proc,
 			return_error_line = __LINE__;
 			goto err_bad_offset;
 		}
-		object_size = binder_get_object(target_proc, t->buffer,
-						object_offset, &object);
+
+		/*
+		 * Copy the source user buffer up to the next object
+		 * that will be processed.
+		 */
+		copy_size = object_offset - user_offset;
+		if (copy_size && (user_offset > object_offset ||
+				binder_alloc_copy_user_to_buffer(
+					&target_proc->alloc,
+					t->buffer, user_offset,
+					user_buffer + user_offset,
+					copy_size))) {
+			binder_user_error("%d:%d got transaction with invalid data ptr\n",
+					proc->pid, thread->pid);
+			return_error = BR_FAILED_REPLY;
+			return_error_param = -EFAULT;
+			return_error_line = __LINE__;
+			goto err_copy_data_failed;
+		}
+		object_size = binder_get_object(target_proc, user_buffer,
+				t->buffer, object_offset, &object);
 		if (object_size == 0 || object_offset < off_min) {
 			binder_user_error("%d:%d got transaction with invalid offset (%lld, min %lld max %lld) or object.\n",
 					  proc->pid, thread->pid,
@@ -2861,6 +2884,11 @@ static void binder_transaction(struct binder_proc *proc,
 			return_error_line = __LINE__;
 			goto err_bad_offset;
 		}
+		/*
+		 * Set offset to the next buffer fragment to be
+		 * copied
+		 */
+		user_offset = object_offset + object_size;
 
 		hdr = &object.hdr;
 		off_min = object_offset + object_size;
@@ -2956,7 +2984,11 @@ static void binder_transaction(struct binder_proc *proc,
 			}
 			ret = binder_translate_fd_array(fda, parent, t, thread,
 							in_reply_to);
-			if (ret < 0) {
+			if (ret < 0 ||
+			    binder_alloc_copy_to_buffer(&target_proc->alloc,
+							t->buffer,
+							object_offset,
+							fda, sizeof(*fda))) {
 				return_error = BR_FAILED_REPLY;
 				return_error_param = ret;
 				return_error_line = __LINE__;
@@ -3028,6 +3060,19 @@ static void binder_transaction(struct binder_proc *proc,
 			goto err_bad_object_type;
 		}
 	}
+	/* Done processing objects, copy the rest of the buffer */
+	if (binder_alloc_copy_user_to_buffer(
+				&target_proc->alloc,
+				t->buffer, user_offset,
+				user_buffer + user_offset,
+				tr->data_size - user_offset)) {
+		binder_user_error("%d:%d got transaction with invalid data ptr\n",
+				proc->pid, thread->pid);
+		return_error = BR_FAILED_REPLY;
+		return_error_param = -EFAULT;
+		return_error_line = __LINE__;
+		goto err_copy_data_failed;
+	}
 	if (t->buffer->oneway_spam_suspect)
 		tcomplete->type = BINDER_WORK_TRANSACTION_ONEWAY_SPAM_SUSPECT;
 	else
-- 
2.34.0.rc2.393.gf8c9666880-goog


^ permalink raw reply	[flat|nested] 20+ messages in thread

* [PATCH 2/3] binder: read pre-translated fds from sender buffer
  2021-11-23 19:17 [PATCH 0/3] binder: Prevent untranslated sender data from being copied to target Todd Kjos
  2021-11-23 19:17 ` [PATCH 1/3] binder: avoid potential data leakage when copying txn Todd Kjos
@ 2021-11-23 19:17 ` Todd Kjos
  2021-11-24  7:50   ` Martijn Coenen
  2021-11-24 12:37   ` Dan Carpenter
  2021-11-23 19:17 ` [PATCH 3/3] binder: defer copies of pre-patched txn data Todd Kjos
  2021-11-24  8:08 ` [PATCH 0/3] binder: Prevent untranslated sender data from being copied to target Greg KH
  3 siblings, 2 replies; 20+ messages in thread
From: Todd Kjos @ 2021-11-23 19:17 UTC (permalink / raw)
  To: tkjos, gregkh, christian, arve, devel, linux-kernel, maco
  Cc: joel, kernel-team

Since we are no longer going to copy the pre-fixup
data from the target buffer, we need to read
pre-translated FD array information from the source
buffer.

Signed-off-by: Todd Kjos <tkjos@google.com>
---
 drivers/android/binder.c | 40 +++++++++++++++++++++++++++++++++-------
 1 file changed, 33 insertions(+), 7 deletions(-)

diff --git a/drivers/android/binder.c b/drivers/android/binder.c
index 571d3c203557..2300fa8e09d5 100644
--- a/drivers/android/binder.c
+++ b/drivers/android/binder.c
@@ -2234,15 +2234,17 @@ static int binder_translate_fd(u32 fd, binder_size_t fd_offset,
 }
 
 static int binder_translate_fd_array(struct binder_fd_array_object *fda,
+				     const void __user *u,
 				     struct binder_buffer_object *parent,
+				     struct binder_buffer_object *uparent,
 				     struct binder_transaction *t,
 				     struct binder_thread *thread,
 				     struct binder_transaction *in_reply_to)
 {
 	binder_size_t fdi, fd_buf_size;
 	binder_size_t fda_offset;
+	const void __user *ufda_base;
 	struct binder_proc *proc = thread->proc;
-	struct binder_proc *target_proc = t->to_proc;
 
 	fd_buf_size = sizeof(u32) * fda->num_fds;
 	if (fda->num_fds >= SIZE_MAX / sizeof(u32)) {
@@ -2266,7 +2268,10 @@ static int binder_translate_fd_array(struct binder_fd_array_object *fda,
 	 */
 	fda_offset = (parent->buffer - (uintptr_t)t->buffer->user_data) +
 		fda->parent_offset;
-	if (!IS_ALIGNED((unsigned long)fda_offset, sizeof(u32))) {
+	ufda_base = (void __user *)uparent->buffer + fda->parent_offset;
+
+	if (!IS_ALIGNED((unsigned long)fda_offset, sizeof(u32)) ||
+	    !IS_ALIGNED((unsigned long)ufda_base, sizeof(u32))) {
 		binder_user_error("%d:%d parent offset not aligned correctly.\n",
 				  proc->pid, thread->pid);
 		return -EINVAL;
@@ -2275,10 +2280,9 @@ static int binder_translate_fd_array(struct binder_fd_array_object *fda,
 		u32 fd;
 		int ret;
 		binder_size_t offset = fda_offset + fdi * sizeof(fd);
+		binder_size_t uoffset = fdi * sizeof(fd);
 
-		ret = binder_alloc_copy_from_buffer(&target_proc->alloc,
-						    &fd, t->buffer,
-						    offset, sizeof(fd));
+		ret = copy_from_user(&fd, ufda_base + uoffset, sizeof(fd));
 		if (!ret)
 			ret = binder_translate_fd(fd, offset, t, thread,
 						  in_reply_to);
@@ -2951,6 +2955,8 @@ static void binder_transaction(struct binder_proc *proc,
 		case BINDER_TYPE_FDA: {
 			struct binder_object ptr_object;
 			binder_size_t parent_offset;
+			struct binder_object user_object;
+			size_t user_parent_size;
 			struct binder_fd_array_object *fda =
 				to_binder_fd_array_object(hdr);
 			size_t num_valid = (buffer_offset - off_start_offset) /
@@ -2982,8 +2988,28 @@ static void binder_transaction(struct binder_proc *proc,
 				return_error_line = __LINE__;
 				goto err_bad_parent;
 			}
-			ret = binder_translate_fd_array(fda, parent, t, thread,
-							in_reply_to);
+
+			/*
+			 * We need to read the user version of the parent
+			 * object to get the original user offset
+			 */
+			user_parent_size =
+				binder_get_object(proc, user_buffer, t->buffer,
+						  parent_offset, &user_object);
+			if (user_parent_size != sizeof(user_object.bbo)) {
+				binder_user_error("%d:%d invalid ptr object size: %lld vs %lld\n",
+						  proc->pid, thread->pid,
+						  user_parent_size,
+						  sizeof(user_object.bbo));
+				return_error = BR_FAILED_REPLY;
+				return_error_param = -EINVAL;
+				return_error_line = __LINE__;
+				goto err_bad_parent;
+			}
+			ret = binder_translate_fd_array(fda, user_buffer,
+							parent,
+							&user_object.bbo, t,
+							thread, in_reply_to);
 			if (ret < 0 ||
 			    binder_alloc_copy_to_buffer(&target_proc->alloc,
 							t->buffer,
-- 
2.34.0.rc2.393.gf8c9666880-goog


^ permalink raw reply	[flat|nested] 20+ messages in thread

* [PATCH 3/3] binder: defer copies of pre-patched txn data
  2021-11-23 19:17 [PATCH 0/3] binder: Prevent untranslated sender data from being copied to target Todd Kjos
  2021-11-23 19:17 ` [PATCH 1/3] binder: avoid potential data leakage when copying txn Todd Kjos
  2021-11-23 19:17 ` [PATCH 2/3] binder: read pre-translated fds from sender buffer Todd Kjos
@ 2021-11-23 19:17 ` Todd Kjos
  2021-11-24  7:50   ` Martijn Coenen
                     ` (2 more replies)
  2021-11-24  8:08 ` [PATCH 0/3] binder: Prevent untranslated sender data from being copied to target Greg KH
  3 siblings, 3 replies; 20+ messages in thread
From: Todd Kjos @ 2021-11-23 19:17 UTC (permalink / raw)
  To: tkjos, gregkh, christian, arve, devel, linux-kernel, maco
  Cc: joel, kernel-team

BINDER_TYPE_PTR objects point to memory areas in the
source process to be copied into the target buffer
as part of a transaction. This implements a scatter-
gather model where non-contiguous memory in a source
process is "gathered" into a contiguous region in
the target buffer.

The data can include pointers that must be fixed up
to correctly point to the copied data. To avoid making
source process pointers visible to the target process,
this patch defers the copy until the fixups are known
and then copies and fixeups are done together.

There is a special case of BINDER_TYPE_FDA which applies
the fixup later in the target process context. In this
case the user data is skipped (so no untranslated fds
become visible to the target).

Signed-off-by: Todd Kjos <tkjos@google.com>
---
 drivers/android/binder.c | 311 +++++++++++++++++++++++++++++++++++----
 1 file changed, 286 insertions(+), 25 deletions(-)

diff --git a/drivers/android/binder.c b/drivers/android/binder.c
index 2300fa8e09d5..56dc814b8dde 100644
--- a/drivers/android/binder.c
+++ b/drivers/android/binder.c
@@ -2233,7 +2233,258 @@ static int binder_translate_fd(u32 fd, binder_size_t fd_offset,
 	return ret;
 }
 
-static int binder_translate_fd_array(struct binder_fd_array_object *fda,
+/**
+ * struct binder_ptr_fixup - data to be fixed-up in target buffer
+ * @offset	offset in target buffer to fixup
+ * @skip_size	bytes to skip in copy (fixup will be written later)
+ * @fixup_data	data to write at fixup offset
+ * @node	list node
+ *
+ * This is used for the pointer fixup list (pf) which is created and consumed
+ * during binder_transaction() and is only accessed locally. No
+ * locking is necessary.
+ *
+ * The list is ordered by @offset.
+ */
+struct binder_ptr_fixup {
+	binder_size_t offset;
+	size_t skip_size;
+	binder_uintptr_t fixup_data;
+	struct list_head node;
+};
+
+/**
+ * struct binder_sg_copy - scatter-gather data to be copied
+ * @offset	offset in target buffer
+ * @uaddr	user address in source buffer
+ * @length	bytes to copy
+ * @node	list node
+ *
+ * This is used for the sg copy list (sgc) which is created and consumed
+ * during binder_transaction() and is only accessed locally. No
+ * locking is necessary.
+ *
+ * The list is ordered by @offset.
+ */
+struct binder_sg_copy {
+	binder_size_t offset;
+	const void __user *uaddr;
+	size_t length;
+	struct list_head node;
+};
+
+/**
+ * binder_do_deferred_txn_copies() - copy and fixup scatter-gather data
+ * @alloc:	binder_alloc associated with @buffer
+ * @buffer:	binder buffer in target process
+ * @sgc_head:	list_head of scatter-gather copy list
+ * @pf_head:	list_head of pointer fixup list
+ *
+ * Processes all elements of @sgc_head, applying fixups from @pf_head
+ * and copying the scatter-gather data from the source process' user
+ * buffer to the target's buffer. It is expected that the list creation
+ * and processing all occurs during binder_transaction() so these lists
+ * are only accessed in local context.
+ *
+ * Return: 0=success, else -errno
+ */
+static int binder_do_deferred_txn_copies(struct binder_alloc *alloc,
+					 struct binder_buffer *buffer,
+					 struct list_head *sgc_head,
+					 struct list_head *pf_head)
+{
+	int ret = 0;
+	struct list_head *entry, *tmp;
+	struct binder_ptr_fixup *pf =
+		list_first_entry_or_null(pf_head, struct binder_ptr_fixup,
+					 node);
+
+	list_for_each_safe(entry, tmp, sgc_head) {
+		size_t bytes_copied = 0;
+		struct binder_sg_copy *sgc =
+			container_of(entry, struct binder_sg_copy, node);
+
+		while (bytes_copied < sgc->length) {
+			size_t copy_size;
+			size_t bytes_left = sgc->length - bytes_copied;
+			size_t offset = sgc->offset + bytes_copied;
+
+			/*
+			 * We copy up to the fixup (pointed to by pf)
+			 */
+			copy_size = pf ? min(bytes_left, (size_t)pf->offset - offset)
+				       : bytes_left;
+			if (!ret && copy_size)
+				ret = binder_alloc_copy_user_to_buffer(
+						alloc, buffer,
+						offset,
+						sgc->uaddr + bytes_copied,
+						copy_size);
+			bytes_copied += copy_size;
+			if (copy_size != bytes_left) {
+				BUG_ON(!pf);
+				/* we stopped at a fixup offset */
+				if (pf->skip_size) {
+					/*
+					 * we are just skipping. This is for
+					 * BINDER_TYPE_FDA where the translated
+					 * fds will be fixed up when we get
+					 * to target context.
+					 */
+					bytes_copied += pf->skip_size;
+				} else {
+					/* apply the fixup indicated by pf */
+					if (!ret)
+						ret = binder_alloc_copy_to_buffer(
+							alloc, buffer,
+							pf->offset,
+							&pf->fixup_data,
+							sizeof(pf->fixup_data));
+					bytes_copied += sizeof(pf->fixup_data);
+				}
+				list_del(&pf->node);
+				kfree(pf);
+				pf = list_first_entry_or_null(pf_head,
+						struct binder_ptr_fixup, node);
+			}
+		}
+		list_del(&sgc->node);
+		kfree(sgc);
+	}
+	BUG_ON(!list_empty(pf_head));
+	BUG_ON(!list_empty(sgc_head));
+
+	return ret;
+}
+
+/**
+ * binder_cleanup_deferred_txn_lists() - free specified lists
+ * @sgc_head:	list_head of scatter-gather copy list
+ * @pf_head:	list_head of pointer fixup list
+ *
+ * Called to clean up @sgc_head and @pf_head if there is an
+ * error.
+ */
+static void binder_cleanup_deferred_txn_lists(struct list_head *sgc_head,
+					      struct list_head *pf_head)
+{
+	struct list_head *entry, *tmp;
+
+	list_for_each_safe(entry, tmp, sgc_head) {
+		struct binder_sg_copy *sgc =
+			container_of(entry, struct binder_sg_copy, node);
+		list_del(&sgc->node);
+		kfree(sgc);
+	}
+	list_for_each_safe(entry, tmp, pf_head) {
+		struct binder_ptr_fixup *pf =
+			container_of(entry, struct binder_ptr_fixup, node);
+		list_del(&pf->node);
+		kfree(pf);
+	}
+}
+
+/**
+ * binder_defer_copy() - queue a scatter-gather buffer for copy
+ * @sgc_head:	list_head of scatter-gather copy list
+ * @offset:	binder buffer offset in target process
+ * @uaddr:	user address in source process
+ * @length:	bytes to copy
+ *
+ * Specify a scatter-gather block to be copied. The actual copy must
+ * be deferred until all the needed fixups are identified and queued.
+ * Then the copy and fixups are done together so un-translated values
+ * from the source are never visible in the target buffer.
+ *
+ * We are guaranteed that repeated calls to this function will have
+ * monotonically increasing @offset values so the list will naturally
+ * be ordered.
+ *
+ * Return: 0=success, else -errno
+ */
+static int binder_defer_copy(struct list_head *sgc_head, binder_size_t offset,
+			     const void __user *uaddr, size_t length)
+{
+	struct binder_sg_copy *bc = kzalloc(sizeof(*bc), GFP_KERNEL);
+
+	if (!bc)
+		return -ENOMEM;
+
+	bc->offset = offset;
+	bc->uaddr = uaddr;
+	bc->length = length;
+	INIT_LIST_HEAD(&bc->node);
+
+	/*
+	 * We are guaranteed that the deferred copies are in-order
+	 * so just add to the tail.
+	 */
+	list_add_tail(&bc->node, sgc_head);
+
+	return 0;
+}
+
+/**
+ * binder_add_fixup() - queue a fixup to be applied to sg copy
+ * @pf_head:	list_head of binder ptr fixup list
+ * @offset:	binder buffer offset in target process
+ * @fixup:	bytes to be copied for fixup
+ * @skip_size:	bytes to skip when copying (fixup will be applied later)
+ *
+ * Add the specified fixup to a list ordered by @offset. When copying
+ * the scatter-gather buffers, the fixup will be copied instead of
+ * data from the source buffer. For BINDER_TYPE_FDA fixups, the fixup
+ * will be applied later (in target process context), so we just skip
+ * the bytes specified by @skip_size. If @skip_size is 0, we copy the
+ * value in @fixup.
+ *
+ * This function is called *mostly* in @offset order, but there are
+ * exceptions. Since out-of-order inserts are relatively uncommon,
+ * we insert the new element by searching backward from the tail of
+ * the list.
+ *
+ * Return: 0=success, else -errno
+ */
+static int binder_add_fixup(struct list_head *pf_head, binder_size_t offset,
+			    binder_uintptr_t fixup, size_t skip_size)
+{
+	struct binder_ptr_fixup *pf = kzalloc(sizeof(*pf), GFP_KERNEL);
+	struct list_head *tmp;
+
+	if (!pf)
+		return -ENOMEM;
+
+	pf->offset = offset;
+	pf->fixup_data = fixup;
+	pf->skip_size = skip_size;
+	INIT_LIST_HEAD(&pf->node);
+
+	/* Fixups are *mostly* added in-order, but there are some
+	 * exceptions. Look backwards through list for insertion point.
+	 */
+	if (!list_empty(pf_head)) {
+		list_for_each_prev(tmp, pf_head) {
+			struct binder_ptr_fixup *tmppf =
+				list_entry(tmp, struct binder_ptr_fixup, node);
+
+			if (tmppf->offset < pf->offset) {
+				list_add(&pf->node, tmp);
+				return 0;
+			}
+		}
+		/*
+		 * if we get here, then the new offset is the lowest so
+		 * insert at the head
+		 */
+		list_add(&pf->node, pf_head);
+		return 0;
+	}
+	list_add_tail(&pf->node, pf_head);
+	return 0;
+}
+
+static int binder_translate_fd_array(struct list_head *pf_head,
+				     struct binder_fd_array_object *fda,
 				     const void __user *u,
 				     struct binder_buffer_object *parent,
 				     struct binder_buffer_object *uparent,
@@ -2245,6 +2496,7 @@ static int binder_translate_fd_array(struct binder_fd_array_object *fda,
 	binder_size_t fda_offset;
 	const void __user *ufda_base;
 	struct binder_proc *proc = thread->proc;
+	int ret;
 
 	fd_buf_size = sizeof(u32) * fda->num_fds;
 	if (fda->num_fds >= SIZE_MAX / sizeof(u32)) {
@@ -2276,9 +2528,12 @@ static int binder_translate_fd_array(struct binder_fd_array_object *fda,
 				  proc->pid, thread->pid);
 		return -EINVAL;
 	}
+	ret = binder_add_fixup(pf_head, fda_offset, 0, fda->num_fds * sizeof(u32));
+	if (ret)
+		return ret;
+
 	for (fdi = 0; fdi < fda->num_fds; fdi++) {
 		u32 fd;
-		int ret;
 		binder_size_t offset = fda_offset + fdi * sizeof(fd);
 		binder_size_t uoffset = fdi * sizeof(fd);
 
@@ -2292,7 +2547,8 @@ static int binder_translate_fd_array(struct binder_fd_array_object *fda,
 	return 0;
 }
 
-static int binder_fixup_parent(struct binder_transaction *t,
+static int binder_fixup_parent(struct list_head *pf_head,
+			       struct binder_transaction *t,
 			       struct binder_thread *thread,
 			       struct binder_buffer_object *bp,
 			       binder_size_t off_start_offset,
@@ -2338,14 +2594,7 @@ static int binder_fixup_parent(struct binder_transaction *t,
 	}
 	buffer_offset = bp->parent_offset +
 			(uintptr_t)parent->buffer - (uintptr_t)b->user_data;
-	if (binder_alloc_copy_to_buffer(&target_proc->alloc, b, buffer_offset,
-					&bp->buffer, sizeof(bp->buffer))) {
-		binder_user_error("%d:%d got transaction with invalid parent offset\n",
-				  proc->pid, thread->pid);
-		return -EINVAL;
-	}
-
-	return 0;
+	return binder_add_fixup(pf_head, buffer_offset, bp->buffer, 0);
 }
 
 /**
@@ -2487,8 +2736,12 @@ static void binder_transaction(struct binder_proc *proc,
 	int t_debug_id = atomic_inc_return(&binder_last_id);
 	char *secctx = NULL;
 	u32 secctx_sz = 0;
+	struct list_head sgc_head;
+	struct list_head pf_head;
 	const void __user *user_buffer = (const void __user *)
 				(uintptr_t)tr->data.ptr.buffer;
+	INIT_LIST_HEAD(&sgc_head);
+	INIT_LIST_HEAD(&pf_head);
 
 	e = binder_transaction_log_add(&binder_transaction_log);
 	e->debug_id = t_debug_id;
@@ -3006,8 +3259,8 @@ static void binder_transaction(struct binder_proc *proc,
 				return_error_line = __LINE__;
 				goto err_bad_parent;
 			}
-			ret = binder_translate_fd_array(fda, user_buffer,
-							parent,
+			ret = binder_translate_fd_array(&pf_head, fda,
+							user_buffer, parent,
 							&user_object.bbo, t,
 							thread, in_reply_to);
 			if (ret < 0 ||
@@ -3038,19 +3291,14 @@ static void binder_transaction(struct binder_proc *proc,
 				return_error_line = __LINE__;
 				goto err_bad_offset;
 			}
-			if (binder_alloc_copy_user_to_buffer(
-						&target_proc->alloc,
-						t->buffer,
-						sg_buf_offset,
-						(const void __user *)
-							(uintptr_t)bp->buffer,
-						bp->length)) {
-				binder_user_error("%d:%d got transaction with invalid offsets ptr\n",
-						  proc->pid, thread->pid);
-				return_error_param = -EFAULT;
+			ret = binder_defer_copy(&sgc_head, sg_buf_offset,
+				(const void __user *)(uintptr_t)bp->buffer,
+				bp->length);
+			if (ret) {
 				return_error = BR_FAILED_REPLY;
+				return_error_param = ret;
 				return_error_line = __LINE__;
-				goto err_copy_data_failed;
+				goto err_translate_failed;
 			}
 			/* Fixup buffer pointer to target proc address space */
 			bp->buffer = (uintptr_t)
@@ -3059,7 +3307,8 @@ static void binder_transaction(struct binder_proc *proc,
 
 			num_valid = (buffer_offset - off_start_offset) /
 					sizeof(binder_size_t);
-			ret = binder_fixup_parent(t, thread, bp,
+			ret = binder_fixup_parent(&pf_head, t,
+						  thread, bp,
 						  off_start_offset,
 						  num_valid,
 						  last_fixup_obj_off,
@@ -3099,6 +3348,17 @@ static void binder_transaction(struct binder_proc *proc,
 		return_error_line = __LINE__;
 		goto err_copy_data_failed;
 	}
+
+	ret = binder_do_deferred_txn_copies(&target_proc->alloc, t->buffer,
+					    &sgc_head, &pf_head);
+	if (ret) {
+		binder_user_error("%d:%d got transaction with invalid offsets ptr\n",
+				  proc->pid, thread->pid);
+		return_error = BR_FAILED_REPLY;
+		return_error_param = ret;
+		return_error_line = __LINE__;
+		goto err_copy_data_failed;
+	}
 	if (t->buffer->oneway_spam_suspect)
 		tcomplete->type = BINDER_WORK_TRANSACTION_ONEWAY_SPAM_SUSPECT;
 	else
@@ -3172,6 +3432,7 @@ static void binder_transaction(struct binder_proc *proc,
 err_bad_offset:
 err_bad_parent:
 err_copy_data_failed:
+	binder_cleanup_deferred_txn_lists(&sgc_head, &pf_head);
 	binder_free_txn_fixups(t);
 	trace_binder_transaction_failed_buffer_release(t->buffer);
 	binder_transaction_buffer_release(target_proc, NULL, t->buffer,
-- 
2.34.0.rc2.393.gf8c9666880-goog


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 1/3] binder: avoid potential data leakage when copying txn
  2021-11-23 19:17 ` [PATCH 1/3] binder: avoid potential data leakage when copying txn Todd Kjos
@ 2021-11-24  7:50   ` Martijn Coenen
  2021-11-24 13:01   ` Dan Carpenter
                     ` (2 subsequent siblings)
  3 siblings, 0 replies; 20+ messages in thread
From: Martijn Coenen @ 2021-11-24  7:50 UTC (permalink / raw)
  To: Todd Kjos
  Cc: gregkh, christian, arve, devel, linux-kernel, maco, joel, kernel-team

On Tue, Nov 23, 2021 at 8:17 PM 'Todd Kjos' via kernel-team
<kernel-team@android.com> wrote:
>
> Transactions are copied from the sender to the target
> first and objects like BINDER_TYPE_PTR and BINDER_TYPE_FDA
> are then fixed up. This means there is a short period where
> the sender's version of these objects are visible to the
> target prior to the fixups.
>
> Instead of copying all of the data first, copy data only
> after any needed fixups have been applied.
>
> Signed-off-by: Todd Kjos <tkjos@google.com>
Reviewed-by: Martijn Coenen <maco@android.com>

> ---
>  drivers/android/binder.c | 95 +++++++++++++++++++++++++++++-----------
>  1 file changed, 70 insertions(+), 25 deletions(-)
>
> diff --git a/drivers/android/binder.c b/drivers/android/binder.c
> index 49fb74196d02..571d3c203557 100644
> --- a/drivers/android/binder.c
> +++ b/drivers/android/binder.c
> @@ -1608,15 +1608,21 @@ static void binder_cleanup_transaction(struct binder_transaction *t,
>  /**
>   * binder_get_object() - gets object and checks for valid metadata
>   * @proc:      binder_proc owning the buffer
> + * @u:         sender's user pointer to base of buffer
>   * @buffer:    binder_buffer that we're parsing.
>   * @offset:    offset in the @buffer at which to validate an object.
>   * @object:    struct binder_object to read into
>   *
> - * Return:     If there's a valid metadata object at @offset in @buffer, the
> + * Copy the binder object at the given offset into @object. If @u is
> + * provided then the copy is from the sender's buffer. If not, then
> + * it is copied from the target's @buffer.
> + *
> + * Return:     If there's a valid metadata object at @offset, the
>   *             size of that object. Otherwise, it returns zero. The object
>   *             is read into the struct binder_object pointed to by @object.
>   */
>  static size_t binder_get_object(struct binder_proc *proc,
> +                               const void __user *u,
>                                 struct binder_buffer *buffer,
>                                 unsigned long offset,
>                                 struct binder_object *object)
> @@ -1626,10 +1632,16 @@ static size_t binder_get_object(struct binder_proc *proc,
>         size_t object_size = 0;
>
>         read_size = min_t(size_t, sizeof(*object), buffer->data_size - offset);
> -       if (offset > buffer->data_size || read_size < sizeof(*hdr) ||
> -           binder_alloc_copy_from_buffer(&proc->alloc, object, buffer,
> -                                         offset, read_size))
> +       if (offset > buffer->data_size || read_size < sizeof(*hdr))
>                 return 0;
> +       if (u) {
> +               if (copy_from_user(object, u + offset, read_size))
> +                       return 0;
> +       } else {
> +               if (binder_alloc_copy_from_buffer(&proc->alloc, object, buffer,
> +                                                 offset, read_size))
> +                       return 0;
> +       }
>
>         /* Ok, now see if we read a complete object. */
>         hdr = &object->hdr;
> @@ -1702,7 +1714,7 @@ static struct binder_buffer_object *binder_validate_ptr(
>                                           b, buffer_offset,
>                                           sizeof(object_offset)))
>                 return NULL;
> -       object_size = binder_get_object(proc, b, object_offset, object);
> +       object_size = binder_get_object(proc, NULL, b, object_offset, object);
>         if (!object_size || object->hdr.type != BINDER_TYPE_PTR)
>                 return NULL;
>         if (object_offsetp)
> @@ -1767,7 +1779,8 @@ static bool binder_validate_fixup(struct binder_proc *proc,
>                 unsigned long buffer_offset;
>                 struct binder_object last_object;
>                 struct binder_buffer_object *last_bbo;
> -               size_t object_size = binder_get_object(proc, b, last_obj_offset,
> +               size_t object_size = binder_get_object(proc, NULL, b,
> +                                                      last_obj_offset,
>                                                        &last_object);
>                 if (object_size != sizeof(*last_bbo))
>                         return false;
> @@ -1882,7 +1895,7 @@ static void binder_transaction_buffer_release(struct binder_proc *proc,
>                 if (!binder_alloc_copy_from_buffer(&proc->alloc, &object_offset,
>                                                    buffer, buffer_offset,
>                                                    sizeof(object_offset)))
> -                       object_size = binder_get_object(proc, buffer,
> +                       object_size = binder_get_object(proc, NULL, buffer,
>                                                         object_offset, &object);
>                 if (object_size == 0) {
>                         pr_err("transaction release %d bad object at offset %lld, size %zd\n",
> @@ -2455,6 +2468,7 @@ static void binder_transaction(struct binder_proc *proc,
>         binder_size_t off_start_offset, off_end_offset;
>         binder_size_t off_min;
>         binder_size_t sg_buf_offset, sg_buf_end_offset;
> +       binder_size_t user_offset = 0;
>         struct binder_proc *target_proc = NULL;
>         struct binder_thread *target_thread = NULL;
>         struct binder_node *target_node = NULL;
> @@ -2469,6 +2483,8 @@ static void binder_transaction(struct binder_proc *proc,
>         int t_debug_id = atomic_inc_return(&binder_last_id);
>         char *secctx = NULL;
>         u32 secctx_sz = 0;
> +       const void __user *user_buffer = (const void __user *)
> +                               (uintptr_t)tr->data.ptr.buffer;
>
>         e = binder_transaction_log_add(&binder_transaction_log);
>         e->debug_id = t_debug_id;
> @@ -2692,7 +2708,7 @@ static void binder_transaction(struct binder_proc *proc,
>                              "%d:%d BC_REPLY %d -> %d:%d, data %016llx-%016llx size %lld-%lld-%lld\n",
>                              proc->pid, thread->pid, t->debug_id,
>                              target_proc->pid, target_thread->pid,
> -                            (u64)tr->data.ptr.buffer,
> +                            (u64)user_buffer,
>                              (u64)tr->data.ptr.offsets,
>                              (u64)tr->data_size, (u64)tr->offsets_size,
>                              (u64)extra_buffers_size);
> @@ -2701,7 +2717,7 @@ static void binder_transaction(struct binder_proc *proc,
>                              "%d:%d BC_TRANSACTION %d -> %d - node %d, data %016llx-%016llx size %lld-%lld-%lld\n",
>                              proc->pid, thread->pid, t->debug_id,
>                              target_proc->pid, target_node->debug_id,
> -                            (u64)tr->data.ptr.buffer,
> +                            (u64)user_buffer,
>                              (u64)tr->data.ptr.offsets,
>                              (u64)tr->data_size, (u64)tr->offsets_size,
>                              (u64)extra_buffers_size);
> @@ -2780,19 +2796,6 @@ static void binder_transaction(struct binder_proc *proc,
>         t->buffer->clear_on_free = !!(t->flags & TF_CLEAR_BUF);
>         trace_binder_transaction_alloc_buf(t->buffer);
>
> -       if (binder_alloc_copy_user_to_buffer(
> -                               &target_proc->alloc,
> -                               t->buffer, 0,
> -                               (const void __user *)
> -                                       (uintptr_t)tr->data.ptr.buffer,
> -                               tr->data_size)) {
> -               binder_user_error("%d:%d got transaction with invalid data ptr\n",
> -                               proc->pid, thread->pid);
> -               return_error = BR_FAILED_REPLY;
> -               return_error_param = -EFAULT;
> -               return_error_line = __LINE__;
> -               goto err_copy_data_failed;
> -       }
>         if (binder_alloc_copy_user_to_buffer(
>                                 &target_proc->alloc,
>                                 t->buffer,
> @@ -2837,6 +2840,7 @@ static void binder_transaction(struct binder_proc *proc,
>                 size_t object_size;
>                 struct binder_object object;
>                 binder_size_t object_offset;
> +               binder_size_t copy_size;
>
>                 if (binder_alloc_copy_from_buffer(&target_proc->alloc,
>                                                   &object_offset,
> @@ -2848,8 +2852,27 @@ static void binder_transaction(struct binder_proc *proc,
>                         return_error_line = __LINE__;
>                         goto err_bad_offset;
>                 }
> -               object_size = binder_get_object(target_proc, t->buffer,
> -                                               object_offset, &object);
> +
> +               /*
> +                * Copy the source user buffer up to the next object
> +                * that will be processed.
> +                */
> +               copy_size = object_offset - user_offset;
> +               if (copy_size && (user_offset > object_offset ||
> +                               binder_alloc_copy_user_to_buffer(
> +                                       &target_proc->alloc,
> +                                       t->buffer, user_offset,
> +                                       user_buffer + user_offset,
> +                                       copy_size))) {
> +                       binder_user_error("%d:%d got transaction with invalid data ptr\n",
> +                                       proc->pid, thread->pid);
> +                       return_error = BR_FAILED_REPLY;
> +                       return_error_param = -EFAULT;
> +                       return_error_line = __LINE__;
> +                       goto err_copy_data_failed;
> +               }
> +               object_size = binder_get_object(target_proc, user_buffer,
> +                               t->buffer, object_offset, &object);
>                 if (object_size == 0 || object_offset < off_min) {
>                         binder_user_error("%d:%d got transaction with invalid offset (%lld, min %lld max %lld) or object.\n",
>                                           proc->pid, thread->pid,
> @@ -2861,6 +2884,11 @@ static void binder_transaction(struct binder_proc *proc,
>                         return_error_line = __LINE__;
>                         goto err_bad_offset;
>                 }
> +               /*
> +                * Set offset to the next buffer fragment to be
> +                * copied
> +                */
> +               user_offset = object_offset + object_size;
>
>                 hdr = &object.hdr;
>                 off_min = object_offset + object_size;
> @@ -2956,7 +2984,11 @@ static void binder_transaction(struct binder_proc *proc,
>                         }
>                         ret = binder_translate_fd_array(fda, parent, t, thread,
>                                                         in_reply_to);
> -                       if (ret < 0) {
> +                       if (ret < 0 ||
> +                           binder_alloc_copy_to_buffer(&target_proc->alloc,
> +                                                       t->buffer,
> +                                                       object_offset,
> +                                                       fda, sizeof(*fda))) {
>                                 return_error = BR_FAILED_REPLY;
>                                 return_error_param = ret;
>                                 return_error_line = __LINE__;
> @@ -3028,6 +3060,19 @@ static void binder_transaction(struct binder_proc *proc,
>                         goto err_bad_object_type;
>                 }
>         }
> +       /* Done processing objects, copy the rest of the buffer */
> +       if (binder_alloc_copy_user_to_buffer(
> +                               &target_proc->alloc,
> +                               t->buffer, user_offset,
> +                               user_buffer + user_offset,
> +                               tr->data_size - user_offset)) {
> +               binder_user_error("%d:%d got transaction with invalid data ptr\n",
> +                               proc->pid, thread->pid);
> +               return_error = BR_FAILED_REPLY;
> +               return_error_param = -EFAULT;
> +               return_error_line = __LINE__;
> +               goto err_copy_data_failed;
> +       }
>         if (t->buffer->oneway_spam_suspect)
>                 tcomplete->type = BINDER_WORK_TRANSACTION_ONEWAY_SPAM_SUSPECT;
>         else
> --
> 2.34.0.rc2.393.gf8c9666880-goog
>
>

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 2/3] binder: read pre-translated fds from sender buffer
  2021-11-23 19:17 ` [PATCH 2/3] binder: read pre-translated fds from sender buffer Todd Kjos
@ 2021-11-24  7:50   ` Martijn Coenen
  2021-11-24 12:37   ` Dan Carpenter
  1 sibling, 0 replies; 20+ messages in thread
From: Martijn Coenen @ 2021-11-24  7:50 UTC (permalink / raw)
  To: Todd Kjos
  Cc: gregkh, christian, arve, devel, linux-kernel, maco, joel, kernel-team

On Tue, Nov 23, 2021 at 8:17 PM 'Todd Kjos' via kernel-team
<kernel-team@android.com> wrote:
>
> Since we are no longer going to copy the pre-fixup
> data from the target buffer, we need to read
> pre-translated FD array information from the source
> buffer.
>
> Signed-off-by: Todd Kjos <tkjos@google.com>
Reviewed-by: Martijn Coenen <maco@android.com>

> ---
>  drivers/android/binder.c | 40 +++++++++++++++++++++++++++++++++-------
>  1 file changed, 33 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/android/binder.c b/drivers/android/binder.c
> index 571d3c203557..2300fa8e09d5 100644
> --- a/drivers/android/binder.c
> +++ b/drivers/android/binder.c
> @@ -2234,15 +2234,17 @@ static int binder_translate_fd(u32 fd, binder_size_t fd_offset,
>  }
>
>  static int binder_translate_fd_array(struct binder_fd_array_object *fda,
> +                                    const void __user *u,
>                                      struct binder_buffer_object *parent,
> +                                    struct binder_buffer_object *uparent,
>                                      struct binder_transaction *t,
>                                      struct binder_thread *thread,
>                                      struct binder_transaction *in_reply_to)
>  {
>         binder_size_t fdi, fd_buf_size;
>         binder_size_t fda_offset;
> +       const void __user *ufda_base;
>         struct binder_proc *proc = thread->proc;
> -       struct binder_proc *target_proc = t->to_proc;
>
>         fd_buf_size = sizeof(u32) * fda->num_fds;
>         if (fda->num_fds >= SIZE_MAX / sizeof(u32)) {
> @@ -2266,7 +2268,10 @@ static int binder_translate_fd_array(struct binder_fd_array_object *fda,
>          */
>         fda_offset = (parent->buffer - (uintptr_t)t->buffer->user_data) +
>                 fda->parent_offset;
> -       if (!IS_ALIGNED((unsigned long)fda_offset, sizeof(u32))) {
> +       ufda_base = (void __user *)uparent->buffer + fda->parent_offset;
> +
> +       if (!IS_ALIGNED((unsigned long)fda_offset, sizeof(u32)) ||
> +           !IS_ALIGNED((unsigned long)ufda_base, sizeof(u32))) {
>                 binder_user_error("%d:%d parent offset not aligned correctly.\n",
>                                   proc->pid, thread->pid);
>                 return -EINVAL;
> @@ -2275,10 +2280,9 @@ static int binder_translate_fd_array(struct binder_fd_array_object *fda,
>                 u32 fd;
>                 int ret;
>                 binder_size_t offset = fda_offset + fdi * sizeof(fd);
> +               binder_size_t uoffset = fdi * sizeof(fd);
>
> -               ret = binder_alloc_copy_from_buffer(&target_proc->alloc,
> -                                                   &fd, t->buffer,
> -                                                   offset, sizeof(fd));
> +               ret = copy_from_user(&fd, ufda_base + uoffset, sizeof(fd));
>                 if (!ret)
>                         ret = binder_translate_fd(fd, offset, t, thread,
>                                                   in_reply_to);
> @@ -2951,6 +2955,8 @@ static void binder_transaction(struct binder_proc *proc,
>                 case BINDER_TYPE_FDA: {
>                         struct binder_object ptr_object;
>                         binder_size_t parent_offset;
> +                       struct binder_object user_object;
> +                       size_t user_parent_size;
>                         struct binder_fd_array_object *fda =
>                                 to_binder_fd_array_object(hdr);
>                         size_t num_valid = (buffer_offset - off_start_offset) /
> @@ -2982,8 +2988,28 @@ static void binder_transaction(struct binder_proc *proc,
>                                 return_error_line = __LINE__;
>                                 goto err_bad_parent;
>                         }
> -                       ret = binder_translate_fd_array(fda, parent, t, thread,
> -                                                       in_reply_to);
> +
> +                       /*
> +                        * We need to read the user version of the parent
> +                        * object to get the original user offset
> +                        */
> +                       user_parent_size =
> +                               binder_get_object(proc, user_buffer, t->buffer,
> +                                                 parent_offset, &user_object);
> +                       if (user_parent_size != sizeof(user_object.bbo)) {
> +                               binder_user_error("%d:%d invalid ptr object size: %lld vs %lld\n",
> +                                                 proc->pid, thread->pid,
> +                                                 user_parent_size,
> +                                                 sizeof(user_object.bbo));
> +                               return_error = BR_FAILED_REPLY;
> +                               return_error_param = -EINVAL;
> +                               return_error_line = __LINE__;
> +                               goto err_bad_parent;
> +                       }
> +                       ret = binder_translate_fd_array(fda, user_buffer,
> +                                                       parent,
> +                                                       &user_object.bbo, t,
> +                                                       thread, in_reply_to);
>                         if (ret < 0 ||
>                             binder_alloc_copy_to_buffer(&target_proc->alloc,
>                                                         t->buffer,
> --
> 2.34.0.rc2.393.gf8c9666880-goog
>
>

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 3/3] binder: defer copies of pre-patched txn data
  2021-11-23 19:17 ` [PATCH 3/3] binder: defer copies of pre-patched txn data Todd Kjos
@ 2021-11-24  7:50   ` Martijn Coenen
  2021-11-24 11:09   ` Dan Carpenter
  2021-11-24 12:43   ` Dan Carpenter
  2 siblings, 0 replies; 20+ messages in thread
From: Martijn Coenen @ 2021-11-24  7:50 UTC (permalink / raw)
  To: Todd Kjos
  Cc: gregkh, christian, arve, devel, linux-kernel, maco, joel, kernel-team

On Tue, Nov 23, 2021 at 8:17 PM 'Todd Kjos' via kernel-team
<kernel-team@android.com> wrote:
>
> BINDER_TYPE_PTR objects point to memory areas in the
> source process to be copied into the target buffer
> as part of a transaction. This implements a scatter-
> gather model where non-contiguous memory in a source
> process is "gathered" into a contiguous region in
> the target buffer.
>
> The data can include pointers that must be fixed up
> to correctly point to the copied data. To avoid making
> source process pointers visible to the target process,
> this patch defers the copy until the fixups are known
> and then copies and fixeups are done together.
>
> There is a special case of BINDER_TYPE_FDA which applies
> the fixup later in the target process context. In this
> case the user data is skipped (so no untranslated fds
> become visible to the target).
>
> Signed-off-by: Todd Kjos <tkjos@google.com>
Reviewed-by: Martijn Coenen <maco@android.com>

> ---
>  drivers/android/binder.c | 311 +++++++++++++++++++++++++++++++++++----
>  1 file changed, 286 insertions(+), 25 deletions(-)
>
> diff --git a/drivers/android/binder.c b/drivers/android/binder.c
> index 2300fa8e09d5..56dc814b8dde 100644
> --- a/drivers/android/binder.c
> +++ b/drivers/android/binder.c
> @@ -2233,7 +2233,258 @@ static int binder_translate_fd(u32 fd, binder_size_t fd_offset,
>         return ret;
>  }
>
> -static int binder_translate_fd_array(struct binder_fd_array_object *fda,
> +/**
> + * struct binder_ptr_fixup - data to be fixed-up in target buffer
> + * @offset     offset in target buffer to fixup
> + * @skip_size  bytes to skip in copy (fixup will be written later)
> + * @fixup_data data to write at fixup offset
> + * @node       list node
> + *
> + * This is used for the pointer fixup list (pf) which is created and consumed
> + * during binder_transaction() and is only accessed locally. No
> + * locking is necessary.
> + *
> + * The list is ordered by @offset.
> + */
> +struct binder_ptr_fixup {
> +       binder_size_t offset;
> +       size_t skip_size;
> +       binder_uintptr_t fixup_data;
> +       struct list_head node;
> +};
> +
> +/**
> + * struct binder_sg_copy - scatter-gather data to be copied
> + * @offset     offset in target buffer
> + * @uaddr      user address in source buffer
> + * @length     bytes to copy
> + * @node       list node
> + *
> + * This is used for the sg copy list (sgc) which is created and consumed
> + * during binder_transaction() and is only accessed locally. No
> + * locking is necessary.
> + *
> + * The list is ordered by @offset.
> + */
> +struct binder_sg_copy {
> +       binder_size_t offset;
> +       const void __user *uaddr;
> +       size_t length;
> +       struct list_head node;
> +};
> +
> +/**
> + * binder_do_deferred_txn_copies() - copy and fixup scatter-gather data
> + * @alloc:     binder_alloc associated with @buffer
> + * @buffer:    binder buffer in target process
> + * @sgc_head:  list_head of scatter-gather copy list
> + * @pf_head:   list_head of pointer fixup list
> + *
> + * Processes all elements of @sgc_head, applying fixups from @pf_head
> + * and copying the scatter-gather data from the source process' user
> + * buffer to the target's buffer. It is expected that the list creation
> + * and processing all occurs during binder_transaction() so these lists
> + * are only accessed in local context.
> + *
> + * Return: 0=success, else -errno
> + */
> +static int binder_do_deferred_txn_copies(struct binder_alloc *alloc,
> +                                        struct binder_buffer *buffer,
> +                                        struct list_head *sgc_head,
> +                                        struct list_head *pf_head)
> +{
> +       int ret = 0;
> +       struct list_head *entry, *tmp;
> +       struct binder_ptr_fixup *pf =
> +               list_first_entry_or_null(pf_head, struct binder_ptr_fixup,
> +                                        node);
> +
> +       list_for_each_safe(entry, tmp, sgc_head) {
> +               size_t bytes_copied = 0;
> +               struct binder_sg_copy *sgc =
> +                       container_of(entry, struct binder_sg_copy, node);
> +
> +               while (bytes_copied < sgc->length) {
> +                       size_t copy_size;
> +                       size_t bytes_left = sgc->length - bytes_copied;
> +                       size_t offset = sgc->offset + bytes_copied;
> +
> +                       /*
> +                        * We copy up to the fixup (pointed to by pf)
> +                        */
> +                       copy_size = pf ? min(bytes_left, (size_t)pf->offset - offset)
> +                                      : bytes_left;
> +                       if (!ret && copy_size)
> +                               ret = binder_alloc_copy_user_to_buffer(
> +                                               alloc, buffer,
> +                                               offset,
> +                                               sgc->uaddr + bytes_copied,
> +                                               copy_size);
> +                       bytes_copied += copy_size;
> +                       if (copy_size != bytes_left) {
> +                               BUG_ON(!pf);
> +                               /* we stopped at a fixup offset */
> +                               if (pf->skip_size) {
> +                                       /*
> +                                        * we are just skipping. This is for
> +                                        * BINDER_TYPE_FDA where the translated
> +                                        * fds will be fixed up when we get
> +                                        * to target context.
> +                                        */
> +                                       bytes_copied += pf->skip_size;
> +                               } else {
> +                                       /* apply the fixup indicated by pf */
> +                                       if (!ret)
> +                                               ret = binder_alloc_copy_to_buffer(
> +                                                       alloc, buffer,
> +                                                       pf->offset,
> +                                                       &pf->fixup_data,
> +                                                       sizeof(pf->fixup_data));
> +                                       bytes_copied += sizeof(pf->fixup_data);
> +                               }
> +                               list_del(&pf->node);
> +                               kfree(pf);
> +                               pf = list_first_entry_or_null(pf_head,
> +                                               struct binder_ptr_fixup, node);
> +                       }
> +               }
> +               list_del(&sgc->node);
> +               kfree(sgc);
> +       }
> +       BUG_ON(!list_empty(pf_head));
> +       BUG_ON(!list_empty(sgc_head));
> +
> +       return ret;
> +}
> +
> +/**
> + * binder_cleanup_deferred_txn_lists() - free specified lists
> + * @sgc_head:  list_head of scatter-gather copy list
> + * @pf_head:   list_head of pointer fixup list
> + *
> + * Called to clean up @sgc_head and @pf_head if there is an
> + * error.
> + */
> +static void binder_cleanup_deferred_txn_lists(struct list_head *sgc_head,
> +                                             struct list_head *pf_head)
> +{
> +       struct list_head *entry, *tmp;
> +
> +       list_for_each_safe(entry, tmp, sgc_head) {
> +               struct binder_sg_copy *sgc =
> +                       container_of(entry, struct binder_sg_copy, node);
> +               list_del(&sgc->node);
> +               kfree(sgc);
> +       }
> +       list_for_each_safe(entry, tmp, pf_head) {
> +               struct binder_ptr_fixup *pf =
> +                       container_of(entry, struct binder_ptr_fixup, node);
> +               list_del(&pf->node);
> +               kfree(pf);
> +       }
> +}
> +
> +/**
> + * binder_defer_copy() - queue a scatter-gather buffer for copy
> + * @sgc_head:  list_head of scatter-gather copy list
> + * @offset:    binder buffer offset in target process
> + * @uaddr:     user address in source process
> + * @length:    bytes to copy
> + *
> + * Specify a scatter-gather block to be copied. The actual copy must
> + * be deferred until all the needed fixups are identified and queued.
> + * Then the copy and fixups are done together so un-translated values
> + * from the source are never visible in the target buffer.
> + *
> + * We are guaranteed that repeated calls to this function will have
> + * monotonically increasing @offset values so the list will naturally
> + * be ordered.
> + *
> + * Return: 0=success, else -errno
> + */
> +static int binder_defer_copy(struct list_head *sgc_head, binder_size_t offset,
> +                            const void __user *uaddr, size_t length)
> +{
> +       struct binder_sg_copy *bc = kzalloc(sizeof(*bc), GFP_KERNEL);
> +
> +       if (!bc)
> +               return -ENOMEM;
> +
> +       bc->offset = offset;
> +       bc->uaddr = uaddr;
> +       bc->length = length;
> +       INIT_LIST_HEAD(&bc->node);
> +
> +       /*
> +        * We are guaranteed that the deferred copies are in-order
> +        * so just add to the tail.
> +        */
> +       list_add_tail(&bc->node, sgc_head);
> +
> +       return 0;
> +}
> +
> +/**
> + * binder_add_fixup() - queue a fixup to be applied to sg copy
> + * @pf_head:   list_head of binder ptr fixup list
> + * @offset:    binder buffer offset in target process
> + * @fixup:     bytes to be copied for fixup
> + * @skip_size: bytes to skip when copying (fixup will be applied later)
> + *
> + * Add the specified fixup to a list ordered by @offset. When copying
> + * the scatter-gather buffers, the fixup will be copied instead of
> + * data from the source buffer. For BINDER_TYPE_FDA fixups, the fixup
> + * will be applied later (in target process context), so we just skip
> + * the bytes specified by @skip_size. If @skip_size is 0, we copy the
> + * value in @fixup.
> + *
> + * This function is called *mostly* in @offset order, but there are
> + * exceptions. Since out-of-order inserts are relatively uncommon,
> + * we insert the new element by searching backward from the tail of
> + * the list.
> + *
> + * Return: 0=success, else -errno
> + */
> +static int binder_add_fixup(struct list_head *pf_head, binder_size_t offset,
> +                           binder_uintptr_t fixup, size_t skip_size)
> +{
> +       struct binder_ptr_fixup *pf = kzalloc(sizeof(*pf), GFP_KERNEL);
> +       struct list_head *tmp;
> +
> +       if (!pf)
> +               return -ENOMEM;
> +
> +       pf->offset = offset;
> +       pf->fixup_data = fixup;
> +       pf->skip_size = skip_size;
> +       INIT_LIST_HEAD(&pf->node);
> +
> +       /* Fixups are *mostly* added in-order, but there are some
> +        * exceptions. Look backwards through list for insertion point.
> +        */
> +       if (!list_empty(pf_head)) {
> +               list_for_each_prev(tmp, pf_head) {
> +                       struct binder_ptr_fixup *tmppf =
> +                               list_entry(tmp, struct binder_ptr_fixup, node);
> +
> +                       if (tmppf->offset < pf->offset) {
> +                               list_add(&pf->node, tmp);
> +                               return 0;
> +                       }
> +               }
> +               /*
> +                * if we get here, then the new offset is the lowest so
> +                * insert at the head
> +                */
> +               list_add(&pf->node, pf_head);
> +               return 0;
> +       }
> +       list_add_tail(&pf->node, pf_head);
> +       return 0;
> +}
> +
> +static int binder_translate_fd_array(struct list_head *pf_head,
> +                                    struct binder_fd_array_object *fda,
>                                      const void __user *u,
>                                      struct binder_buffer_object *parent,
>                                      struct binder_buffer_object *uparent,
> @@ -2245,6 +2496,7 @@ static int binder_translate_fd_array(struct binder_fd_array_object *fda,
>         binder_size_t fda_offset;
>         const void __user *ufda_base;
>         struct binder_proc *proc = thread->proc;
> +       int ret;
>
>         fd_buf_size = sizeof(u32) * fda->num_fds;
>         if (fda->num_fds >= SIZE_MAX / sizeof(u32)) {
> @@ -2276,9 +2528,12 @@ static int binder_translate_fd_array(struct binder_fd_array_object *fda,
>                                   proc->pid, thread->pid);
>                 return -EINVAL;
>         }
> +       ret = binder_add_fixup(pf_head, fda_offset, 0, fda->num_fds * sizeof(u32));
> +       if (ret)
> +               return ret;
> +
>         for (fdi = 0; fdi < fda->num_fds; fdi++) {
>                 u32 fd;
> -               int ret;
>                 binder_size_t offset = fda_offset + fdi * sizeof(fd);
>                 binder_size_t uoffset = fdi * sizeof(fd);
>
> @@ -2292,7 +2547,8 @@ static int binder_translate_fd_array(struct binder_fd_array_object *fda,
>         return 0;
>  }
>
> -static int binder_fixup_parent(struct binder_transaction *t,
> +static int binder_fixup_parent(struct list_head *pf_head,
> +                              struct binder_transaction *t,
>                                struct binder_thread *thread,
>                                struct binder_buffer_object *bp,
>                                binder_size_t off_start_offset,
> @@ -2338,14 +2594,7 @@ static int binder_fixup_parent(struct binder_transaction *t,
>         }
>         buffer_offset = bp->parent_offset +
>                         (uintptr_t)parent->buffer - (uintptr_t)b->user_data;
> -       if (binder_alloc_copy_to_buffer(&target_proc->alloc, b, buffer_offset,
> -                                       &bp->buffer, sizeof(bp->buffer))) {
> -               binder_user_error("%d:%d got transaction with invalid parent offset\n",
> -                                 proc->pid, thread->pid);
> -               return -EINVAL;
> -       }
> -
> -       return 0;
> +       return binder_add_fixup(pf_head, buffer_offset, bp->buffer, 0);
>  }
>
>  /**
> @@ -2487,8 +2736,12 @@ static void binder_transaction(struct binder_proc *proc,
>         int t_debug_id = atomic_inc_return(&binder_last_id);
>         char *secctx = NULL;
>         u32 secctx_sz = 0;
> +       struct list_head sgc_head;
> +       struct list_head pf_head;
>         const void __user *user_buffer = (const void __user *)
>                                 (uintptr_t)tr->data.ptr.buffer;
> +       INIT_LIST_HEAD(&sgc_head);
> +       INIT_LIST_HEAD(&pf_head);
>
>         e = binder_transaction_log_add(&binder_transaction_log);
>         e->debug_id = t_debug_id;
> @@ -3006,8 +3259,8 @@ static void binder_transaction(struct binder_proc *proc,
>                                 return_error_line = __LINE__;
>                                 goto err_bad_parent;
>                         }
> -                       ret = binder_translate_fd_array(fda, user_buffer,
> -                                                       parent,
> +                       ret = binder_translate_fd_array(&pf_head, fda,
> +                                                       user_buffer, parent,
>                                                         &user_object.bbo, t,
>                                                         thread, in_reply_to);
>                         if (ret < 0 ||
> @@ -3038,19 +3291,14 @@ static void binder_transaction(struct binder_proc *proc,
>                                 return_error_line = __LINE__;
>                                 goto err_bad_offset;
>                         }
> -                       if (binder_alloc_copy_user_to_buffer(
> -                                               &target_proc->alloc,
> -                                               t->buffer,
> -                                               sg_buf_offset,
> -                                               (const void __user *)
> -                                                       (uintptr_t)bp->buffer,
> -                                               bp->length)) {
> -                               binder_user_error("%d:%d got transaction with invalid offsets ptr\n",
> -                                                 proc->pid, thread->pid);
> -                               return_error_param = -EFAULT;
> +                       ret = binder_defer_copy(&sgc_head, sg_buf_offset,
> +                               (const void __user *)(uintptr_t)bp->buffer,
> +                               bp->length);
> +                       if (ret) {
>                                 return_error = BR_FAILED_REPLY;
> +                               return_error_param = ret;
>                                 return_error_line = __LINE__;
> -                               goto err_copy_data_failed;
> +                               goto err_translate_failed;
>                         }
>                         /* Fixup buffer pointer to target proc address space */
>                         bp->buffer = (uintptr_t)
> @@ -3059,7 +3307,8 @@ static void binder_transaction(struct binder_proc *proc,
>
>                         num_valid = (buffer_offset - off_start_offset) /
>                                         sizeof(binder_size_t);
> -                       ret = binder_fixup_parent(t, thread, bp,
> +                       ret = binder_fixup_parent(&pf_head, t,
> +                                                 thread, bp,
>                                                   off_start_offset,
>                                                   num_valid,
>                                                   last_fixup_obj_off,
> @@ -3099,6 +3348,17 @@ static void binder_transaction(struct binder_proc *proc,
>                 return_error_line = __LINE__;
>                 goto err_copy_data_failed;
>         }
> +
> +       ret = binder_do_deferred_txn_copies(&target_proc->alloc, t->buffer,
> +                                           &sgc_head, &pf_head);
> +       if (ret) {
> +               binder_user_error("%d:%d got transaction with invalid offsets ptr\n",
> +                                 proc->pid, thread->pid);
> +               return_error = BR_FAILED_REPLY;
> +               return_error_param = ret;
> +               return_error_line = __LINE__;
> +               goto err_copy_data_failed;
> +       }
>         if (t->buffer->oneway_spam_suspect)
>                 tcomplete->type = BINDER_WORK_TRANSACTION_ONEWAY_SPAM_SUSPECT;
>         else
> @@ -3172,6 +3432,7 @@ static void binder_transaction(struct binder_proc *proc,
>  err_bad_offset:
>  err_bad_parent:
>  err_copy_data_failed:
> +       binder_cleanup_deferred_txn_lists(&sgc_head, &pf_head);
>         binder_free_txn_fixups(t);
>         trace_binder_transaction_failed_buffer_release(t->buffer);
>         binder_transaction_buffer_release(target_proc, NULL, t->buffer,
> --
> 2.34.0.rc2.393.gf8c9666880-goog
>
>

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 0/3] binder: Prevent untranslated sender data from being copied to target
  2021-11-23 19:17 [PATCH 0/3] binder: Prevent untranslated sender data from being copied to target Todd Kjos
                   ` (2 preceding siblings ...)
  2021-11-23 19:17 ` [PATCH 3/3] binder: defer copies of pre-patched txn data Todd Kjos
@ 2021-11-24  8:08 ` Greg KH
  2021-11-24 15:54   ` Todd Kjos
  3 siblings, 1 reply; 20+ messages in thread
From: Greg KH @ 2021-11-24  8:08 UTC (permalink / raw)
  To: Todd Kjos; +Cc: christian, arve, devel, linux-kernel, maco, joel, kernel-team

On Tue, Nov 23, 2021 at 11:17:34AM -0800, Todd Kjos wrote:
> Binder copies transactions directly from the sender buffer
> to the target buffer and then fixes up BINDER_TYPE_PTR and
> BINDER_TYPE_FDA objects. This means there is a brief time
> when sender pointers and fds are visible to the target
> process.
> 
> This series reworks the the sender to target copy to
> avoid leaking any untranslated sender data from being
> visible in the target.
> 
> Todd Kjos (3):
>   binder: defer copies of pre-patched txn data
>   binder: read pre-translated fds from sender buffer
>   binder: avoid potential data leakage when copying txn
> 
>  drivers/android/binder.c | 442 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------------
>  1 file changed, 387 insertions(+), 55 deletions(-)

Are these changes needed now in 5.16-final and also in stable kernels?

Or can they wait until 5.17-rc1?

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 3/3] binder: defer copies of pre-patched txn data
  2021-11-23 19:17 ` [PATCH 3/3] binder: defer copies of pre-patched txn data Todd Kjos
  2021-11-24  7:50   ` Martijn Coenen
@ 2021-11-24 11:09   ` Dan Carpenter
  2021-11-24 20:39     ` Todd Kjos
  2021-11-24 12:43   ` Dan Carpenter
  2 siblings, 1 reply; 20+ messages in thread
From: Dan Carpenter @ 2021-11-24 11:09 UTC (permalink / raw)
  To: Todd Kjos
  Cc: gregkh, christian, arve, devel, linux-kernel, maco, joel, kernel-team

On Tue, Nov 23, 2021 at 11:17:37AM -0800, Todd Kjos wrote:
> +/**
> + * binder_do_deferred_txn_copies() - copy and fixup scatter-gather data
> + * @alloc:	binder_alloc associated with @buffer
> + * @buffer:	binder buffer in target process
> + * @sgc_head:	list_head of scatter-gather copy list
> + * @pf_head:	list_head of pointer fixup list
> + *
> + * Processes all elements of @sgc_head, applying fixups from @pf_head
> + * and copying the scatter-gather data from the source process' user
> + * buffer to the target's buffer. It is expected that the list creation
> + * and processing all occurs during binder_transaction() so these lists
> + * are only accessed in local context.
> + *
> + * Return: 0=success, else -errno
      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
This function is supposed to return negatives on error.

> + */
> +static int binder_do_deferred_txn_copies(struct binder_alloc *alloc,
> +					 struct binder_buffer *buffer,
> +					 struct list_head *sgc_head,
> +					 struct list_head *pf_head)
> +{
> +	int ret = 0;
> +	struct list_head *entry, *tmp;
> +	struct binder_ptr_fixup *pf =
> +		list_first_entry_or_null(pf_head, struct binder_ptr_fixup,
> +					 node);
> +
> +	list_for_each_safe(entry, tmp, sgc_head) {
> +		size_t bytes_copied = 0;
> +		struct binder_sg_copy *sgc =
> +			container_of(entry, struct binder_sg_copy, node);
> +
> +		while (bytes_copied < sgc->length) {
> +			size_t copy_size;
> +			size_t bytes_left = sgc->length - bytes_copied;
> +			size_t offset = sgc->offset + bytes_copied;
> +
> +			/*
> +			 * We copy up to the fixup (pointed to by pf)
> +			 */
> +			copy_size = pf ? min(bytes_left, (size_t)pf->offset - offset)
> +				       : bytes_left;
> +			if (!ret && copy_size)
> +				ret = binder_alloc_copy_user_to_buffer(
                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
"ret" is the number of bytes remaining to be copied.


> +						alloc, buffer,
> +						offset,
> +						sgc->uaddr + bytes_copied,
> +						copy_size);
> +			bytes_copied += copy_size;
> +			if (copy_size != bytes_left) {
> +				BUG_ON(!pf);
> +				/* we stopped at a fixup offset */
> +				if (pf->skip_size) {
> +					/*
> +					 * we are just skipping. This is for
> +					 * BINDER_TYPE_FDA where the translated
> +					 * fds will be fixed up when we get
> +					 * to target context.
> +					 */
> +					bytes_copied += pf->skip_size;
> +				} else {
> +					/* apply the fixup indicated by pf */
> +					if (!ret)
> +						ret = binder_alloc_copy_to_buffer(
> +							alloc, buffer,
> +							pf->offset,
> +							&pf->fixup_data,
> +							sizeof(pf->fixup_data));
> +					bytes_copied += sizeof(pf->fixup_data);
> +				}
> +				list_del(&pf->node);
> +				kfree(pf);
> +				pf = list_first_entry_or_null(pf_head,
> +						struct binder_ptr_fixup, node);
> +			}
> +		}
> +		list_del(&sgc->node);
> +		kfree(sgc);
> +	}
> +	BUG_ON(!list_empty(pf_head));
> +	BUG_ON(!list_empty(sgc_head));
> +
> +	return ret;
> +}
> +
> +/**
> + * binder_cleanup_deferred_txn_lists() - free specified lists
> + * @sgc_head:	list_head of scatter-gather copy list
> + * @pf_head:	list_head of pointer fixup list
> + *
> + * Called to clean up @sgc_head and @pf_head if there is an
> + * error.
> + */
> +static void binder_cleanup_deferred_txn_lists(struct list_head *sgc_head,
> +					      struct list_head *pf_head)
> +{
> +	struct list_head *entry, *tmp;
> +
> +	list_for_each_safe(entry, tmp, sgc_head) {
> +		struct binder_sg_copy *sgc =
> +			container_of(entry, struct binder_sg_copy, node);
> +		list_del(&sgc->node);
> +		kfree(sgc);
> +	}
> +	list_for_each_safe(entry, tmp, pf_head) {
> +		struct binder_ptr_fixup *pf =
> +			container_of(entry, struct binder_ptr_fixup, node);
> +		list_del(&pf->node);
> +		kfree(pf);
> +	}
> +}
> +
> +/**
> + * binder_defer_copy() - queue a scatter-gather buffer for copy
> + * @sgc_head:	list_head of scatter-gather copy list
> + * @offset:	binder buffer offset in target process
> + * @uaddr:	user address in source process
> + * @length:	bytes to copy
> + *
> + * Specify a scatter-gather block to be copied. The actual copy must
> + * be deferred until all the needed fixups are identified and queued.
> + * Then the copy and fixups are done together so un-translated values
> + * from the source are never visible in the target buffer.
> + *
> + * We are guaranteed that repeated calls to this function will have
> + * monotonically increasing @offset values so the list will naturally
> + * be ordered.
> + *
> + * Return: 0=success, else -errno
> + */
> +static int binder_defer_copy(struct list_head *sgc_head, binder_size_t offset,
> +			     const void __user *uaddr, size_t length)
> +{
> +	struct binder_sg_copy *bc = kzalloc(sizeof(*bc), GFP_KERNEL);
> +
> +	if (!bc)
> +		return -ENOMEM;
> +
> +	bc->offset = offset;
> +	bc->uaddr = uaddr;
> +	bc->length = length;
> +	INIT_LIST_HEAD(&bc->node);
> +
> +	/*
> +	 * We are guaranteed that the deferred copies are in-order
> +	 * so just add to the tail.
> +	 */
> +	list_add_tail(&bc->node, sgc_head);
> +
> +	return 0;
> +}
> +
> +/**
> + * binder_add_fixup() - queue a fixup to be applied to sg copy
> + * @pf_head:	list_head of binder ptr fixup list
> + * @offset:	binder buffer offset in target process
> + * @fixup:	bytes to be copied for fixup
> + * @skip_size:	bytes to skip when copying (fixup will be applied later)
> + *
> + * Add the specified fixup to a list ordered by @offset. When copying
> + * the scatter-gather buffers, the fixup will be copied instead of
> + * data from the source buffer. For BINDER_TYPE_FDA fixups, the fixup
> + * will be applied later (in target process context), so we just skip
> + * the bytes specified by @skip_size. If @skip_size is 0, we copy the
> + * value in @fixup.
> + *
> + * This function is called *mostly* in @offset order, but there are
> + * exceptions. Since out-of-order inserts are relatively uncommon,
> + * we insert the new element by searching backward from the tail of
> + * the list.
> + *
> + * Return: 0=success, else -errno
> + */
> +static int binder_add_fixup(struct list_head *pf_head, binder_size_t offset,
> +			    binder_uintptr_t fixup, size_t skip_size)
> +{
> +	struct binder_ptr_fixup *pf = kzalloc(sizeof(*pf), GFP_KERNEL);
> +	struct list_head *tmp;
> +
> +	if (!pf)
> +		return -ENOMEM;
> +
> +	pf->offset = offset;
> +	pf->fixup_data = fixup;
> +	pf->skip_size = skip_size;
> +	INIT_LIST_HEAD(&pf->node);
> +
> +	/* Fixups are *mostly* added in-order, but there are some
> +	 * exceptions. Look backwards through list for insertion point.
> +	 */
> +	if (!list_empty(pf_head)) {

This condition is not required.  If list is empty we add it to the tail,
but when there is only one item on the list, the first and last item are
going to be the same.

> +		list_for_each_prev(tmp, pf_head) {
> +			struct binder_ptr_fixup *tmppf =
> +				list_entry(tmp, struct binder_ptr_fixup, node);
> +
> +			if (tmppf->offset < pf->offset) {
> +				list_add(&pf->node, tmp);
> +				return 0;
> +			}
> +		}
> +		/*
> +		 * if we get here, then the new offset is the lowest so
> +		 * insert at the head
> +		 */
> +		list_add(&pf->node, pf_head);
> +		return 0;
> +	}
> +	list_add_tail(&pf->node, pf_head);
> +	return 0;
> +}
> +

regards,
dan carpenter

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 2/3] binder: read pre-translated fds from sender buffer
  2021-11-23 19:17 ` [PATCH 2/3] binder: read pre-translated fds from sender buffer Todd Kjos
  2021-11-24  7:50   ` Martijn Coenen
@ 2021-11-24 12:37   ` Dan Carpenter
  2021-11-24 20:33     ` Todd Kjos
  1 sibling, 1 reply; 20+ messages in thread
From: Dan Carpenter @ 2021-11-24 12:37 UTC (permalink / raw)
  To: Todd Kjos
  Cc: gregkh, christian, arve, devel, linux-kernel, maco, joel, kernel-team

On Tue, Nov 23, 2021 at 11:17:36AM -0800, Todd Kjos wrote:
> Since we are no longer going to copy the pre-fixup
> data from the target buffer, we need to read
> pre-translated FD array information from the source
> buffer.
> 

The commit message is really misleading.  From the commit message it
sounds like the commit is changing runtime but it's not.  What I want is
a commit message like this:

  This patch is to prepare for an up coming patch where we read
  pre-translated fds from the sender buffer and translate them before
  copying them to the target.  It does not change run time.

  The patch adds two new parameters to binder_translate_fd_array() to
  hold the sender buffer and sender buffer parent.  These parameters let
  us call copy_from_user() directly instead of using
  binder_alloc_copy_from_buffer() which is a cleanup.  Also the patch
  adds some new alignment checks.  Previously the alignment checks would
  have been done in a different place, but this lets us print more
  useful error messages.


> Signed-off-by: Todd Kjos <tkjos@google.com>
> ---
>  drivers/android/binder.c | 40 +++++++++++++++++++++++++++++++++-------
>  1 file changed, 33 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/android/binder.c b/drivers/android/binder.c
> index 571d3c203557..2300fa8e09d5 100644
> --- a/drivers/android/binder.c
> +++ b/drivers/android/binder.c
> @@ -2234,15 +2234,17 @@ static int binder_translate_fd(u32 fd, binder_size_t fd_offset,
>  }
>  
>  static int binder_translate_fd_array(struct binder_fd_array_object *fda,
> +				     const void __user *u,

I wish we could use sender/target terminology everywhere.  Please change
every place that has "u" or "user" to either "sender" or "target" as
appropriate.

>  				     struct binder_buffer_object *parent,
> +				     struct binder_buffer_object *uparent,
                                                                  ^

>  				     struct binder_transaction *t,
>  				     struct binder_thread *thread,
>  				     struct binder_transaction *in_reply_to)
>  {
>  	binder_size_t fdi, fd_buf_size;
>  	binder_size_t fda_offset;
> +	const void __user *ufda_base;
                           ^

>  	struct binder_proc *proc = thread->proc;
> -	struct binder_proc *target_proc = t->to_proc;
>  
>  	fd_buf_size = sizeof(u32) * fda->num_fds;
>  	if (fda->num_fds >= SIZE_MAX / sizeof(u32)) {
> @@ -2266,7 +2268,10 @@ static int binder_translate_fd_array(struct binder_fd_array_object *fda,
>  	 */>  	fda_offset = (parent->buffer - (uintptr_t)t->buffer->user_data) +
>  		fda->parent_offset;
> -	if (!IS_ALIGNED((unsigned long)fda_offset, sizeof(u32))) {
> +	ufda_base = (void __user *)uparent->buffer + fda->parent_offset;
> +
> +	if (!IS_ALIGNED((unsigned long)fda_offset, sizeof(u32)) ||
> +	    !IS_ALIGNED((unsigned long)ufda_base, sizeof(u32))) {
>  		binder_user_error("%d:%d parent offset not aligned correctly.\n",
>  				  proc->pid, thread->pid);
>  		return -EINVAL;
> @@ -2275,10 +2280,9 @@ static int binder_translate_fd_array(struct binder_fd_array_object *fda,
>  		u32 fd;
>  		int ret;
>  		binder_size_t offset = fda_offset + fdi * sizeof(fd);
> +		binder_size_t uoffset = fdi * sizeof(fd);
>  
> -		ret = binder_alloc_copy_from_buffer(&target_proc->alloc,
> -						    &fd, t->buffer,
> -						    offset, sizeof(fd));
> +		ret = copy_from_user(&fd, ufda_base + uoffset, sizeof(fd));
>  		if (!ret)
>  			ret = binder_translate_fd(fd, offset, t, thread,
>  						  in_reply_to);

This is something from the original code but if the copy_from_user()
fails, then we just skip that "fd" without informing the user.  It feels
wrong.  Does that not lead to a bug in the target app?


> @@ -2951,6 +2955,8 @@ static void binder_transaction(struct binder_proc *proc,
>  		case BINDER_TYPE_FDA: {
>  			struct binder_object ptr_object;
>  			binder_size_t parent_offset;
> +			struct binder_object user_object;
> +			size_t user_parent_size;
>  			struct binder_fd_array_object *fda =
>  				to_binder_fd_array_object(hdr);
>  			size_t num_valid = (buffer_offset - off_start_offset) /
> @@ -2982,8 +2988,28 @@ static void binder_transaction(struct binder_proc *proc,
>  				return_error_line = __LINE__;
>  				goto err_bad_parent;
>  			}
> -			ret = binder_translate_fd_array(fda, parent, t, thread,
> -							in_reply_to);
> +
> +			/*
> +			 * We need to read the user version of the parent
> +			 * object to get the original user offset
> +			 */
> +			user_parent_size =
> +				binder_get_object(proc, user_buffer, t->buffer,
> +						  parent_offset, &user_object);
> +			if (user_parent_size != sizeof(user_object.bbo)) {
> +				binder_user_error("%d:%d invalid ptr object size: %lld vs %lld\n",

Apparently %lld breaks the build on my .config.  The correct format for
size_t is %zd.

> +						  proc->pid, thread->pid,
> +						  user_parent_size,
> +						  sizeof(user_object.bbo));
> +				return_error = BR_FAILED_REPLY;
> +				return_error_param = -EINVAL;
> +				return_error_line = __LINE__;
> +				goto err_bad_parent;
> +			}
> +			ret = binder_translate_fd_array(fda, user_buffer,
> +							parent,
> +							&user_object.bbo, t,
> +							thread, in_reply_to);

regards,
dan carpenter


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 3/3] binder: defer copies of pre-patched txn data
  2021-11-23 19:17 ` [PATCH 3/3] binder: defer copies of pre-patched txn data Todd Kjos
  2021-11-24  7:50   ` Martijn Coenen
  2021-11-24 11:09   ` Dan Carpenter
@ 2021-11-24 12:43   ` Dan Carpenter
  2021-11-24 20:37     ` Todd Kjos
  2 siblings, 1 reply; 20+ messages in thread
From: Dan Carpenter @ 2021-11-24 12:43 UTC (permalink / raw)
  To: Todd Kjos
  Cc: gregkh, christian, arve, devel, linux-kernel, maco, joel, kernel-team

On Tue, Nov 23, 2021 at 11:17:37AM -0800, Todd Kjos wrote:
> +static int binder_do_deferred_txn_copies(struct binder_alloc *alloc,
> +					 struct binder_buffer *buffer,
> +					 struct list_head *sgc_head,
> +					 struct list_head *pf_head)
> +{
> +	int ret = 0;
> +	struct list_head *entry, *tmp;
> +	struct binder_ptr_fixup *pf =
> +		list_first_entry_or_null(pf_head, struct binder_ptr_fixup,
> +					 node);
> +
> +	list_for_each_safe(entry, tmp, sgc_head) {
        ^^^^^^^^^^^^^^^^^^^
All the list_for_each() loops can be changed to list_for_each_entry().


	list_for_each_entry_safe(sgc, tmp, sgc_head, node) {

regards,
dan carpenter



> +		size_t bytes_copied = 0;
> +		struct binder_sg_copy *sgc =
> +			container_of(entry, struct binder_sg_copy, node);
> +


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 1/3] binder: avoid potential data leakage when copying txn
  2021-11-23 19:17 ` [PATCH 1/3] binder: avoid potential data leakage when copying txn Todd Kjos
  2021-11-24  7:50   ` Martijn Coenen
@ 2021-11-24 13:01   ` Dan Carpenter
  2021-11-24 20:11     ` Todd Kjos
  2021-11-25  2:05   ` kernel test robot
  2021-11-25 12:18   ` kernel test robot
  3 siblings, 1 reply; 20+ messages in thread
From: Dan Carpenter @ 2021-11-24 13:01 UTC (permalink / raw)
  To: Todd Kjos
  Cc: gregkh, christian, arve, devel, linux-kernel, maco, joel, kernel-team

On Tue, Nov 23, 2021 at 11:17:35AM -0800, Todd Kjos wrote:
> Transactions are copied from the sender to the target
> first and objects like BINDER_TYPE_PTR and BINDER_TYPE_FDA
> are then fixed up. This means there is a short period where
> the sender's version of these objects are visible to the
> target prior to the fixups.
> 
> Instead of copying all of the data first, copy data only
> after any needed fixups have been applied.
> 

This patch needs a fixes tag.

So this patch basically fixes the simple part of the info leak and
patch 3 fixes the complicated part.  Have I understood that correctly?

> @@ -2956,7 +2984,11 @@ static void binder_transaction(struct binder_proc *proc,
>  			}
>  			ret = binder_translate_fd_array(fda, parent, t, thread,
>  							in_reply_to);
> -			if (ret < 0) {
> +			if (ret < 0 ||
> +			    binder_alloc_copy_to_buffer(&target_proc->alloc,
> +							t->buffer,
> +							object_offset,
> +							fda, sizeof(*fda))) {
>  				return_error = BR_FAILED_REPLY;
>  				return_error_param = ret;

"ret" is not a negative error code if binder_translate_fd_array()
succeeds but binder_alloc_copy_to_buffer() fails.


>  				return_error_line = __LINE__;
> @@ -3028,6 +3060,19 @@ static void binder_transaction(struct binder_proc *proc,
>  			goto err_bad_object_type;
>  		}
>  	}

regards,
dan carpenter

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 0/3] binder: Prevent untranslated sender data from being copied to target
  2021-11-24  8:08 ` [PATCH 0/3] binder: Prevent untranslated sender data from being copied to target Greg KH
@ 2021-11-24 15:54   ` Todd Kjos
  0 siblings, 0 replies; 20+ messages in thread
From: Todd Kjos @ 2021-11-24 15:54 UTC (permalink / raw)
  To: Greg KH; +Cc: christian, arve, devel, linux-kernel, maco, joel, kernel-team

On Wed, Nov 24, 2021 at 12:08 AM Greg KH <gregkh@linuxfoundation.org> wrote:
>
> On Tue, Nov 23, 2021 at 11:17:34AM -0800, Todd Kjos wrote:
> > Binder copies transactions directly from the sender buffer
> > to the target buffer and then fixes up BINDER_TYPE_PTR and
> > BINDER_TYPE_FDA objects. This means there is a brief time
> > when sender pointers and fds are visible to the target
> > process.
> >
> > This series reworks the the sender to target copy to
> > avoid leaking any untranslated sender data from being
> > visible in the target.
> >
> > Todd Kjos (3):
> >   binder: defer copies of pre-patched txn data
> >   binder: read pre-translated fds from sender buffer
> >   binder: avoid potential data leakage when copying txn
> >
> >  drivers/android/binder.c | 442 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------------
> >  1 file changed, 387 insertions(+), 55 deletions(-)
>
> Are these changes needed now in 5.16-final and also in stable kernels?
>
> Or can they wait until 5.17-rc1?

They can wait until 5.17-rc1.

>
> thanks,
>
> greg k-h

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 1/3] binder: avoid potential data leakage when copying txn
  2021-11-24 13:01   ` Dan Carpenter
@ 2021-11-24 20:11     ` Todd Kjos
  0 siblings, 0 replies; 20+ messages in thread
From: Todd Kjos @ 2021-11-24 20:11 UTC (permalink / raw)
  To: Dan Carpenter
  Cc: gregkh, christian, arve, devel, linux-kernel, maco, joel, kernel-team

On Wed, Nov 24, 2021 at 5:01 AM Dan Carpenter <dan.carpenter@oracle.com> wrote:
>
> On Tue, Nov 23, 2021 at 11:17:35AM -0800, Todd Kjos wrote:
> > Transactions are copied from the sender to the target
> > first and objects like BINDER_TYPE_PTR and BINDER_TYPE_FDA
> > are then fixed up. This means there is a short period where
> > the sender's version of these objects are visible to the
> > target prior to the fixups.
> >
> > Instead of copying all of the data first, copy data only
> > after any needed fixups have been applied.
> >
>
> This patch needs a fixes tag.

Sure, it goes back to the original submission, so I'll add:

Fixes: 457b9a6f09f0 ("Staging: android: add binder driver")

>
> So this patch basically fixes the simple part of the info leak and
> patch 3 fixes the complicated part.  Have I understood that correctly?

Yes.

>
> > @@ -2956,7 +2984,11 @@ static void binder_transaction(struct binder_proc *proc,
> >                       }
> >                       ret = binder_translate_fd_array(fda, parent, t, thread,
> >                                                       in_reply_to);
> > -                     if (ret < 0) {
> > +                     if (ret < 0 ||
> > +                         binder_alloc_copy_to_buffer(&target_proc->alloc,
> > +                                                     t->buffer,
> > +                                                     object_offset,
> > +                                                     fda, sizeof(*fda))) {
> >                               return_error = BR_FAILED_REPLY;
> >                               return_error_param = ret;
>
> "ret" is not a negative error code if binder_translate_fd_array()
> succeeds but binder_alloc_copy_to_buffer() fails.

You are right. return_error_param would be 0 in this case. Will
capture the return of binder_alloc_copy_to_buffer(). Thanks.

>
>
> >                               return_error_line = __LINE__;
> > @@ -3028,6 +3060,19 @@ static void binder_transaction(struct binder_proc *proc,
> >                       goto err_bad_object_type;
> >               }
> >       }
>
> regards,
> dan carpenter
>
> --
> To unsubscribe from this group and stop receiving emails from it, send an email to kernel-team+unsubscribe@android.com.
>

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 2/3] binder: read pre-translated fds from sender buffer
  2021-11-24 12:37   ` Dan Carpenter
@ 2021-11-24 20:33     ` Todd Kjos
  2021-11-25  6:37       ` Dan Carpenter
  0 siblings, 1 reply; 20+ messages in thread
From: Todd Kjos @ 2021-11-24 20:33 UTC (permalink / raw)
  To: Dan Carpenter
  Cc: gregkh, christian, arve, devel, linux-kernel, maco, joel, kernel-team

On Wed, Nov 24, 2021 at 4:37 AM Dan Carpenter <dan.carpenter@oracle.com> wrote:
>
> On Tue, Nov 23, 2021 at 11:17:36AM -0800, Todd Kjos wrote:
> > Since we are no longer going to copy the pre-fixup
> > data from the target buffer, we need to read
> > pre-translated FD array information from the source
> > buffer.
> >
>
> The commit message is really misleading.  From the commit message it
> sounds like the commit is changing runtime but it's not.  What I want is
> a commit message like this:
>
>   This patch is to prepare for an up coming patch where we read
>   pre-translated fds from the sender buffer and translate them before
>   copying them to the target.  It does not change run time.
>
>   The patch adds two new parameters to binder_translate_fd_array() to
>   hold the sender buffer and sender buffer parent.  These parameters let
>   us call copy_from_user() directly instead of using
>   binder_alloc_copy_from_buffer() which is a cleanup.  Also the patch
>   adds some new alignment checks.  Previously the alignment checks would
>   have been done in a different place, but this lets us print more
>   useful error messages.

Got it. Will fix in update.

>
>
> > Signed-off-by: Todd Kjos <tkjos@google.com>
> > ---
> >  drivers/android/binder.c | 40 +++++++++++++++++++++++++++++++++-------
> >  1 file changed, 33 insertions(+), 7 deletions(-)
> >
> > diff --git a/drivers/android/binder.c b/drivers/android/binder.c
> > index 571d3c203557..2300fa8e09d5 100644
> > --- a/drivers/android/binder.c
> > +++ b/drivers/android/binder.c
> > @@ -2234,15 +2234,17 @@ static int binder_translate_fd(u32 fd, binder_size_t fd_offset,
> >  }
> >
> >  static int binder_translate_fd_array(struct binder_fd_array_object *fda,
> > +                                  const void __user *u,
>
> I wish we could use sender/target terminology everywhere.  Please change
> every place that has "u" or "user" to either "sender" or "target" as
> appropriate.

Ok (all "u/user" cases are sender).

>
> >                                    struct binder_buffer_object *parent,
> > +                                  struct binder_buffer_object *uparent,
>                                                                   ^
>
> >                                    struct binder_transaction *t,
> >                                    struct binder_thread *thread,
> >                                    struct binder_transaction *in_reply_to)
> >  {
> >       binder_size_t fdi, fd_buf_size;
> >       binder_size_t fda_offset;
> > +     const void __user *ufda_base;
>                            ^
>
> >       struct binder_proc *proc = thread->proc;
> > -     struct binder_proc *target_proc = t->to_proc;
> >
> >       fd_buf_size = sizeof(u32) * fda->num_fds;
> >       if (fda->num_fds >= SIZE_MAX / sizeof(u32)) {
> > @@ -2266,7 +2268,10 @@ static int binder_translate_fd_array(struct binder_fd_array_object *fda,
> >        */>    fda_offset = (parent->buffer - (uintptr_t)t->buffer->user_data) +
> >               fda->parent_offset;
> > -     if (!IS_ALIGNED((unsigned long)fda_offset, sizeof(u32))) {
> > +     ufda_base = (void __user *)uparent->buffer + fda->parent_offset;
> > +
> > +     if (!IS_ALIGNED((unsigned long)fda_offset, sizeof(u32)) ||
> > +         !IS_ALIGNED((unsigned long)ufda_base, sizeof(u32))) {
> >               binder_user_error("%d:%d parent offset not aligned correctly.\n",
> >                                 proc->pid, thread->pid);
> >               return -EINVAL;
> > @@ -2275,10 +2280,9 @@ static int binder_translate_fd_array(struct binder_fd_array_object *fda,
> >               u32 fd;
> >               int ret;
> >               binder_size_t offset = fda_offset + fdi * sizeof(fd);
> > +             binder_size_t uoffset = fdi * sizeof(fd);
> >
> > -             ret = binder_alloc_copy_from_buffer(&target_proc->alloc,
> > -                                                 &fd, t->buffer,
> > -                                                 offset, sizeof(fd));
> > +             ret = copy_from_user(&fd, ufda_base + uoffset, sizeof(fd));
> >               if (!ret)
> >                       ret = binder_translate_fd(fd, offset, t, thread,
> >                                                 in_reply_to);
>
> This is something from the original code but if the copy_from_user()
> fails, then we just skip that "fd" without informing the user.

Here is the whole code fragment(the diff doesn't include the "if
(ret<0) return ret"):

  ret = copy_from_user(&fd, ufda_base + uoffset, sizeof(fd));
  if (!ret)
    ret = binder_translate_fd(fd, offset, t, thread, in_reply_to);
  if (ret < 0)
    return ret;

I agree -- if copy_from_user() for some reason doesn't copy the whole
buffer, it might return a positive integer. Then it would skip
binder_translate_fd(), but not return. That should probably be
something like:

  if (ret)
    return ret > 0 ? -EINVAL : ret;

Will fix in next version.

> It feels wrong.  Does that not lead to a bug in the target app?
>

If copy_from_user() returned a positive integer, we would translate
some random fd. Most likely it would be invalid, but it might not be.
Definitely would be a bug.

>
> > @@ -2951,6 +2955,8 @@ static void binder_transaction(struct binder_proc *proc,
> >               case BINDER_TYPE_FDA: {
> >                       struct binder_object ptr_object;
> >                       binder_size_t parent_offset;
> > +                     struct binder_object user_object;
> > +                     size_t user_parent_size;
> >                       struct binder_fd_array_object *fda =
> >                               to_binder_fd_array_object(hdr);
> >                       size_t num_valid = (buffer_offset - off_start_offset) /
> > @@ -2982,8 +2988,28 @@ static void binder_transaction(struct binder_proc *proc,
> >                               return_error_line = __LINE__;
> >                               goto err_bad_parent;
> >                       }
> > -                     ret = binder_translate_fd_array(fda, parent, t, thread,
> > -                                                     in_reply_to);
> > +
> > +                     /*
> > +                      * We need to read the user version of the parent
> > +                      * object to get the original user offset
> > +                      */
> > +                     user_parent_size =
> > +                             binder_get_object(proc, user_buffer, t->buffer,
> > +                                               parent_offset, &user_object);
> > +                     if (user_parent_size != sizeof(user_object.bbo)) {
> > +                             binder_user_error("%d:%d invalid ptr object size: %lld vs %lld\n",
>
> Apparently %lld breaks the build on my .config.  The correct format for
> size_t is %zd.
>
> > +                                               proc->pid, thread->pid,
> > +                                               user_parent_size,
> > +                                               sizeof(user_object.bbo));
> > +                             return_error = BR_FAILED_REPLY;
> > +                             return_error_param = -EINVAL;
> > +                             return_error_line = __LINE__;
> > +                             goto err_bad_parent;
> > +                     }
> > +                     ret = binder_translate_fd_array(fda, user_buffer,
> > +                                                     parent,
> > +                                                     &user_object.bbo, t,
> > +                                                     thread, in_reply_to);
>
> regards,
> dan carpenter
>
> --
> To unsubscribe from this group and stop receiving emails from it, send an email to kernel-team+unsubscribe@android.com.
>

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 3/3] binder: defer copies of pre-patched txn data
  2021-11-24 12:43   ` Dan Carpenter
@ 2021-11-24 20:37     ` Todd Kjos
  0 siblings, 0 replies; 20+ messages in thread
From: Todd Kjos @ 2021-11-24 20:37 UTC (permalink / raw)
  To: Dan Carpenter
  Cc: gregkh, christian, arve, devel, linux-kernel, maco, joel, kernel-team

On Wed, Nov 24, 2021 at 4:44 AM Dan Carpenter <dan.carpenter@oracle.com> wrote:
>
> On Tue, Nov 23, 2021 at 11:17:37AM -0800, Todd Kjos wrote:
> > +static int binder_do_deferred_txn_copies(struct binder_alloc *alloc,
> > +                                      struct binder_buffer *buffer,
> > +                                      struct list_head *sgc_head,
> > +                                      struct list_head *pf_head)
> > +{
> > +     int ret = 0;
> > +     struct list_head *entry, *tmp;
> > +     struct binder_ptr_fixup *pf =
> > +             list_first_entry_or_null(pf_head, struct binder_ptr_fixup,
> > +                                      node);
> > +
> > +     list_for_each_safe(entry, tmp, sgc_head) {
>         ^^^^^^^^^^^^^^^^^^^
> All the list_for_each() loops can be changed to list_for_each_entry().
>
>
>         list_for_each_entry_safe(sgc, tmp, sgc_head, node) {

Will change. Thanks for the suggestion.

>
> regards,
> dan carpenter
>
>
>
> > +             size_t bytes_copied = 0;
> > +             struct binder_sg_copy *sgc =
> > +                     container_of(entry, struct binder_sg_copy, node);
> > +
>
> --
> To unsubscribe from this group and stop receiving emails from it, send an email to kernel-team+unsubscribe@android.com.
>

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 3/3] binder: defer copies of pre-patched txn data
  2021-11-24 11:09   ` Dan Carpenter
@ 2021-11-24 20:39     ` Todd Kjos
  0 siblings, 0 replies; 20+ messages in thread
From: Todd Kjos @ 2021-11-24 20:39 UTC (permalink / raw)
  To: Dan Carpenter
  Cc: gregkh, christian, arve, devel, linux-kernel, maco, joel, kernel-team

On Wed, Nov 24, 2021 at 3:10 AM Dan Carpenter <dan.carpenter@oracle.com> wrote:
>
> On Tue, Nov 23, 2021 at 11:17:37AM -0800, Todd Kjos wrote:
> > +/**
> > + * binder_do_deferred_txn_copies() - copy and fixup scatter-gather data
> > + * @alloc:   binder_alloc associated with @buffer
> > + * @buffer:  binder buffer in target process
> > + * @sgc_head:        list_head of scatter-gather copy list
> > + * @pf_head: list_head of pointer fixup list
> > + *
> > + * Processes all elements of @sgc_head, applying fixups from @pf_head
> > + * and copying the scatter-gather data from the source process' user
> > + * buffer to the target's buffer. It is expected that the list creation
> > + * and processing all occurs during binder_transaction() so these lists
> > + * are only accessed in local context.
> > + *
> > + * Return: 0=success, else -errno
>       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> This function is supposed to return negatives on error.
>
> > + */
> > +static int binder_do_deferred_txn_copies(struct binder_alloc *alloc,
> > +                                      struct binder_buffer *buffer,
> > +                                      struct list_head *sgc_head,
> > +                                      struct list_head *pf_head)
> > +{
> > +     int ret = 0;
> > +     struct list_head *entry, *tmp;
> > +     struct binder_ptr_fixup *pf =
> > +             list_first_entry_or_null(pf_head, struct binder_ptr_fixup,
> > +                                      node);
> > +
> > +     list_for_each_safe(entry, tmp, sgc_head) {
> > +             size_t bytes_copied = 0;
> > +             struct binder_sg_copy *sgc =
> > +                     container_of(entry, struct binder_sg_copy, node);
> > +
> > +             while (bytes_copied < sgc->length) {
> > +                     size_t copy_size;
> > +                     size_t bytes_left = sgc->length - bytes_copied;
> > +                     size_t offset = sgc->offset + bytes_copied;
> > +
> > +                     /*
> > +                      * We copy up to the fixup (pointed to by pf)
> > +                      */
> > +                     copy_size = pf ? min(bytes_left, (size_t)pf->offset - offset)
> > +                                    : bytes_left;
> > +                     if (!ret && copy_size)
> > +                             ret = binder_alloc_copy_user_to_buffer(
>                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> "ret" is the number of bytes remaining to be copied.

Good catch. Thanks. Will fix.

>
>
> > +                                             alloc, buffer,
> > +                                             offset,
> > +                                             sgc->uaddr + bytes_copied,
> > +                                             copy_size);
> > +                     bytes_copied += copy_size;
> > +                     if (copy_size != bytes_left) {
> > +                             BUG_ON(!pf);
> > +                             /* we stopped at a fixup offset */
> > +                             if (pf->skip_size) {
> > +                                     /*
> > +                                      * we are just skipping. This is for
> > +                                      * BINDER_TYPE_FDA where the translated
> > +                                      * fds will be fixed up when we get
> > +                                      * to target context.
> > +                                      */
> > +                                     bytes_copied += pf->skip_size;
> > +                             } else {
> > +                                     /* apply the fixup indicated by pf */
> > +                                     if (!ret)
> > +                                             ret = binder_alloc_copy_to_buffer(
> > +                                                     alloc, buffer,
> > +                                                     pf->offset,
> > +                                                     &pf->fixup_data,
> > +                                                     sizeof(pf->fixup_data));
> > +                                     bytes_copied += sizeof(pf->fixup_data);
> > +                             }
> > +                             list_del(&pf->node);
> > +                             kfree(pf);
> > +                             pf = list_first_entry_or_null(pf_head,
> > +                                             struct binder_ptr_fixup, node);
> > +                     }
> > +             }
> > +             list_del(&sgc->node);
> > +             kfree(sgc);
> > +     }
> > +     BUG_ON(!list_empty(pf_head));
> > +     BUG_ON(!list_empty(sgc_head));
> > +
> > +     return ret;
> > +}
> > +
> > +/**
> > + * binder_cleanup_deferred_txn_lists() - free specified lists
> > + * @sgc_head:        list_head of scatter-gather copy list
> > + * @pf_head: list_head of pointer fixup list
> > + *
> > + * Called to clean up @sgc_head and @pf_head if there is an
> > + * error.
> > + */
> > +static void binder_cleanup_deferred_txn_lists(struct list_head *sgc_head,
> > +                                           struct list_head *pf_head)
> > +{
> > +     struct list_head *entry, *tmp;
> > +
> > +     list_for_each_safe(entry, tmp, sgc_head) {
> > +             struct binder_sg_copy *sgc =
> > +                     container_of(entry, struct binder_sg_copy, node);
> > +             list_del(&sgc->node);
> > +             kfree(sgc);
> > +     }
> > +     list_for_each_safe(entry, tmp, pf_head) {
> > +             struct binder_ptr_fixup *pf =
> > +                     container_of(entry, struct binder_ptr_fixup, node);
> > +             list_del(&pf->node);
> > +             kfree(pf);
> > +     }
> > +}
> > +
> > +/**
> > + * binder_defer_copy() - queue a scatter-gather buffer for copy
> > + * @sgc_head:        list_head of scatter-gather copy list
> > + * @offset:  binder buffer offset in target process
> > + * @uaddr:   user address in source process
> > + * @length:  bytes to copy
> > + *
> > + * Specify a scatter-gather block to be copied. The actual copy must
> > + * be deferred until all the needed fixups are identified and queued.
> > + * Then the copy and fixups are done together so un-translated values
> > + * from the source are never visible in the target buffer.
> > + *
> > + * We are guaranteed that repeated calls to this function will have
> > + * monotonically increasing @offset values so the list will naturally
> > + * be ordered.
> > + *
> > + * Return: 0=success, else -errno
> > + */
> > +static int binder_defer_copy(struct list_head *sgc_head, binder_size_t offset,
> > +                          const void __user *uaddr, size_t length)
> > +{
> > +     struct binder_sg_copy *bc = kzalloc(sizeof(*bc), GFP_KERNEL);
> > +
> > +     if (!bc)
> > +             return -ENOMEM;
> > +
> > +     bc->offset = offset;
> > +     bc->uaddr = uaddr;
> > +     bc->length = length;
> > +     INIT_LIST_HEAD(&bc->node);
> > +
> > +     /*
> > +      * We are guaranteed that the deferred copies are in-order
> > +      * so just add to the tail.
> > +      */
> > +     list_add_tail(&bc->node, sgc_head);
> > +
> > +     return 0;
> > +}
> > +
> > +/**
> > + * binder_add_fixup() - queue a fixup to be applied to sg copy
> > + * @pf_head: list_head of binder ptr fixup list
> > + * @offset:  binder buffer offset in target process
> > + * @fixup:   bytes to be copied for fixup
> > + * @skip_size:       bytes to skip when copying (fixup will be applied later)
> > + *
> > + * Add the specified fixup to a list ordered by @offset. When copying
> > + * the scatter-gather buffers, the fixup will be copied instead of
> > + * data from the source buffer. For BINDER_TYPE_FDA fixups, the fixup
> > + * will be applied later (in target process context), so we just skip
> > + * the bytes specified by @skip_size. If @skip_size is 0, we copy the
> > + * value in @fixup.
> > + *
> > + * This function is called *mostly* in @offset order, but there are
> > + * exceptions. Since out-of-order inserts are relatively uncommon,
> > + * we insert the new element by searching backward from the tail of
> > + * the list.
> > + *
> > + * Return: 0=success, else -errno
> > + */
> > +static int binder_add_fixup(struct list_head *pf_head, binder_size_t offset,
> > +                         binder_uintptr_t fixup, size_t skip_size)
> > +{
> > +     struct binder_ptr_fixup *pf = kzalloc(sizeof(*pf), GFP_KERNEL);
> > +     struct list_head *tmp;
> > +
> > +     if (!pf)
> > +             return -ENOMEM;
> > +
> > +     pf->offset = offset;
> > +     pf->fixup_data = fixup;
> > +     pf->skip_size = skip_size;
> > +     INIT_LIST_HEAD(&pf->node);
> > +
> > +     /* Fixups are *mostly* added in-order, but there are some
> > +      * exceptions. Look backwards through list for insertion point.
> > +      */
> > +     if (!list_empty(pf_head)) {
>
> This condition is not required.  If list is empty we add it to the tail,
> but when there is only one item on the list, the first and last item are
> going to be the same.

Good point.

>
> > +             list_for_each_prev(tmp, pf_head) {
> > +                     struct binder_ptr_fixup *tmppf =
> > +                             list_entry(tmp, struct binder_ptr_fixup, node);
> > +
> > +                     if (tmppf->offset < pf->offset) {
> > +                             list_add(&pf->node, tmp);
> > +                             return 0;
> > +                     }
> > +             }
> > +             /*
> > +              * if we get here, then the new offset is the lowest so
> > +              * insert at the head
> > +              */
> > +             list_add(&pf->node, pf_head);
> > +             return 0;
> > +     }
> > +     list_add_tail(&pf->node, pf_head);
> > +     return 0;
> > +}
> > +
>
> regards,
> dan carpenter

Dan, Thanks for the detailed review on all 3 patches.

>
> --
> To unsubscribe from this group and stop receiving emails from it, send an email to kernel-team+unsubscribe@android.com.
>

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 1/3] binder: avoid potential data leakage when copying txn
  2021-11-23 19:17 ` [PATCH 1/3] binder: avoid potential data leakage when copying txn Todd Kjos
  2021-11-24  7:50   ` Martijn Coenen
  2021-11-24 13:01   ` Dan Carpenter
@ 2021-11-25  2:05   ` kernel test robot
  2021-11-25 12:18   ` kernel test robot
  3 siblings, 0 replies; 20+ messages in thread
From: kernel test robot @ 2021-11-25  2:05 UTC (permalink / raw)
  To: Todd Kjos, gregkh, christian, arve, devel, linux-kernel, maco
  Cc: kbuild-all, joel, kernel-team

Hi Todd,

I love your patch! Perhaps something to improve:

[auto build test WARNING on staging/staging-testing]
[also build test WARNING on v5.16-rc2 next-20211124]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Todd-Kjos/binder-Prevent-untranslated-sender-data-from-being-copied-to-target/20211124-031908
base:   https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging.git 1189d2fb15a4b09b2e8dd01d60a0817d985d933d
config: nds32-buildonly-randconfig-r004-20211123 (https://download.01.org/0day-ci/archive/20211125/202111251005.ZQfHG0PB-lkp@intel.com/config)
compiler: nds32le-linux-gcc (GCC) 11.2.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/0day-ci/linux/commit/d51c5e7a3791e9e748200416f85456c826d3030e
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Todd-Kjos/binder-Prevent-untranslated-sender-data-from-being-copied-to-target/20211124-031908
        git checkout d51c5e7a3791e9e748200416f85456c826d3030e
        # save the config file to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross ARCH=nds32 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All warnings (new ones prefixed by >>):

   In file included from include/asm-generic/bug.h:22,
                    from ./arch/nds32/include/generated/asm/bug.h:1,
                    from include/linux/bug.h:5,
                    from include/linux/thread_info.h:13,
                    from include/asm-generic/preempt.h:5,
                    from ./arch/nds32/include/generated/asm/preempt.h:1,
                    from include/linux/preempt.h:78,
                    from include/linux/spinlock.h:55,
                    from include/linux/fdtable.h:11,
                    from drivers/android/binder.c:45:
   drivers/android/binder.c: In function 'binder_transaction':
>> drivers/android/binder.c:2711:30: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
    2711 |                              (u64)user_buffer,
         |                              ^
   include/linux/printk.h:418:33: note: in definition of macro 'printk_index_wrap'
     418 |                 _p_func(_fmt, ##__VA_ARGS__);                           \
         |                                 ^~~~~~~~~~~
   include/linux/printk.h:640:17: note: in expansion of macro 'printk'
     640 |                 printk(fmt, ##__VA_ARGS__);                             \
         |                 ^~~~~~
   include/linux/printk.h:660:9: note: in expansion of macro 'printk_ratelimited'
     660 |         printk_ratelimited(KERN_INFO pr_fmt(fmt), ##__VA_ARGS__)
         |         ^~~~~~~~~~~~~~~~~~
   drivers/android/binder.c:139:25: note: in expansion of macro 'pr_info_ratelimited'
     139 |                         pr_info_ratelimited(x); \
         |                         ^~~~~~~~~~~~~~~~~~~
   drivers/android/binder.c:2707:17: note: in expansion of macro 'binder_debug'
    2707 |                 binder_debug(BINDER_DEBUG_TRANSACTION,
         |                 ^~~~~~~~~~~~
   drivers/android/binder.c:2720:30: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
    2720 |                              (u64)user_buffer,
         |                              ^
   include/linux/printk.h:418:33: note: in definition of macro 'printk_index_wrap'
     418 |                 _p_func(_fmt, ##__VA_ARGS__);                           \
         |                                 ^~~~~~~~~~~
   include/linux/printk.h:640:17: note: in expansion of macro 'printk'
     640 |                 printk(fmt, ##__VA_ARGS__);                             \
         |                 ^~~~~~
   include/linux/printk.h:660:9: note: in expansion of macro 'printk_ratelimited'
     660 |         printk_ratelimited(KERN_INFO pr_fmt(fmt), ##__VA_ARGS__)
         |         ^~~~~~~~~~~~~~~~~~
   drivers/android/binder.c:139:25: note: in expansion of macro 'pr_info_ratelimited'
     139 |                         pr_info_ratelimited(x); \
         |                         ^~~~~~~~~~~~~~~~~~~
   drivers/android/binder.c:2716:17: note: in expansion of macro 'binder_debug'
    2716 |                 binder_debug(BINDER_DEBUG_TRANSACTION,
         |                 ^~~~~~~~~~~~


vim +2711 drivers/android/binder.c

  2457	
  2458	static void binder_transaction(struct binder_proc *proc,
  2459				       struct binder_thread *thread,
  2460				       struct binder_transaction_data *tr, int reply,
  2461				       binder_size_t extra_buffers_size)
  2462	{
  2463		int ret;
  2464		struct binder_transaction *t;
  2465		struct binder_work *w;
  2466		struct binder_work *tcomplete;
  2467		binder_size_t buffer_offset = 0;
  2468		binder_size_t off_start_offset, off_end_offset;
  2469		binder_size_t off_min;
  2470		binder_size_t sg_buf_offset, sg_buf_end_offset;
  2471		binder_size_t user_offset = 0;
  2472		struct binder_proc *target_proc = NULL;
  2473		struct binder_thread *target_thread = NULL;
  2474		struct binder_node *target_node = NULL;
  2475		struct binder_transaction *in_reply_to = NULL;
  2476		struct binder_transaction_log_entry *e;
  2477		uint32_t return_error = 0;
  2478		uint32_t return_error_param = 0;
  2479		uint32_t return_error_line = 0;
  2480		binder_size_t last_fixup_obj_off = 0;
  2481		binder_size_t last_fixup_min_off = 0;
  2482		struct binder_context *context = proc->context;
  2483		int t_debug_id = atomic_inc_return(&binder_last_id);
  2484		char *secctx = NULL;
  2485		u32 secctx_sz = 0;
  2486		const void __user *user_buffer = (const void __user *)
  2487					(uintptr_t)tr->data.ptr.buffer;
  2488	
  2489		e = binder_transaction_log_add(&binder_transaction_log);
  2490		e->debug_id = t_debug_id;
  2491		e->call_type = reply ? 2 : !!(tr->flags & TF_ONE_WAY);
  2492		e->from_proc = proc->pid;
  2493		e->from_thread = thread->pid;
  2494		e->target_handle = tr->target.handle;
  2495		e->data_size = tr->data_size;
  2496		e->offsets_size = tr->offsets_size;
  2497		strscpy(e->context_name, proc->context->name, BINDERFS_MAX_NAME);
  2498	
  2499		if (reply) {
  2500			binder_inner_proc_lock(proc);
  2501			in_reply_to = thread->transaction_stack;
  2502			if (in_reply_to == NULL) {
  2503				binder_inner_proc_unlock(proc);
  2504				binder_user_error("%d:%d got reply transaction with no transaction stack\n",
  2505						  proc->pid, thread->pid);
  2506				return_error = BR_FAILED_REPLY;
  2507				return_error_param = -EPROTO;
  2508				return_error_line = __LINE__;
  2509				goto err_empty_call_stack;
  2510			}
  2511			if (in_reply_to->to_thread != thread) {
  2512				spin_lock(&in_reply_to->lock);
  2513				binder_user_error("%d:%d got reply transaction with bad transaction stack, transaction %d has target %d:%d\n",
  2514					proc->pid, thread->pid, in_reply_to->debug_id,
  2515					in_reply_to->to_proc ?
  2516					in_reply_to->to_proc->pid : 0,
  2517					in_reply_to->to_thread ?
  2518					in_reply_to->to_thread->pid : 0);
  2519				spin_unlock(&in_reply_to->lock);
  2520				binder_inner_proc_unlock(proc);
  2521				return_error = BR_FAILED_REPLY;
  2522				return_error_param = -EPROTO;
  2523				return_error_line = __LINE__;
  2524				in_reply_to = NULL;
  2525				goto err_bad_call_stack;
  2526			}
  2527			thread->transaction_stack = in_reply_to->to_parent;
  2528			binder_inner_proc_unlock(proc);
  2529			binder_set_nice(in_reply_to->saved_priority);
  2530			target_thread = binder_get_txn_from_and_acq_inner(in_reply_to);
  2531			if (target_thread == NULL) {
  2532				/* annotation for sparse */
  2533				__release(&target_thread->proc->inner_lock);
  2534				return_error = BR_DEAD_REPLY;
  2535				return_error_line = __LINE__;
  2536				goto err_dead_binder;
  2537			}
  2538			if (target_thread->transaction_stack != in_reply_to) {
  2539				binder_user_error("%d:%d got reply transaction with bad target transaction stack %d, expected %d\n",
  2540					proc->pid, thread->pid,
  2541					target_thread->transaction_stack ?
  2542					target_thread->transaction_stack->debug_id : 0,
  2543					in_reply_to->debug_id);
  2544				binder_inner_proc_unlock(target_thread->proc);
  2545				return_error = BR_FAILED_REPLY;
  2546				return_error_param = -EPROTO;
  2547				return_error_line = __LINE__;
  2548				in_reply_to = NULL;
  2549				target_thread = NULL;
  2550				goto err_dead_binder;
  2551			}
  2552			target_proc = target_thread->proc;
  2553			target_proc->tmp_ref++;
  2554			binder_inner_proc_unlock(target_thread->proc);
  2555		} else {
  2556			if (tr->target.handle) {
  2557				struct binder_ref *ref;
  2558	
  2559				/*
  2560				 * There must already be a strong ref
  2561				 * on this node. If so, do a strong
  2562				 * increment on the node to ensure it
  2563				 * stays alive until the transaction is
  2564				 * done.
  2565				 */
  2566				binder_proc_lock(proc);
  2567				ref = binder_get_ref_olocked(proc, tr->target.handle,
  2568							     true);
  2569				if (ref) {
  2570					target_node = binder_get_node_refs_for_txn(
  2571							ref->node, &target_proc,
  2572							&return_error);
  2573				} else {
  2574					binder_user_error("%d:%d got transaction to invalid handle, %u\n",
  2575							  proc->pid, thread->pid, tr->target.handle);
  2576					return_error = BR_FAILED_REPLY;
  2577				}
  2578				binder_proc_unlock(proc);
  2579			} else {
  2580				mutex_lock(&context->context_mgr_node_lock);
  2581				target_node = context->binder_context_mgr_node;
  2582				if (target_node)
  2583					target_node = binder_get_node_refs_for_txn(
  2584							target_node, &target_proc,
  2585							&return_error);
  2586				else
  2587					return_error = BR_DEAD_REPLY;
  2588				mutex_unlock(&context->context_mgr_node_lock);
  2589				if (target_node && target_proc->pid == proc->pid) {
  2590					binder_user_error("%d:%d got transaction to context manager from process owning it\n",
  2591							  proc->pid, thread->pid);
  2592					return_error = BR_FAILED_REPLY;
  2593					return_error_param = -EINVAL;
  2594					return_error_line = __LINE__;
  2595					goto err_invalid_target_handle;
  2596				}
  2597			}
  2598			if (!target_node) {
  2599				/*
  2600				 * return_error is set above
  2601				 */
  2602				return_error_param = -EINVAL;
  2603				return_error_line = __LINE__;
  2604				goto err_dead_binder;
  2605			}
  2606			e->to_node = target_node->debug_id;
  2607			if (WARN_ON(proc == target_proc)) {
  2608				return_error = BR_FAILED_REPLY;
  2609				return_error_param = -EINVAL;
  2610				return_error_line = __LINE__;
  2611				goto err_invalid_target_handle;
  2612			}
  2613			if (security_binder_transaction(proc->cred,
  2614							target_proc->cred) < 0) {
  2615				return_error = BR_FAILED_REPLY;
  2616				return_error_param = -EPERM;
  2617				return_error_line = __LINE__;
  2618				goto err_invalid_target_handle;
  2619			}
  2620			binder_inner_proc_lock(proc);
  2621	
  2622			w = list_first_entry_or_null(&thread->todo,
  2623						     struct binder_work, entry);
  2624			if (!(tr->flags & TF_ONE_WAY) && w &&
  2625			    w->type == BINDER_WORK_TRANSACTION) {
  2626				/*
  2627				 * Do not allow new outgoing transaction from a
  2628				 * thread that has a transaction at the head of
  2629				 * its todo list. Only need to check the head
  2630				 * because binder_select_thread_ilocked picks a
  2631				 * thread from proc->waiting_threads to enqueue
  2632				 * the transaction, and nothing is queued to the
  2633				 * todo list while the thread is on waiting_threads.
  2634				 */
  2635				binder_user_error("%d:%d new transaction not allowed when there is a transaction on thread todo\n",
  2636						  proc->pid, thread->pid);
  2637				binder_inner_proc_unlock(proc);
  2638				return_error = BR_FAILED_REPLY;
  2639				return_error_param = -EPROTO;
  2640				return_error_line = __LINE__;
  2641				goto err_bad_todo_list;
  2642			}
  2643	
  2644			if (!(tr->flags & TF_ONE_WAY) && thread->transaction_stack) {
  2645				struct binder_transaction *tmp;
  2646	
  2647				tmp = thread->transaction_stack;
  2648				if (tmp->to_thread != thread) {
  2649					spin_lock(&tmp->lock);
  2650					binder_user_error("%d:%d got new transaction with bad transaction stack, transaction %d has target %d:%d\n",
  2651						proc->pid, thread->pid, tmp->debug_id,
  2652						tmp->to_proc ? tmp->to_proc->pid : 0,
  2653						tmp->to_thread ?
  2654						tmp->to_thread->pid : 0);
  2655					spin_unlock(&tmp->lock);
  2656					binder_inner_proc_unlock(proc);
  2657					return_error = BR_FAILED_REPLY;
  2658					return_error_param = -EPROTO;
  2659					return_error_line = __LINE__;
  2660					goto err_bad_call_stack;
  2661				}
  2662				while (tmp) {
  2663					struct binder_thread *from;
  2664	
  2665					spin_lock(&tmp->lock);
  2666					from = tmp->from;
  2667					if (from && from->proc == target_proc) {
  2668						atomic_inc(&from->tmp_ref);
  2669						target_thread = from;
  2670						spin_unlock(&tmp->lock);
  2671						break;
  2672					}
  2673					spin_unlock(&tmp->lock);
  2674					tmp = tmp->from_parent;
  2675				}
  2676			}
  2677			binder_inner_proc_unlock(proc);
  2678		}
  2679		if (target_thread)
  2680			e->to_thread = target_thread->pid;
  2681		e->to_proc = target_proc->pid;
  2682	
  2683		/* TODO: reuse incoming transaction for reply */
  2684		t = kzalloc(sizeof(*t), GFP_KERNEL);
  2685		if (t == NULL) {
  2686			return_error = BR_FAILED_REPLY;
  2687			return_error_param = -ENOMEM;
  2688			return_error_line = __LINE__;
  2689			goto err_alloc_t_failed;
  2690		}
  2691		INIT_LIST_HEAD(&t->fd_fixups);
  2692		binder_stats_created(BINDER_STAT_TRANSACTION);
  2693		spin_lock_init(&t->lock);
  2694	
  2695		tcomplete = kzalloc(sizeof(*tcomplete), GFP_KERNEL);
  2696		if (tcomplete == NULL) {
  2697			return_error = BR_FAILED_REPLY;
  2698			return_error_param = -ENOMEM;
  2699			return_error_line = __LINE__;
  2700			goto err_alloc_tcomplete_failed;
  2701		}
  2702		binder_stats_created(BINDER_STAT_TRANSACTION_COMPLETE);
  2703	
  2704		t->debug_id = t_debug_id;
  2705	
  2706		if (reply)
  2707			binder_debug(BINDER_DEBUG_TRANSACTION,
  2708				     "%d:%d BC_REPLY %d -> %d:%d, data %016llx-%016llx size %lld-%lld-%lld\n",
  2709				     proc->pid, thread->pid, t->debug_id,
  2710				     target_proc->pid, target_thread->pid,
> 2711				     (u64)user_buffer,
  2712				     (u64)tr->data.ptr.offsets,
  2713				     (u64)tr->data_size, (u64)tr->offsets_size,
  2714				     (u64)extra_buffers_size);
  2715		else
  2716			binder_debug(BINDER_DEBUG_TRANSACTION,
  2717				     "%d:%d BC_TRANSACTION %d -> %d - node %d, data %016llx-%016llx size %lld-%lld-%lld\n",
  2718				     proc->pid, thread->pid, t->debug_id,
  2719				     target_proc->pid, target_node->debug_id,
  2720				     (u64)user_buffer,
  2721				     (u64)tr->data.ptr.offsets,
  2722				     (u64)tr->data_size, (u64)tr->offsets_size,
  2723				     (u64)extra_buffers_size);
  2724	
  2725		if (!reply && !(tr->flags & TF_ONE_WAY))
  2726			t->from = thread;
  2727		else
  2728			t->from = NULL;
  2729		t->sender_euid = proc->cred->euid;
  2730		t->to_proc = target_proc;
  2731		t->to_thread = target_thread;
  2732		t->code = tr->code;
  2733		t->flags = tr->flags;
  2734		t->priority = task_nice(current);
  2735	
  2736		if (target_node && target_node->txn_security_ctx) {
  2737			u32 secid;
  2738			size_t added_size;
  2739	
  2740			security_cred_getsecid(proc->cred, &secid);
  2741			ret = security_secid_to_secctx(secid, &secctx, &secctx_sz);
  2742			if (ret) {
  2743				return_error = BR_FAILED_REPLY;
  2744				return_error_param = ret;
  2745				return_error_line = __LINE__;
  2746				goto err_get_secctx_failed;
  2747			}
  2748			added_size = ALIGN(secctx_sz, sizeof(u64));
  2749			extra_buffers_size += added_size;
  2750			if (extra_buffers_size < added_size) {
  2751				/* integer overflow of extra_buffers_size */
  2752				return_error = BR_FAILED_REPLY;
  2753				return_error_param = -EINVAL;
  2754				return_error_line = __LINE__;
  2755				goto err_bad_extra_size;
  2756			}
  2757		}
  2758	
  2759		trace_binder_transaction(reply, t, target_node);
  2760	
  2761		t->buffer = binder_alloc_new_buf(&target_proc->alloc, tr->data_size,
  2762			tr->offsets_size, extra_buffers_size,
  2763			!reply && (t->flags & TF_ONE_WAY), current->tgid);
  2764		if (IS_ERR(t->buffer)) {
  2765			/*
  2766			 * -ESRCH indicates VMA cleared. The target is dying.
  2767			 */
  2768			return_error_param = PTR_ERR(t->buffer);
  2769			return_error = return_error_param == -ESRCH ?
  2770				BR_DEAD_REPLY : BR_FAILED_REPLY;
  2771			return_error_line = __LINE__;
  2772			t->buffer = NULL;
  2773			goto err_binder_alloc_buf_failed;
  2774		}
  2775		if (secctx) {
  2776			int err;
  2777			size_t buf_offset = ALIGN(tr->data_size, sizeof(void *)) +
  2778					    ALIGN(tr->offsets_size, sizeof(void *)) +
  2779					    ALIGN(extra_buffers_size, sizeof(void *)) -
  2780					    ALIGN(secctx_sz, sizeof(u64));
  2781	
  2782			t->security_ctx = (uintptr_t)t->buffer->user_data + buf_offset;
  2783			err = binder_alloc_copy_to_buffer(&target_proc->alloc,
  2784							  t->buffer, buf_offset,
  2785							  secctx, secctx_sz);
  2786			if (err) {
  2787				t->security_ctx = 0;
  2788				WARN_ON(1);
  2789			}
  2790			security_release_secctx(secctx, secctx_sz);
  2791			secctx = NULL;
  2792		}
  2793		t->buffer->debug_id = t->debug_id;
  2794		t->buffer->transaction = t;
  2795		t->buffer->target_node = target_node;
  2796		t->buffer->clear_on_free = !!(t->flags & TF_CLEAR_BUF);
  2797		trace_binder_transaction_alloc_buf(t->buffer);
  2798	
  2799		if (binder_alloc_copy_user_to_buffer(
  2800					&target_proc->alloc,
  2801					t->buffer,
  2802					ALIGN(tr->data_size, sizeof(void *)),
  2803					(const void __user *)
  2804						(uintptr_t)tr->data.ptr.offsets,
  2805					tr->offsets_size)) {
  2806			binder_user_error("%d:%d got transaction with invalid offsets ptr\n",
  2807					proc->pid, thread->pid);
  2808			return_error = BR_FAILED_REPLY;
  2809			return_error_param = -EFAULT;
  2810			return_error_line = __LINE__;
  2811			goto err_copy_data_failed;
  2812		}
  2813		if (!IS_ALIGNED(tr->offsets_size, sizeof(binder_size_t))) {
  2814			binder_user_error("%d:%d got transaction with invalid offsets size, %lld\n",
  2815					proc->pid, thread->pid, (u64)tr->offsets_size);
  2816			return_error = BR_FAILED_REPLY;
  2817			return_error_param = -EINVAL;
  2818			return_error_line = __LINE__;
  2819			goto err_bad_offset;
  2820		}
  2821		if (!IS_ALIGNED(extra_buffers_size, sizeof(u64))) {
  2822			binder_user_error("%d:%d got transaction with unaligned buffers size, %lld\n",
  2823					  proc->pid, thread->pid,
  2824					  (u64)extra_buffers_size);
  2825			return_error = BR_FAILED_REPLY;
  2826			return_error_param = -EINVAL;
  2827			return_error_line = __LINE__;
  2828			goto err_bad_offset;
  2829		}
  2830		off_start_offset = ALIGN(tr->data_size, sizeof(void *));
  2831		buffer_offset = off_start_offset;
  2832		off_end_offset = off_start_offset + tr->offsets_size;
  2833		sg_buf_offset = ALIGN(off_end_offset, sizeof(void *));
  2834		sg_buf_end_offset = sg_buf_offset + extra_buffers_size -
  2835			ALIGN(secctx_sz, sizeof(u64));
  2836		off_min = 0;
  2837		for (buffer_offset = off_start_offset; buffer_offset < off_end_offset;
  2838		     buffer_offset += sizeof(binder_size_t)) {
  2839			struct binder_object_header *hdr;
  2840			size_t object_size;
  2841			struct binder_object object;
  2842			binder_size_t object_offset;
  2843			binder_size_t copy_size;
  2844	
  2845			if (binder_alloc_copy_from_buffer(&target_proc->alloc,
  2846							  &object_offset,
  2847							  t->buffer,
  2848							  buffer_offset,
  2849							  sizeof(object_offset))) {
  2850				return_error = BR_FAILED_REPLY;
  2851				return_error_param = -EINVAL;
  2852				return_error_line = __LINE__;
  2853				goto err_bad_offset;
  2854			}
  2855	
  2856			/*
  2857			 * Copy the source user buffer up to the next object
  2858			 * that will be processed.
  2859			 */
  2860			copy_size = object_offset - user_offset;
  2861			if (copy_size && (user_offset > object_offset ||
  2862					binder_alloc_copy_user_to_buffer(
  2863						&target_proc->alloc,
  2864						t->buffer, user_offset,
  2865						user_buffer + user_offset,
  2866						copy_size))) {
  2867				binder_user_error("%d:%d got transaction with invalid data ptr\n",
  2868						proc->pid, thread->pid);
  2869				return_error = BR_FAILED_REPLY;
  2870				return_error_param = -EFAULT;
  2871				return_error_line = __LINE__;
  2872				goto err_copy_data_failed;
  2873			}
  2874			object_size = binder_get_object(target_proc, user_buffer,
  2875					t->buffer, object_offset, &object);
  2876			if (object_size == 0 || object_offset < off_min) {
  2877				binder_user_error("%d:%d got transaction with invalid offset (%lld, min %lld max %lld) or object.\n",
  2878						  proc->pid, thread->pid,
  2879						  (u64)object_offset,
  2880						  (u64)off_min,
  2881						  (u64)t->buffer->data_size);
  2882				return_error = BR_FAILED_REPLY;
  2883				return_error_param = -EINVAL;
  2884				return_error_line = __LINE__;
  2885				goto err_bad_offset;
  2886			}
  2887			/*
  2888			 * Set offset to the next buffer fragment to be
  2889			 * copied
  2890			 */
  2891			user_offset = object_offset + object_size;
  2892	
  2893			hdr = &object.hdr;
  2894			off_min = object_offset + object_size;
  2895			switch (hdr->type) {
  2896			case BINDER_TYPE_BINDER:
  2897			case BINDER_TYPE_WEAK_BINDER: {
  2898				struct flat_binder_object *fp;
  2899	
  2900				fp = to_flat_binder_object(hdr);
  2901				ret = binder_translate_binder(fp, t, thread);
  2902	
  2903				if (ret < 0 ||
  2904				    binder_alloc_copy_to_buffer(&target_proc->alloc,
  2905								t->buffer,
  2906								object_offset,
  2907								fp, sizeof(*fp))) {
  2908					return_error = BR_FAILED_REPLY;
  2909					return_error_param = ret;
  2910					return_error_line = __LINE__;
  2911					goto err_translate_failed;
  2912				}
  2913			} break;
  2914			case BINDER_TYPE_HANDLE:
  2915			case BINDER_TYPE_WEAK_HANDLE: {
  2916				struct flat_binder_object *fp;
  2917	
  2918				fp = to_flat_binder_object(hdr);
  2919				ret = binder_translate_handle(fp, t, thread);
  2920				if (ret < 0 ||
  2921				    binder_alloc_copy_to_buffer(&target_proc->alloc,
  2922								t->buffer,
  2923								object_offset,
  2924								fp, sizeof(*fp))) {
  2925					return_error = BR_FAILED_REPLY;
  2926					return_error_param = ret;
  2927					return_error_line = __LINE__;
  2928					goto err_translate_failed;
  2929				}
  2930			} break;
  2931	
  2932			case BINDER_TYPE_FD: {
  2933				struct binder_fd_object *fp = to_binder_fd_object(hdr);
  2934				binder_size_t fd_offset = object_offset +
  2935					(uintptr_t)&fp->fd - (uintptr_t)fp;
  2936				int ret = binder_translate_fd(fp->fd, fd_offset, t,
  2937							      thread, in_reply_to);
  2938	
  2939				fp->pad_binder = 0;
  2940				if (ret < 0 ||
  2941				    binder_alloc_copy_to_buffer(&target_proc->alloc,
  2942								t->buffer,
  2943								object_offset,
  2944								fp, sizeof(*fp))) {
  2945					return_error = BR_FAILED_REPLY;
  2946					return_error_param = ret;
  2947					return_error_line = __LINE__;
  2948					goto err_translate_failed;
  2949				}
  2950			} break;
  2951			case BINDER_TYPE_FDA: {
  2952				struct binder_object ptr_object;
  2953				binder_size_t parent_offset;
  2954				struct binder_fd_array_object *fda =
  2955					to_binder_fd_array_object(hdr);
  2956				size_t num_valid = (buffer_offset - off_start_offset) /
  2957							sizeof(binder_size_t);
  2958				struct binder_buffer_object *parent =
  2959					binder_validate_ptr(target_proc, t->buffer,
  2960							    &ptr_object, fda->parent,
  2961							    off_start_offset,
  2962							    &parent_offset,
  2963							    num_valid);
  2964				if (!parent) {
  2965					binder_user_error("%d:%d got transaction with invalid parent offset or type\n",
  2966							  proc->pid, thread->pid);
  2967					return_error = BR_FAILED_REPLY;
  2968					return_error_param = -EINVAL;
  2969					return_error_line = __LINE__;
  2970					goto err_bad_parent;
  2971				}
  2972				if (!binder_validate_fixup(target_proc, t->buffer,
  2973							   off_start_offset,
  2974							   parent_offset,
  2975							   fda->parent_offset,
  2976							   last_fixup_obj_off,
  2977							   last_fixup_min_off)) {
  2978					binder_user_error("%d:%d got transaction with out-of-order buffer fixup\n",
  2979							  proc->pid, thread->pid);
  2980					return_error = BR_FAILED_REPLY;
  2981					return_error_param = -EINVAL;
  2982					return_error_line = __LINE__;
  2983					goto err_bad_parent;
  2984				}
  2985				ret = binder_translate_fd_array(fda, parent, t, thread,
  2986								in_reply_to);
  2987				if (ret < 0 ||
  2988				    binder_alloc_copy_to_buffer(&target_proc->alloc,
  2989								t->buffer,
  2990								object_offset,
  2991								fda, sizeof(*fda))) {
  2992					return_error = BR_FAILED_REPLY;
  2993					return_error_param = ret;
  2994					return_error_line = __LINE__;
  2995					goto err_translate_failed;
  2996				}
  2997				last_fixup_obj_off = parent_offset;
  2998				last_fixup_min_off =
  2999					fda->parent_offset + sizeof(u32) * fda->num_fds;
  3000			} break;
  3001			case BINDER_TYPE_PTR: {
  3002				struct binder_buffer_object *bp =
  3003					to_binder_buffer_object(hdr);
  3004				size_t buf_left = sg_buf_end_offset - sg_buf_offset;
  3005				size_t num_valid;
  3006	
  3007				if (bp->length > buf_left) {
  3008					binder_user_error("%d:%d got transaction with too large buffer\n",
  3009							  proc->pid, thread->pid);
  3010					return_error = BR_FAILED_REPLY;
  3011					return_error_param = -EINVAL;
  3012					return_error_line = __LINE__;
  3013					goto err_bad_offset;
  3014				}
  3015				if (binder_alloc_copy_user_to_buffer(
  3016							&target_proc->alloc,
  3017							t->buffer,
  3018							sg_buf_offset,
  3019							(const void __user *)
  3020								(uintptr_t)bp->buffer,
  3021							bp->length)) {
  3022					binder_user_error("%d:%d got transaction with invalid offsets ptr\n",
  3023							  proc->pid, thread->pid);
  3024					return_error_param = -EFAULT;
  3025					return_error = BR_FAILED_REPLY;
  3026					return_error_line = __LINE__;
  3027					goto err_copy_data_failed;
  3028				}
  3029				/* Fixup buffer pointer to target proc address space */
  3030				bp->buffer = (uintptr_t)
  3031					t->buffer->user_data + sg_buf_offset;
  3032				sg_buf_offset += ALIGN(bp->length, sizeof(u64));
  3033	
  3034				num_valid = (buffer_offset - off_start_offset) /
  3035						sizeof(binder_size_t);
  3036				ret = binder_fixup_parent(t, thread, bp,
  3037							  off_start_offset,
  3038							  num_valid,
  3039							  last_fixup_obj_off,
  3040							  last_fixup_min_off);
  3041				if (ret < 0 ||
  3042				    binder_alloc_copy_to_buffer(&target_proc->alloc,
  3043								t->buffer,
  3044								object_offset,
  3045								bp, sizeof(*bp))) {
  3046					return_error = BR_FAILED_REPLY;
  3047					return_error_param = ret;
  3048					return_error_line = __LINE__;
  3049					goto err_translate_failed;
  3050				}
  3051				last_fixup_obj_off = object_offset;
  3052				last_fixup_min_off = 0;
  3053			} break;
  3054			default:
  3055				binder_user_error("%d:%d got transaction with invalid object type, %x\n",
  3056					proc->pid, thread->pid, hdr->type);
  3057				return_error = BR_FAILED_REPLY;
  3058				return_error_param = -EINVAL;
  3059				return_error_line = __LINE__;
  3060				goto err_bad_object_type;
  3061			}
  3062		}
  3063		/* Done processing objects, copy the rest of the buffer */
  3064		if (binder_alloc_copy_user_to_buffer(
  3065					&target_proc->alloc,
  3066					t->buffer, user_offset,
  3067					user_buffer + user_offset,
  3068					tr->data_size - user_offset)) {
  3069			binder_user_error("%d:%d got transaction with invalid data ptr\n",
  3070					proc->pid, thread->pid);
  3071			return_error = BR_FAILED_REPLY;
  3072			return_error_param = -EFAULT;
  3073			return_error_line = __LINE__;
  3074			goto err_copy_data_failed;
  3075		}
  3076		if (t->buffer->oneway_spam_suspect)
  3077			tcomplete->type = BINDER_WORK_TRANSACTION_ONEWAY_SPAM_SUSPECT;
  3078		else
  3079			tcomplete->type = BINDER_WORK_TRANSACTION_COMPLETE;
  3080		t->work.type = BINDER_WORK_TRANSACTION;
  3081	
  3082		if (reply) {
  3083			binder_enqueue_thread_work(thread, tcomplete);
  3084			binder_inner_proc_lock(target_proc);
  3085			if (target_thread->is_dead) {
  3086				return_error = BR_DEAD_REPLY;
  3087				binder_inner_proc_unlock(target_proc);
  3088				goto err_dead_proc_or_thread;
  3089			}
  3090			BUG_ON(t->buffer->async_transaction != 0);
  3091			binder_pop_transaction_ilocked(target_thread, in_reply_to);
  3092			binder_enqueue_thread_work_ilocked(target_thread, &t->work);
  3093			target_proc->outstanding_txns++;
  3094			binder_inner_proc_unlock(target_proc);
  3095			wake_up_interruptible_sync(&target_thread->wait);
  3096			binder_free_transaction(in_reply_to);
  3097		} else if (!(t->flags & TF_ONE_WAY)) {
  3098			BUG_ON(t->buffer->async_transaction != 0);
  3099			binder_inner_proc_lock(proc);
  3100			/*
  3101			 * Defer the TRANSACTION_COMPLETE, so we don't return to
  3102			 * userspace immediately; this allows the target process to
  3103			 * immediately start processing this transaction, reducing
  3104			 * latency. We will then return the TRANSACTION_COMPLETE when
  3105			 * the target replies (or there is an error).
  3106			 */
  3107			binder_enqueue_deferred_thread_work_ilocked(thread, tcomplete);
  3108			t->need_reply = 1;
  3109			t->from_parent = thread->transaction_stack;
  3110			thread->transaction_stack = t;
  3111			binder_inner_proc_unlock(proc);
  3112			return_error = binder_proc_transaction(t,
  3113					target_proc, target_thread);
  3114			if (return_error) {
  3115				binder_inner_proc_lock(proc);
  3116				binder_pop_transaction_ilocked(thread, t);
  3117				binder_inner_proc_unlock(proc);
  3118				goto err_dead_proc_or_thread;
  3119			}
  3120		} else {
  3121			BUG_ON(target_node == NULL);
  3122			BUG_ON(t->buffer->async_transaction != 1);
  3123			binder_enqueue_thread_work(thread, tcomplete);
  3124			return_error = binder_proc_transaction(t, target_proc, NULL);
  3125			if (return_error)
  3126				goto err_dead_proc_or_thread;
  3127		}
  3128		if (target_thread)
  3129			binder_thread_dec_tmpref(target_thread);
  3130		binder_proc_dec_tmpref(target_proc);
  3131		if (target_node)
  3132			binder_dec_node_tmpref(target_node);
  3133		/*
  3134		 * write barrier to synchronize with initialization
  3135		 * of log entry
  3136		 */
  3137		smp_wmb();
  3138		WRITE_ONCE(e->debug_id_done, t_debug_id);
  3139		return;
  3140	
  3141	err_dead_proc_or_thread:
  3142		return_error_line = __LINE__;
  3143		binder_dequeue_work(proc, tcomplete);
  3144	err_translate_failed:
  3145	err_bad_object_type:
  3146	err_bad_offset:
  3147	err_bad_parent:
  3148	err_copy_data_failed:
  3149		binder_free_txn_fixups(t);
  3150		trace_binder_transaction_failed_buffer_release(t->buffer);
  3151		binder_transaction_buffer_release(target_proc, NULL, t->buffer,
  3152						  buffer_offset, true);
  3153		if (target_node)
  3154			binder_dec_node_tmpref(target_node);
  3155		target_node = NULL;
  3156		t->buffer->transaction = NULL;
  3157		binder_alloc_free_buf(&target_proc->alloc, t->buffer);
  3158	err_binder_alloc_buf_failed:
  3159	err_bad_extra_size:
  3160		if (secctx)
  3161			security_release_secctx(secctx, secctx_sz);
  3162	err_get_secctx_failed:
  3163		kfree(tcomplete);
  3164		binder_stats_deleted(BINDER_STAT_TRANSACTION_COMPLETE);
  3165	err_alloc_tcomplete_failed:
  3166		if (trace_binder_txn_latency_free_enabled())
  3167			binder_txn_latency_free(t);
  3168		kfree(t);
  3169		binder_stats_deleted(BINDER_STAT_TRANSACTION);
  3170	err_alloc_t_failed:
  3171	err_bad_todo_list:
  3172	err_bad_call_stack:
  3173	err_empty_call_stack:
  3174	err_dead_binder:
  3175	err_invalid_target_handle:
  3176		if (target_thread)
  3177			binder_thread_dec_tmpref(target_thread);
  3178		if (target_proc)
  3179			binder_proc_dec_tmpref(target_proc);
  3180		if (target_node) {
  3181			binder_dec_node(target_node, 1, 0);
  3182			binder_dec_node_tmpref(target_node);
  3183		}
  3184	
  3185		binder_debug(BINDER_DEBUG_FAILED_TRANSACTION,
  3186			     "%d:%d transaction failed %d/%d, size %lld-%lld line %d\n",
  3187			     proc->pid, thread->pid, return_error, return_error_param,
  3188			     (u64)tr->data_size, (u64)tr->offsets_size,
  3189			     return_error_line);
  3190	
  3191		{
  3192			struct binder_transaction_log_entry *fe;
  3193	
  3194			e->return_error = return_error;
  3195			e->return_error_param = return_error_param;
  3196			e->return_error_line = return_error_line;
  3197			fe = binder_transaction_log_add(&binder_transaction_log_failed);
  3198			*fe = *e;
  3199			/*
  3200			 * write barrier to synchronize with initialization
  3201			 * of log entry
  3202			 */
  3203			smp_wmb();
  3204			WRITE_ONCE(e->debug_id_done, t_debug_id);
  3205			WRITE_ONCE(fe->debug_id_done, t_debug_id);
  3206		}
  3207	
  3208		BUG_ON(thread->return_error.cmd != BR_OK);
  3209		if (in_reply_to) {
  3210			thread->return_error.cmd = BR_TRANSACTION_COMPLETE;
  3211			binder_enqueue_thread_work(thread, &thread->return_error.work);
  3212			binder_send_failed_reply(in_reply_to, return_error);
  3213		} else {
  3214			thread->return_error.cmd = return_error;
  3215			binder_enqueue_thread_work(thread, &thread->return_error.work);
  3216		}
  3217	}
  3218	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 2/3] binder: read pre-translated fds from sender buffer
  2021-11-24 20:33     ` Todd Kjos
@ 2021-11-25  6:37       ` Dan Carpenter
  0 siblings, 0 replies; 20+ messages in thread
From: Dan Carpenter @ 2021-11-25  6:37 UTC (permalink / raw)
  To: Todd Kjos
  Cc: devel, gregkh, linux-kernel, arve, maco, joel, kernel-team, christian

On Wed, Nov 24, 2021 at 12:33:20PM -0800, Todd Kjos wrote:
> I agree -- if copy_from_user() for some reason doesn't copy the whole
> buffer, it might return a positive integer. Then it would skip
> binder_translate_fd(), but not return. That should probably be
> something like:
> 
>   if (ret)
>     return ret > 0 ? -EINVAL : ret;
> 
> Will fix in next version.

It should really be a separate patch at the start of the series because
it's from the original code and unrelated.

regards,
dan carpenter


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 1/3] binder: avoid potential data leakage when copying txn
  2021-11-23 19:17 ` [PATCH 1/3] binder: avoid potential data leakage when copying txn Todd Kjos
                     ` (2 preceding siblings ...)
  2021-11-25  2:05   ` kernel test robot
@ 2021-11-25 12:18   ` kernel test robot
  3 siblings, 0 replies; 20+ messages in thread
From: kernel test robot @ 2021-11-25 12:18 UTC (permalink / raw)
  To: Todd Kjos, gregkh, christian, arve, devel, linux-kernel, maco
  Cc: kbuild-all, joel, kernel-team

Hi Todd,

I love your patch! Perhaps something to improve:

[auto build test WARNING on staging/staging-testing]
[also build test WARNING on v5.16-rc2 next-20211125]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Todd-Kjos/binder-Prevent-untranslated-sender-data-from-being-copied-to-target/20211124-031908
base:   https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging.git 1189d2fb15a4b09b2e8dd01d60a0817d985d933d
config: ia64-randconfig-s032-20211123 (https://download.01.org/0day-ci/archive/20211125/202111252042.kCPmeLlY-lkp@intel.com/config)
compiler: ia64-linux-gcc (GCC) 11.2.0
reproduce:
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # apt-get install sparse
        # sparse version: v0.6.4-dirty
        # https://github.com/0day-ci/linux/commit/d51c5e7a3791e9e748200416f85456c826d3030e
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Todd-Kjos/binder-Prevent-untranslated-sender-data-from-being-copied-to-target/20211124-031908
        git checkout d51c5e7a3791e9e748200416f85456c826d3030e
        # save the config file to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__' O=build_dir ARCH=ia64 SHELL=/bin/bash drivers/android/

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>


sparse warnings: (new ones prefixed by >>)
>> drivers/android/binder.c:2707:17: sparse: sparse: cast removes address space '__user' of expression
   drivers/android/binder.c:2716:17: sparse: sparse: cast removes address space '__user' of expression
   drivers/android/binder.c:4507:24: sparse: sparse: incorrect type in return expression (different base types) @@     expected restricted __poll_t @@     got int @@
   drivers/android/binder.c:4507:24: sparse:     expected restricted __poll_t
   drivers/android/binder.c:4507:24: sparse:     got int

vim +/__user +2707 drivers/android/binder.c

512cf465ee01eb drivers/android/binder.c         Todd Kjos             2017-09-29  2457  
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2458  static void binder_transaction(struct binder_proc *proc,
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2459  			       struct binder_thread *thread,
4bfac80af3a63f drivers/android/binder.c         Martijn Coenen        2017-02-03  2460  			       struct binder_transaction_data *tr, int reply,
4bfac80af3a63f drivers/android/binder.c         Martijn Coenen        2017-02-03  2461  			       binder_size_t extra_buffers_size)
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2462  {
a056af42032e56 drivers/android/binder.c         Martijn Coenen        2017-02-03  2463  	int ret;
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2464  	struct binder_transaction *t;
44b73962cb25f1 drivers/android/binder.c         Sherry Yang           2018-08-13  2465  	struct binder_work *w;
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2466  	struct binder_work *tcomplete;
bde4a19fc04f5f drivers/android/binder.c         Todd Kjos             2019-02-08  2467  	binder_size_t buffer_offset = 0;
bde4a19fc04f5f drivers/android/binder.c         Todd Kjos             2019-02-08  2468  	binder_size_t off_start_offset, off_end_offset;
212265e5ad726e drivers/android/binder.c         Arve Hjønnevåg        2016-02-09  2469  	binder_size_t off_min;
bde4a19fc04f5f drivers/android/binder.c         Todd Kjos             2019-02-08  2470  	binder_size_t sg_buf_offset, sg_buf_end_offset;
d51c5e7a3791e9 drivers/android/binder.c         Todd Kjos             2021-11-23  2471  	binder_size_t user_offset = 0;
7a4408c6bd3eb1 drivers/android/binder.c         Todd Kjos             2017-06-29  2472  	struct binder_proc *target_proc = NULL;
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2473  	struct binder_thread *target_thread = NULL;
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2474  	struct binder_node *target_node = NULL;
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2475  	struct binder_transaction *in_reply_to = NULL;
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2476  	struct binder_transaction_log_entry *e;
57ada2fb2250ea drivers/android/binder.c         Todd Kjos             2017-06-29  2477  	uint32_t return_error = 0;
57ada2fb2250ea drivers/android/binder.c         Todd Kjos             2017-06-29  2478  	uint32_t return_error_param = 0;
57ada2fb2250ea drivers/android/binder.c         Todd Kjos             2017-06-29  2479  	uint32_t return_error_line = 0;
db6b0b810bf945 drivers/android/binder.c         Todd Kjos             2019-02-08  2480  	binder_size_t last_fixup_obj_off = 0;
7980240b6d63e0 drivers/android/binder.c         Martijn Coenen        2017-02-03  2481  	binder_size_t last_fixup_min_off = 0;
342e5c90b60134 drivers/android/binder.c         Martijn Coenen        2017-02-03  2482  	struct binder_context *context = proc->context;
d99c7333ab1c9d drivers/android/binder.c         Todd Kjos             2017-06-29  2483  	int t_debug_id = atomic_inc_return(&binder_last_id);
ec74136ded792d drivers/android/binder.c         Todd Kjos             2019-01-14  2484  	char *secctx = NULL;
ec74136ded792d drivers/android/binder.c         Todd Kjos             2019-01-14  2485  	u32 secctx_sz = 0;
d51c5e7a3791e9 drivers/android/binder.c         Todd Kjos             2021-11-23  2486  	const void __user *user_buffer = (const void __user *)
d51c5e7a3791e9 drivers/android/binder.c         Todd Kjos             2021-11-23  2487  				(uintptr_t)tr->data.ptr.buffer;
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2488  
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2489  	e = binder_transaction_log_add(&binder_transaction_log);
d99c7333ab1c9d drivers/android/binder.c         Todd Kjos             2017-06-29  2490  	e->debug_id = t_debug_id;
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2491  	e->call_type = reply ? 2 : !!(tr->flags & TF_ONE_WAY);
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2492  	e->from_proc = proc->pid;
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2493  	e->from_thread = thread->pid;
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2494  	e->target_handle = tr->target.handle;
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2495  	e->data_size = tr->data_size;
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2496  	e->offsets_size = tr->offsets_size;
51d8a7eca67784 drivers/android/binder.c         Christian Brauner     2019-10-08  2497  	strscpy(e->context_name, proc->context->name, BINDERFS_MAX_NAME);
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2498  
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2499  	if (reply) {
0b89d69a962588 drivers/android/binder.c         Martijn Coenen        2017-06-29  2500  		binder_inner_proc_lock(proc);
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2501  		in_reply_to = thread->transaction_stack;
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2502  		if (in_reply_to == NULL) {
0b89d69a962588 drivers/android/binder.c         Martijn Coenen        2017-06-29  2503  			binder_inner_proc_unlock(proc);
56b468fc709b2b drivers/staging/android/binder.c Anmol Sarma           2012-10-30  2504  			binder_user_error("%d:%d got reply transaction with no transaction stack\n",
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2505  					  proc->pid, thread->pid);
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2506  			return_error = BR_FAILED_REPLY;
57ada2fb2250ea drivers/android/binder.c         Todd Kjos             2017-06-29  2507  			return_error_param = -EPROTO;
57ada2fb2250ea drivers/android/binder.c         Todd Kjos             2017-06-29  2508  			return_error_line = __LINE__;
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2509  			goto err_empty_call_stack;
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2510  		}
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2511  		if (in_reply_to->to_thread != thread) {
7a4408c6bd3eb1 drivers/android/binder.c         Todd Kjos             2017-06-29  2512  			spin_lock(&in_reply_to->lock);
56b468fc709b2b drivers/staging/android/binder.c Anmol Sarma           2012-10-30  2513  			binder_user_error("%d:%d got reply transaction with bad transaction stack, transaction %d has target %d:%d\n",
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2514  				proc->pid, thread->pid, in_reply_to->debug_id,
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2515  				in_reply_to->to_proc ?
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2516  				in_reply_to->to_proc->pid : 0,
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2517  				in_reply_to->to_thread ?
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2518  				in_reply_to->to_thread->pid : 0);
7a4408c6bd3eb1 drivers/android/binder.c         Todd Kjos             2017-06-29  2519  			spin_unlock(&in_reply_to->lock);
0b89d69a962588 drivers/android/binder.c         Martijn Coenen        2017-06-29  2520  			binder_inner_proc_unlock(proc);
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2521  			return_error = BR_FAILED_REPLY;
57ada2fb2250ea drivers/android/binder.c         Todd Kjos             2017-06-29  2522  			return_error_param = -EPROTO;
57ada2fb2250ea drivers/android/binder.c         Todd Kjos             2017-06-29  2523  			return_error_line = __LINE__;
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2524  			in_reply_to = NULL;
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2525  			goto err_bad_call_stack;
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2526  		}
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2527  		thread->transaction_stack = in_reply_to->to_parent;
0b89d69a962588 drivers/android/binder.c         Martijn Coenen        2017-06-29  2528  		binder_inner_proc_unlock(proc);
0b89d69a962588 drivers/android/binder.c         Martijn Coenen        2017-06-29  2529  		binder_set_nice(in_reply_to->saved_priority);
0b89d69a962588 drivers/android/binder.c         Martijn Coenen        2017-06-29  2530  		target_thread = binder_get_txn_from_and_acq_inner(in_reply_to);
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2531  		if (target_thread == NULL) {
324fa64cf41890 drivers/android/binder.c         Todd Kjos             2018-11-06  2532  			/* annotation for sparse */
324fa64cf41890 drivers/android/binder.c         Todd Kjos             2018-11-06  2533  			__release(&target_thread->proc->inner_lock);
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2534  			return_error = BR_DEAD_REPLY;
57ada2fb2250ea drivers/android/binder.c         Todd Kjos             2017-06-29  2535  			return_error_line = __LINE__;
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2536  			goto err_dead_binder;
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2537  		}
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2538  		if (target_thread->transaction_stack != in_reply_to) {
56b468fc709b2b drivers/staging/android/binder.c Anmol Sarma           2012-10-30  2539  			binder_user_error("%d:%d got reply transaction with bad target transaction stack %d, expected %d\n",
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2540  				proc->pid, thread->pid,
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2541  				target_thread->transaction_stack ?
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2542  				target_thread->transaction_stack->debug_id : 0,
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2543  				in_reply_to->debug_id);
0b89d69a962588 drivers/android/binder.c         Martijn Coenen        2017-06-29  2544  			binder_inner_proc_unlock(target_thread->proc);
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2545  			return_error = BR_FAILED_REPLY;
57ada2fb2250ea drivers/android/binder.c         Todd Kjos             2017-06-29  2546  			return_error_param = -EPROTO;
57ada2fb2250ea drivers/android/binder.c         Todd Kjos             2017-06-29  2547  			return_error_line = __LINE__;
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2548  			in_reply_to = NULL;
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2549  			target_thread = NULL;
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2550  			goto err_dead_binder;
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2551  		}
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2552  		target_proc = target_thread->proc;
7a4408c6bd3eb1 drivers/android/binder.c         Todd Kjos             2017-06-29  2553  		target_proc->tmp_ref++;
0b89d69a962588 drivers/android/binder.c         Martijn Coenen        2017-06-29  2554  		binder_inner_proc_unlock(target_thread->proc);
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2555  	} else {
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2556  		if (tr->target.handle) {
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2557  			struct binder_ref *ref;
10f62861b4a2f2 drivers/staging/android/binder.c Seunghun Lee          2014-05-01  2558  
eb34983ba170f2 drivers/android/binder.c         Todd Kjos             2017-06-29  2559  			/*
eb34983ba170f2 drivers/android/binder.c         Todd Kjos             2017-06-29  2560  			 * There must already be a strong ref
eb34983ba170f2 drivers/android/binder.c         Todd Kjos             2017-06-29  2561  			 * on this node. If so, do a strong
eb34983ba170f2 drivers/android/binder.c         Todd Kjos             2017-06-29  2562  			 * increment on the node to ensure it
eb34983ba170f2 drivers/android/binder.c         Todd Kjos             2017-06-29  2563  			 * stays alive until the transaction is
eb34983ba170f2 drivers/android/binder.c         Todd Kjos             2017-06-29  2564  			 * done.
eb34983ba170f2 drivers/android/binder.c         Todd Kjos             2017-06-29  2565  			 */
2c1838dc6817dd drivers/android/binder.c         Todd Kjos             2017-06-29  2566  			binder_proc_lock(proc);
2c1838dc6817dd drivers/android/binder.c         Todd Kjos             2017-06-29  2567  			ref = binder_get_ref_olocked(proc, tr->target.handle,
2c1838dc6817dd drivers/android/binder.c         Todd Kjos             2017-06-29  2568  						     true);
eb34983ba170f2 drivers/android/binder.c         Todd Kjos             2017-06-29  2569  			if (ref) {
512cf465ee01eb drivers/android/binder.c         Todd Kjos             2017-09-29  2570  				target_node = binder_get_node_refs_for_txn(
512cf465ee01eb drivers/android/binder.c         Todd Kjos             2017-09-29  2571  						ref->node, &target_proc,
512cf465ee01eb drivers/android/binder.c         Todd Kjos             2017-09-29  2572  						&return_error);
512cf465ee01eb drivers/android/binder.c         Todd Kjos             2017-09-29  2573  			} else {
1ae14df56cc3e8 drivers/android/binder.c         Ramji Jiyani          2021-08-02  2574  				binder_user_error("%d:%d got transaction to invalid handle, %u\n",
1ae14df56cc3e8 drivers/android/binder.c         Ramji Jiyani          2021-08-02  2575  						  proc->pid, thread->pid, tr->target.handle);
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2576  				return_error = BR_FAILED_REPLY;
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2577  			}
512cf465ee01eb drivers/android/binder.c         Todd Kjos             2017-09-29  2578  			binder_proc_unlock(proc);
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2579  		} else {
c44b1231ff1170 drivers/android/binder.c         Todd Kjos             2017-06-29  2580  			mutex_lock(&context->context_mgr_node_lock);
342e5c90b60134 drivers/android/binder.c         Martijn Coenen        2017-02-03  2581  			target_node = context->binder_context_mgr_node;
512cf465ee01eb drivers/android/binder.c         Todd Kjos             2017-09-29  2582  			if (target_node)
512cf465ee01eb drivers/android/binder.c         Todd Kjos             2017-09-29  2583  				target_node = binder_get_node_refs_for_txn(
512cf465ee01eb drivers/android/binder.c         Todd Kjos             2017-09-29  2584  						target_node, &target_proc,
512cf465ee01eb drivers/android/binder.c         Todd Kjos             2017-09-29  2585  						&return_error);
512cf465ee01eb drivers/android/binder.c         Todd Kjos             2017-09-29  2586  			else
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2587  				return_error = BR_DEAD_REPLY;
c44b1231ff1170 drivers/android/binder.c         Todd Kjos             2017-06-29  2588  			mutex_unlock(&context->context_mgr_node_lock);
49ed96943a8e0c drivers/android/binder.c         Hridya Valsaraju      2019-07-15  2589  			if (target_node && target_proc->pid == proc->pid) {
7aa135fcf26377 drivers/android/binder.c         Martijn Coenen        2018-03-28  2590  				binder_user_error("%d:%d got transaction to context manager from process owning it\n",
7aa135fcf26377 drivers/android/binder.c         Martijn Coenen        2018-03-28  2591  						  proc->pid, thread->pid);
7aa135fcf26377 drivers/android/binder.c         Martijn Coenen        2018-03-28  2592  				return_error = BR_FAILED_REPLY;
7aa135fcf26377 drivers/android/binder.c         Martijn Coenen        2018-03-28  2593  				return_error_param = -EINVAL;
7aa135fcf26377 drivers/android/binder.c         Martijn Coenen        2018-03-28  2594  				return_error_line = __LINE__;
7aa135fcf26377 drivers/android/binder.c         Martijn Coenen        2018-03-28  2595  				goto err_invalid_target_handle;
7aa135fcf26377 drivers/android/binder.c         Martijn Coenen        2018-03-28  2596  			}
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2597  		}
512cf465ee01eb drivers/android/binder.c         Todd Kjos             2017-09-29  2598  		if (!target_node) {
512cf465ee01eb drivers/android/binder.c         Todd Kjos             2017-09-29  2599  			/*
512cf465ee01eb drivers/android/binder.c         Todd Kjos             2017-09-29  2600  			 * return_error is set above
512cf465ee01eb drivers/android/binder.c         Todd Kjos             2017-09-29  2601  			 */
512cf465ee01eb drivers/android/binder.c         Todd Kjos             2017-09-29  2602  			return_error_param = -EINVAL;
57ada2fb2250ea drivers/android/binder.c         Todd Kjos             2017-06-29  2603  			return_error_line = __LINE__;
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2604  			goto err_dead_binder;
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2605  		}
512cf465ee01eb drivers/android/binder.c         Todd Kjos             2017-09-29  2606  		e->to_node = target_node->debug_id;
4b836a1426cb0f drivers/android/binder.c         Jann Horn             2020-07-27  2607  		if (WARN_ON(proc == target_proc)) {
4b836a1426cb0f drivers/android/binder.c         Jann Horn             2020-07-27  2608  			return_error = BR_FAILED_REPLY;
4b836a1426cb0f drivers/android/binder.c         Jann Horn             2020-07-27  2609  			return_error_param = -EINVAL;
4b836a1426cb0f drivers/android/binder.c         Jann Horn             2020-07-27  2610  			return_error_line = __LINE__;
4b836a1426cb0f drivers/android/binder.c         Jann Horn             2020-07-27  2611  			goto err_invalid_target_handle;
4b836a1426cb0f drivers/android/binder.c         Jann Horn             2020-07-27  2612  		}
52f88693378a58 drivers/android/binder.c         Todd Kjos             2021-10-12  2613  		if (security_binder_transaction(proc->cred,
52f88693378a58 drivers/android/binder.c         Todd Kjos             2021-10-12  2614  						target_proc->cred) < 0) {
79af73079d753b drivers/android/binder.c         Stephen Smalley       2015-01-21  2615  			return_error = BR_FAILED_REPLY;
57ada2fb2250ea drivers/android/binder.c         Todd Kjos             2017-06-29  2616  			return_error_param = -EPERM;
57ada2fb2250ea drivers/android/binder.c         Todd Kjos             2017-06-29  2617  			return_error_line = __LINE__;
79af73079d753b drivers/android/binder.c         Stephen Smalley       2015-01-21  2618  			goto err_invalid_target_handle;
79af73079d753b drivers/android/binder.c         Stephen Smalley       2015-01-21  2619  		}
0b89d69a962588 drivers/android/binder.c         Martijn Coenen        2017-06-29  2620  		binder_inner_proc_lock(proc);
44b73962cb25f1 drivers/android/binder.c         Sherry Yang           2018-08-13  2621  
44b73962cb25f1 drivers/android/binder.c         Sherry Yang           2018-08-13  2622  		w = list_first_entry_or_null(&thread->todo,
44b73962cb25f1 drivers/android/binder.c         Sherry Yang           2018-08-13  2623  					     struct binder_work, entry);
44b73962cb25f1 drivers/android/binder.c         Sherry Yang           2018-08-13  2624  		if (!(tr->flags & TF_ONE_WAY) && w &&
44b73962cb25f1 drivers/android/binder.c         Sherry Yang           2018-08-13  2625  		    w->type == BINDER_WORK_TRANSACTION) {
44b73962cb25f1 drivers/android/binder.c         Sherry Yang           2018-08-13  2626  			/*
44b73962cb25f1 drivers/android/binder.c         Sherry Yang           2018-08-13  2627  			 * Do not allow new outgoing transaction from a
44b73962cb25f1 drivers/android/binder.c         Sherry Yang           2018-08-13  2628  			 * thread that has a transaction at the head of
44b73962cb25f1 drivers/android/binder.c         Sherry Yang           2018-08-13  2629  			 * its todo list. Only need to check the head
44b73962cb25f1 drivers/android/binder.c         Sherry Yang           2018-08-13  2630  			 * because binder_select_thread_ilocked picks a
44b73962cb25f1 drivers/android/binder.c         Sherry Yang           2018-08-13  2631  			 * thread from proc->waiting_threads to enqueue
44b73962cb25f1 drivers/android/binder.c         Sherry Yang           2018-08-13  2632  			 * the transaction, and nothing is queued to the
44b73962cb25f1 drivers/android/binder.c         Sherry Yang           2018-08-13  2633  			 * todo list while the thread is on waiting_threads.
44b73962cb25f1 drivers/android/binder.c         Sherry Yang           2018-08-13  2634  			 */
44b73962cb25f1 drivers/android/binder.c         Sherry Yang           2018-08-13  2635  			binder_user_error("%d:%d new transaction not allowed when there is a transaction on thread todo\n",
44b73962cb25f1 drivers/android/binder.c         Sherry Yang           2018-08-13  2636  					  proc->pid, thread->pid);
44b73962cb25f1 drivers/android/binder.c         Sherry Yang           2018-08-13  2637  			binder_inner_proc_unlock(proc);
44b73962cb25f1 drivers/android/binder.c         Sherry Yang           2018-08-13  2638  			return_error = BR_FAILED_REPLY;
44b73962cb25f1 drivers/android/binder.c         Sherry Yang           2018-08-13  2639  			return_error_param = -EPROTO;
44b73962cb25f1 drivers/android/binder.c         Sherry Yang           2018-08-13  2640  			return_error_line = __LINE__;
44b73962cb25f1 drivers/android/binder.c         Sherry Yang           2018-08-13  2641  			goto err_bad_todo_list;
44b73962cb25f1 drivers/android/binder.c         Sherry Yang           2018-08-13  2642  		}
44b73962cb25f1 drivers/android/binder.c         Sherry Yang           2018-08-13  2643  
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2644  		if (!(tr->flags & TF_ONE_WAY) && thread->transaction_stack) {
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2645  			struct binder_transaction *tmp;
10f62861b4a2f2 drivers/staging/android/binder.c Seunghun Lee          2014-05-01  2646  
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2647  			tmp = thread->transaction_stack;
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2648  			if (tmp->to_thread != thread) {
7a4408c6bd3eb1 drivers/android/binder.c         Todd Kjos             2017-06-29  2649  				spin_lock(&tmp->lock);
56b468fc709b2b drivers/staging/android/binder.c Anmol Sarma           2012-10-30  2650  				binder_user_error("%d:%d got new transaction with bad transaction stack, transaction %d has target %d:%d\n",
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2651  					proc->pid, thread->pid, tmp->debug_id,
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2652  					tmp->to_proc ? tmp->to_proc->pid : 0,
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2653  					tmp->to_thread ?
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2654  					tmp->to_thread->pid : 0);
7a4408c6bd3eb1 drivers/android/binder.c         Todd Kjos             2017-06-29  2655  				spin_unlock(&tmp->lock);
0b89d69a962588 drivers/android/binder.c         Martijn Coenen        2017-06-29  2656  				binder_inner_proc_unlock(proc);
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2657  				return_error = BR_FAILED_REPLY;
57ada2fb2250ea drivers/android/binder.c         Todd Kjos             2017-06-29  2658  				return_error_param = -EPROTO;
57ada2fb2250ea drivers/android/binder.c         Todd Kjos             2017-06-29  2659  				return_error_line = __LINE__;
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2660  				goto err_bad_call_stack;
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2661  			}
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2662  			while (tmp) {
7a4408c6bd3eb1 drivers/android/binder.c         Todd Kjos             2017-06-29  2663  				struct binder_thread *from;
7a4408c6bd3eb1 drivers/android/binder.c         Todd Kjos             2017-06-29  2664  
7a4408c6bd3eb1 drivers/android/binder.c         Todd Kjos             2017-06-29  2665  				spin_lock(&tmp->lock);
7a4408c6bd3eb1 drivers/android/binder.c         Todd Kjos             2017-06-29  2666  				from = tmp->from;
7a4408c6bd3eb1 drivers/android/binder.c         Todd Kjos             2017-06-29  2667  				if (from && from->proc == target_proc) {
7a4408c6bd3eb1 drivers/android/binder.c         Todd Kjos             2017-06-29  2668  					atomic_inc(&from->tmp_ref);
7a4408c6bd3eb1 drivers/android/binder.c         Todd Kjos             2017-06-29  2669  					target_thread = from;
7a4408c6bd3eb1 drivers/android/binder.c         Todd Kjos             2017-06-29  2670  					spin_unlock(&tmp->lock);
7a4408c6bd3eb1 drivers/android/binder.c         Todd Kjos             2017-06-29  2671  					break;
7a4408c6bd3eb1 drivers/android/binder.c         Todd Kjos             2017-06-29  2672  				}
7a4408c6bd3eb1 drivers/android/binder.c         Todd Kjos             2017-06-29  2673  				spin_unlock(&tmp->lock);
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2674  				tmp = tmp->from_parent;
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2675  			}
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2676  		}
0b89d69a962588 drivers/android/binder.c         Martijn Coenen        2017-06-29  2677  		binder_inner_proc_unlock(proc);
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2678  	}
408c68b17aea2f drivers/android/binder.c         Martijn Coenen        2017-08-31  2679  	if (target_thread)
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2680  		e->to_thread = target_thread->pid;
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2681  	e->to_proc = target_proc->pid;
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2682  
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2683  	/* TODO: reuse incoming transaction for reply */
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2684  	t = kzalloc(sizeof(*t), GFP_KERNEL);
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2685  	if (t == NULL) {
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2686  		return_error = BR_FAILED_REPLY;
57ada2fb2250ea drivers/android/binder.c         Todd Kjos             2017-06-29  2687  		return_error_param = -ENOMEM;
57ada2fb2250ea drivers/android/binder.c         Todd Kjos             2017-06-29  2688  		return_error_line = __LINE__;
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2689  		goto err_alloc_t_failed;
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2690  	}
44d8047f1d87ad drivers/android/binder.c         Todd Kjos             2018-08-28  2691  	INIT_LIST_HEAD(&t->fd_fixups);
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2692  	binder_stats_created(BINDER_STAT_TRANSACTION);
7a4408c6bd3eb1 drivers/android/binder.c         Todd Kjos             2017-06-29  2693  	spin_lock_init(&t->lock);
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2694  
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2695  	tcomplete = kzalloc(sizeof(*tcomplete), GFP_KERNEL);
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2696  	if (tcomplete == NULL) {
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2697  		return_error = BR_FAILED_REPLY;
57ada2fb2250ea drivers/android/binder.c         Todd Kjos             2017-06-29  2698  		return_error_param = -ENOMEM;
57ada2fb2250ea drivers/android/binder.c         Todd Kjos             2017-06-29  2699  		return_error_line = __LINE__;
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2700  		goto err_alloc_tcomplete_failed;
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2701  	}
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2702  	binder_stats_created(BINDER_STAT_TRANSACTION_COMPLETE);
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2703  
d99c7333ab1c9d drivers/android/binder.c         Todd Kjos             2017-06-29  2704  	t->debug_id = t_debug_id;
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2705  
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2706  	if (reply)
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30 @2707  		binder_debug(BINDER_DEBUG_TRANSACTION,
4bfac80af3a63f drivers/android/binder.c         Martijn Coenen        2017-02-03  2708  			     "%d:%d BC_REPLY %d -> %d:%d, data %016llx-%016llx size %lld-%lld-%lld\n",
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2709  			     proc->pid, thread->pid, t->debug_id,
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2710  			     target_proc->pid, target_thread->pid,
d51c5e7a3791e9 drivers/android/binder.c         Todd Kjos             2021-11-23  2711  			     (u64)user_buffer,
da49889deb34d3 drivers/staging/android/binder.c Arve Hjønnevåg        2014-02-21  2712  			     (u64)tr->data.ptr.offsets,
4bfac80af3a63f drivers/android/binder.c         Martijn Coenen        2017-02-03  2713  			     (u64)tr->data_size, (u64)tr->offsets_size,
4bfac80af3a63f drivers/android/binder.c         Martijn Coenen        2017-02-03  2714  			     (u64)extra_buffers_size);
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2715  	else
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2716  		binder_debug(BINDER_DEBUG_TRANSACTION,
4bfac80af3a63f drivers/android/binder.c         Martijn Coenen        2017-02-03  2717  			     "%d:%d BC_TRANSACTION %d -> %d - node %d, data %016llx-%016llx size %lld-%lld-%lld\n",
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2718  			     proc->pid, thread->pid, t->debug_id,
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2719  			     target_proc->pid, target_node->debug_id,
d51c5e7a3791e9 drivers/android/binder.c         Todd Kjos             2021-11-23  2720  			     (u64)user_buffer,
da49889deb34d3 drivers/staging/android/binder.c Arve Hjønnevåg        2014-02-21  2721  			     (u64)tr->data.ptr.offsets,
4bfac80af3a63f drivers/android/binder.c         Martijn Coenen        2017-02-03  2722  			     (u64)tr->data_size, (u64)tr->offsets_size,
4bfac80af3a63f drivers/android/binder.c         Martijn Coenen        2017-02-03  2723  			     (u64)extra_buffers_size);
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2724  
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2725  	if (!reply && !(tr->flags & TF_ONE_WAY))
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2726  		t->from = thread;
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2727  	else
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2728  		t->from = NULL;
29bc22ac5e5bc6 drivers/android/binder.c         Todd Kjos             2021-10-12  2729  	t->sender_euid = proc->cred->euid;
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2730  	t->to_proc = target_proc;
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2731  	t->to_thread = target_thread;
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2732  	t->code = tr->code;
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2733  	t->flags = tr->flags;
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2734  	t->priority = task_nice(current);
975a1ac9a9fe65 drivers/staging/android/binder.c Arve Hjønnevåg        2012-10-16  2735  
ec74136ded792d drivers/android/binder.c         Todd Kjos             2019-01-14  2736  	if (target_node && target_node->txn_security_ctx) {
ec74136ded792d drivers/android/binder.c         Todd Kjos             2019-01-14  2737  		u32 secid;
0b0509508beff6 drivers/android/binder.c         Todd Kjos             2019-04-24  2738  		size_t added_size;
ec74136ded792d drivers/android/binder.c         Todd Kjos             2019-01-14  2739  
4d5b5539742d25 drivers/android/binder.c         Todd Kjos             2021-10-12  2740  		security_cred_getsecid(proc->cred, &secid);
ec74136ded792d drivers/android/binder.c         Todd Kjos             2019-01-14  2741  		ret = security_secid_to_secctx(secid, &secctx, &secctx_sz);
ec74136ded792d drivers/android/binder.c         Todd Kjos             2019-01-14  2742  		if (ret) {
ec74136ded792d drivers/android/binder.c         Todd Kjos             2019-01-14  2743  			return_error = BR_FAILED_REPLY;
ec74136ded792d drivers/android/binder.c         Todd Kjos             2019-01-14  2744  			return_error_param = ret;
ec74136ded792d drivers/android/binder.c         Todd Kjos             2019-01-14  2745  			return_error_line = __LINE__;
ec74136ded792d drivers/android/binder.c         Todd Kjos             2019-01-14  2746  			goto err_get_secctx_failed;
ec74136ded792d drivers/android/binder.c         Todd Kjos             2019-01-14  2747  		}
0b0509508beff6 drivers/android/binder.c         Todd Kjos             2019-04-24  2748  		added_size = ALIGN(secctx_sz, sizeof(u64));
0b0509508beff6 drivers/android/binder.c         Todd Kjos             2019-04-24  2749  		extra_buffers_size += added_size;
0b0509508beff6 drivers/android/binder.c         Todd Kjos             2019-04-24  2750  		if (extra_buffers_size < added_size) {
0b0509508beff6 drivers/android/binder.c         Todd Kjos             2019-04-24  2751  			/* integer overflow of extra_buffers_size */
0b0509508beff6 drivers/android/binder.c         Todd Kjos             2019-04-24  2752  			return_error = BR_FAILED_REPLY;
88f6c77927e4ae drivers/android/binder.c         Zhang Qilong          2020-10-26  2753  			return_error_param = -EINVAL;
0b0509508beff6 drivers/android/binder.c         Todd Kjos             2019-04-24  2754  			return_error_line = __LINE__;
0b0509508beff6 drivers/android/binder.c         Todd Kjos             2019-04-24  2755  			goto err_bad_extra_size;
0b0509508beff6 drivers/android/binder.c         Todd Kjos             2019-04-24  2756  		}
ec74136ded792d drivers/android/binder.c         Todd Kjos             2019-01-14  2757  	}
ec74136ded792d drivers/android/binder.c         Todd Kjos             2019-01-14  2758  
975a1ac9a9fe65 drivers/staging/android/binder.c Arve Hjønnevåg        2012-10-16  2759  	trace_binder_transaction(reply, t, target_node);
975a1ac9a9fe65 drivers/staging/android/binder.c Arve Hjønnevåg        2012-10-16  2760  
19c987241ca121 drivers/android/binder.c         Todd Kjos             2017-06-29  2761  	t->buffer = binder_alloc_new_buf(&target_proc->alloc, tr->data_size,
4bfac80af3a63f drivers/android/binder.c         Martijn Coenen        2017-02-03  2762  		tr->offsets_size, extra_buffers_size,
261e7818f06ec5 drivers/android/binder.c         Martijn Coenen        2020-08-21  2763  		!reply && (t->flags & TF_ONE_WAY), current->tgid);
57ada2fb2250ea drivers/android/binder.c         Todd Kjos             2017-06-29  2764  	if (IS_ERR(t->buffer)) {
57ada2fb2250ea drivers/android/binder.c         Todd Kjos             2017-06-29  2765  		/*
57ada2fb2250ea drivers/android/binder.c         Todd Kjos             2017-06-29  2766  		 * -ESRCH indicates VMA cleared. The target is dying.
57ada2fb2250ea drivers/android/binder.c         Todd Kjos             2017-06-29  2767  		 */
57ada2fb2250ea drivers/android/binder.c         Todd Kjos             2017-06-29  2768  		return_error_param = PTR_ERR(t->buffer);
57ada2fb2250ea drivers/android/binder.c         Todd Kjos             2017-06-29  2769  		return_error = return_error_param == -ESRCH ?
57ada2fb2250ea drivers/android/binder.c         Todd Kjos             2017-06-29  2770  			BR_DEAD_REPLY : BR_FAILED_REPLY;
57ada2fb2250ea drivers/android/binder.c         Todd Kjos             2017-06-29  2771  		return_error_line = __LINE__;
57ada2fb2250ea drivers/android/binder.c         Todd Kjos             2017-06-29  2772  		t->buffer = NULL;
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2773  		goto err_binder_alloc_buf_failed;
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2774  	}
ec74136ded792d drivers/android/binder.c         Todd Kjos             2019-01-14  2775  	if (secctx) {
bb4a2e48d5100e drivers/android/binder.c         Todd Kjos             2019-06-28  2776  		int err;
ec74136ded792d drivers/android/binder.c         Todd Kjos             2019-01-14  2777  		size_t buf_offset = ALIGN(tr->data_size, sizeof(void *)) +
ec74136ded792d drivers/android/binder.c         Todd Kjos             2019-01-14  2778  				    ALIGN(tr->offsets_size, sizeof(void *)) +
ec74136ded792d drivers/android/binder.c         Todd Kjos             2019-01-14  2779  				    ALIGN(extra_buffers_size, sizeof(void *)) -
ec74136ded792d drivers/android/binder.c         Todd Kjos             2019-01-14  2780  				    ALIGN(secctx_sz, sizeof(u64));
ec74136ded792d drivers/android/binder.c         Todd Kjos             2019-01-14  2781  
bde4a19fc04f5f drivers/android/binder.c         Todd Kjos             2019-02-08  2782  		t->security_ctx = (uintptr_t)t->buffer->user_data + buf_offset;
bb4a2e48d5100e drivers/android/binder.c         Todd Kjos             2019-06-28  2783  		err = binder_alloc_copy_to_buffer(&target_proc->alloc,
8ced0c6231ead2 drivers/android/binder.c         Todd Kjos             2019-02-08  2784  						  t->buffer, buf_offset,
8ced0c6231ead2 drivers/android/binder.c         Todd Kjos             2019-02-08  2785  						  secctx, secctx_sz);
bb4a2e48d5100e drivers/android/binder.c         Todd Kjos             2019-06-28  2786  		if (err) {
bb4a2e48d5100e drivers/android/binder.c         Todd Kjos             2019-06-28  2787  			t->security_ctx = 0;
bb4a2e48d5100e drivers/android/binder.c         Todd Kjos             2019-06-28  2788  			WARN_ON(1);
bb4a2e48d5100e drivers/android/binder.c         Todd Kjos             2019-06-28  2789  		}
ec74136ded792d drivers/android/binder.c         Todd Kjos             2019-01-14  2790  		security_release_secctx(secctx, secctx_sz);
ec74136ded792d drivers/android/binder.c         Todd Kjos             2019-01-14  2791  		secctx = NULL;
ec74136ded792d drivers/android/binder.c         Todd Kjos             2019-01-14  2792  	}
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2793  	t->buffer->debug_id = t->debug_id;
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2794  	t->buffer->transaction = t;
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2795  	t->buffer->target_node = target_node;
0f966cba95c780 drivers/android/binder.c         Todd Kjos             2020-11-20  2796  	t->buffer->clear_on_free = !!(t->flags & TF_CLEAR_BUF);
975a1ac9a9fe65 drivers/staging/android/binder.c Arve Hjønnevåg        2012-10-16  2797  	trace_binder_transaction_alloc_buf(t->buffer);
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2798  
1a7c3d9bb7a926 drivers/android/binder.c         Todd Kjos             2019-02-08  2799  	if (binder_alloc_copy_user_to_buffer(
1a7c3d9bb7a926 drivers/android/binder.c         Todd Kjos             2019-02-08  2800  				&target_proc->alloc,
1a7c3d9bb7a926 drivers/android/binder.c         Todd Kjos             2019-02-08  2801  				t->buffer,
1a7c3d9bb7a926 drivers/android/binder.c         Todd Kjos             2019-02-08  2802  				ALIGN(tr->data_size, sizeof(void *)),
1a7c3d9bb7a926 drivers/android/binder.c         Todd Kjos             2019-02-08  2803  				(const void __user *)
1a7c3d9bb7a926 drivers/android/binder.c         Todd Kjos             2019-02-08  2804  					(uintptr_t)tr->data.ptr.offsets,
1a7c3d9bb7a926 drivers/android/binder.c         Todd Kjos             2019-02-08  2805  				tr->offsets_size)) {
56b468fc709b2b drivers/staging/android/binder.c Anmol Sarma           2012-10-30  2806  		binder_user_error("%d:%d got transaction with invalid offsets ptr\n",
56b468fc709b2b drivers/staging/android/binder.c Anmol Sarma           2012-10-30  2807  				proc->pid, thread->pid);
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2808  		return_error = BR_FAILED_REPLY;
57ada2fb2250ea drivers/android/binder.c         Todd Kjos             2017-06-29  2809  		return_error_param = -EFAULT;
57ada2fb2250ea drivers/android/binder.c         Todd Kjos             2017-06-29  2810  		return_error_line = __LINE__;
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2811  		goto err_copy_data_failed;
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2812  	}
da49889deb34d3 drivers/staging/android/binder.c Arve Hjønnevåg        2014-02-21  2813  	if (!IS_ALIGNED(tr->offsets_size, sizeof(binder_size_t))) {
da49889deb34d3 drivers/staging/android/binder.c Arve Hjønnevåg        2014-02-21  2814  		binder_user_error("%d:%d got transaction with invalid offsets size, %lld\n",
da49889deb34d3 drivers/staging/android/binder.c Arve Hjønnevåg        2014-02-21  2815  				proc->pid, thread->pid, (u64)tr->offsets_size);
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2816  		return_error = BR_FAILED_REPLY;
57ada2fb2250ea drivers/android/binder.c         Todd Kjos             2017-06-29  2817  		return_error_param = -EINVAL;
57ada2fb2250ea drivers/android/binder.c         Todd Kjos             2017-06-29  2818  		return_error_line = __LINE__;
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2819  		goto err_bad_offset;
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2820  	}
7980240b6d63e0 drivers/android/binder.c         Martijn Coenen        2017-02-03  2821  	if (!IS_ALIGNED(extra_buffers_size, sizeof(u64))) {
7980240b6d63e0 drivers/android/binder.c         Martijn Coenen        2017-02-03  2822  		binder_user_error("%d:%d got transaction with unaligned buffers size, %lld\n",
7980240b6d63e0 drivers/android/binder.c         Martijn Coenen        2017-02-03  2823  				  proc->pid, thread->pid,
7980240b6d63e0 drivers/android/binder.c         Martijn Coenen        2017-02-03  2824  				  (u64)extra_buffers_size);
7980240b6d63e0 drivers/android/binder.c         Martijn Coenen        2017-02-03  2825  		return_error = BR_FAILED_REPLY;
57ada2fb2250ea drivers/android/binder.c         Todd Kjos             2017-06-29  2826  		return_error_param = -EINVAL;
57ada2fb2250ea drivers/android/binder.c         Todd Kjos             2017-06-29  2827  		return_error_line = __LINE__;
7980240b6d63e0 drivers/android/binder.c         Martijn Coenen        2017-02-03  2828  		goto err_bad_offset;
7980240b6d63e0 drivers/android/binder.c         Martijn Coenen        2017-02-03  2829  	}
bde4a19fc04f5f drivers/android/binder.c         Todd Kjos             2019-02-08  2830  	off_start_offset = ALIGN(tr->data_size, sizeof(void *));
bde4a19fc04f5f drivers/android/binder.c         Todd Kjos             2019-02-08  2831  	buffer_offset = off_start_offset;
bde4a19fc04f5f drivers/android/binder.c         Todd Kjos             2019-02-08  2832  	off_end_offset = off_start_offset + tr->offsets_size;
bde4a19fc04f5f drivers/android/binder.c         Todd Kjos             2019-02-08  2833  	sg_buf_offset = ALIGN(off_end_offset, sizeof(void *));
a56587065094fd drivers/android/binder.c         Martijn Coenen        2019-07-09  2834  	sg_buf_end_offset = sg_buf_offset + extra_buffers_size -
a56587065094fd drivers/android/binder.c         Martijn Coenen        2019-07-09  2835  		ALIGN(secctx_sz, sizeof(u64));
212265e5ad726e drivers/android/binder.c         Arve Hjønnevåg        2016-02-09  2836  	off_min = 0;
bde4a19fc04f5f drivers/android/binder.c         Todd Kjos             2019-02-08  2837  	for (buffer_offset = off_start_offset; buffer_offset < off_end_offset;
bde4a19fc04f5f drivers/android/binder.c         Todd Kjos             2019-02-08  2838  	     buffer_offset += sizeof(binder_size_t)) {
feba3900cabb8e drivers/android/binder.c         Martijn Coenen        2017-02-03  2839  		struct binder_object_header *hdr;
8ced0c6231ead2 drivers/android/binder.c         Todd Kjos             2019-02-08  2840  		size_t object_size;
7a67a39320dfba drivers/android/binder.c         Todd Kjos             2019-02-08  2841  		struct binder_object object;
8ced0c6231ead2 drivers/android/binder.c         Todd Kjos             2019-02-08  2842  		binder_size_t object_offset;
d51c5e7a3791e9 drivers/android/binder.c         Todd Kjos             2021-11-23  2843  		binder_size_t copy_size;
10f62861b4a2f2 drivers/staging/android/binder.c Seunghun Lee          2014-05-01  2844  
bb4a2e48d5100e drivers/android/binder.c         Todd Kjos             2019-06-28  2845  		if (binder_alloc_copy_from_buffer(&target_proc->alloc,
8ced0c6231ead2 drivers/android/binder.c         Todd Kjos             2019-02-08  2846  						  &object_offset,
8ced0c6231ead2 drivers/android/binder.c         Todd Kjos             2019-02-08  2847  						  t->buffer,
8ced0c6231ead2 drivers/android/binder.c         Todd Kjos             2019-02-08  2848  						  buffer_offset,
bb4a2e48d5100e drivers/android/binder.c         Todd Kjos             2019-06-28  2849  						  sizeof(object_offset))) {
bb4a2e48d5100e drivers/android/binder.c         Todd Kjos             2019-06-28  2850  			return_error = BR_FAILED_REPLY;
bb4a2e48d5100e drivers/android/binder.c         Todd Kjos             2019-06-28  2851  			return_error_param = -EINVAL;
bb4a2e48d5100e drivers/android/binder.c         Todd Kjos             2019-06-28  2852  			return_error_line = __LINE__;
bb4a2e48d5100e drivers/android/binder.c         Todd Kjos             2019-06-28  2853  			goto err_bad_offset;
bb4a2e48d5100e drivers/android/binder.c         Todd Kjos             2019-06-28  2854  		}
d51c5e7a3791e9 drivers/android/binder.c         Todd Kjos             2021-11-23  2855  
d51c5e7a3791e9 drivers/android/binder.c         Todd Kjos             2021-11-23  2856  		/*
d51c5e7a3791e9 drivers/android/binder.c         Todd Kjos             2021-11-23  2857  		 * Copy the source user buffer up to the next object
d51c5e7a3791e9 drivers/android/binder.c         Todd Kjos             2021-11-23  2858  		 * that will be processed.
d51c5e7a3791e9 drivers/android/binder.c         Todd Kjos             2021-11-23  2859  		 */
d51c5e7a3791e9 drivers/android/binder.c         Todd Kjos             2021-11-23  2860  		copy_size = object_offset - user_offset;
d51c5e7a3791e9 drivers/android/binder.c         Todd Kjos             2021-11-23  2861  		if (copy_size && (user_offset > object_offset ||
d51c5e7a3791e9 drivers/android/binder.c         Todd Kjos             2021-11-23  2862  				binder_alloc_copy_user_to_buffer(
d51c5e7a3791e9 drivers/android/binder.c         Todd Kjos             2021-11-23  2863  					&target_proc->alloc,
d51c5e7a3791e9 drivers/android/binder.c         Todd Kjos             2021-11-23  2864  					t->buffer, user_offset,
d51c5e7a3791e9 drivers/android/binder.c         Todd Kjos             2021-11-23  2865  					user_buffer + user_offset,
d51c5e7a3791e9 drivers/android/binder.c         Todd Kjos             2021-11-23  2866  					copy_size))) {
d51c5e7a3791e9 drivers/android/binder.c         Todd Kjos             2021-11-23  2867  			binder_user_error("%d:%d got transaction with invalid data ptr\n",
d51c5e7a3791e9 drivers/android/binder.c         Todd Kjos             2021-11-23  2868  					proc->pid, thread->pid);
d51c5e7a3791e9 drivers/android/binder.c         Todd Kjos             2021-11-23  2869  			return_error = BR_FAILED_REPLY;
d51c5e7a3791e9 drivers/android/binder.c         Todd Kjos             2021-11-23  2870  			return_error_param = -EFAULT;
d51c5e7a3791e9 drivers/android/binder.c         Todd Kjos             2021-11-23  2871  			return_error_line = __LINE__;
d51c5e7a3791e9 drivers/android/binder.c         Todd Kjos             2021-11-23  2872  			goto err_copy_data_failed;
d51c5e7a3791e9 drivers/android/binder.c         Todd Kjos             2021-11-23  2873  		}
d51c5e7a3791e9 drivers/android/binder.c         Todd Kjos             2021-11-23  2874  		object_size = binder_get_object(target_proc, user_buffer,
d51c5e7a3791e9 drivers/android/binder.c         Todd Kjos             2021-11-23  2875  				t->buffer, object_offset, &object);
8ced0c6231ead2 drivers/android/binder.c         Todd Kjos             2019-02-08  2876  		if (object_size == 0 || object_offset < off_min) {
feba3900cabb8e drivers/android/binder.c         Martijn Coenen        2017-02-03  2877  			binder_user_error("%d:%d got transaction with invalid offset (%lld, min %lld max %lld) or object.\n",
8ced0c6231ead2 drivers/android/binder.c         Todd Kjos             2019-02-08  2878  					  proc->pid, thread->pid,
8ced0c6231ead2 drivers/android/binder.c         Todd Kjos             2019-02-08  2879  					  (u64)object_offset,
212265e5ad726e drivers/android/binder.c         Arve Hjønnevåg        2016-02-09  2880  					  (u64)off_min,
feba3900cabb8e drivers/android/binder.c         Martijn Coenen        2017-02-03  2881  					  (u64)t->buffer->data_size);
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2882  			return_error = BR_FAILED_REPLY;
57ada2fb2250ea drivers/android/binder.c         Todd Kjos             2017-06-29  2883  			return_error_param = -EINVAL;
57ada2fb2250ea drivers/android/binder.c         Todd Kjos             2017-06-29  2884  			return_error_line = __LINE__;
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2885  			goto err_bad_offset;
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2886  		}
d51c5e7a3791e9 drivers/android/binder.c         Todd Kjos             2021-11-23  2887  		/*
d51c5e7a3791e9 drivers/android/binder.c         Todd Kjos             2021-11-23  2888  		 * Set offset to the next buffer fragment to be
d51c5e7a3791e9 drivers/android/binder.c         Todd Kjos             2021-11-23  2889  		 * copied
d51c5e7a3791e9 drivers/android/binder.c         Todd Kjos             2021-11-23  2890  		 */
d51c5e7a3791e9 drivers/android/binder.c         Todd Kjos             2021-11-23  2891  		user_offset = object_offset + object_size;
feba3900cabb8e drivers/android/binder.c         Martijn Coenen        2017-02-03  2892  
7a67a39320dfba drivers/android/binder.c         Todd Kjos             2019-02-08  2893  		hdr = &object.hdr;
8ced0c6231ead2 drivers/android/binder.c         Todd Kjos             2019-02-08  2894  		off_min = object_offset + object_size;
feba3900cabb8e drivers/android/binder.c         Martijn Coenen        2017-02-03  2895  		switch (hdr->type) {
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2896  		case BINDER_TYPE_BINDER:
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2897  		case BINDER_TYPE_WEAK_BINDER: {
feba3900cabb8e drivers/android/binder.c         Martijn Coenen        2017-02-03  2898  			struct flat_binder_object *fp;
10f62861b4a2f2 drivers/staging/android/binder.c Seunghun Lee          2014-05-01  2899  
feba3900cabb8e drivers/android/binder.c         Martijn Coenen        2017-02-03  2900  			fp = to_flat_binder_object(hdr);
a056af42032e56 drivers/android/binder.c         Martijn Coenen        2017-02-03  2901  			ret = binder_translate_binder(fp, t, thread);
bb4a2e48d5100e drivers/android/binder.c         Todd Kjos             2019-06-28  2902  
bb4a2e48d5100e drivers/android/binder.c         Todd Kjos             2019-06-28  2903  			if (ret < 0 ||
bb4a2e48d5100e drivers/android/binder.c         Todd Kjos             2019-06-28  2904  			    binder_alloc_copy_to_buffer(&target_proc->alloc,
bb4a2e48d5100e drivers/android/binder.c         Todd Kjos             2019-06-28  2905  							t->buffer,
bb4a2e48d5100e drivers/android/binder.c         Todd Kjos             2019-06-28  2906  							object_offset,
bb4a2e48d5100e drivers/android/binder.c         Todd Kjos             2019-06-28  2907  							fp, sizeof(*fp))) {
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2908  				return_error = BR_FAILED_REPLY;
57ada2fb2250ea drivers/android/binder.c         Todd Kjos             2017-06-29  2909  				return_error_param = ret;
57ada2fb2250ea drivers/android/binder.c         Todd Kjos             2017-06-29  2910  				return_error_line = __LINE__;
a056af42032e56 drivers/android/binder.c         Martijn Coenen        2017-02-03  2911  				goto err_translate_failed;
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2912  			}
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2913  		} break;
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2914  		case BINDER_TYPE_HANDLE:
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2915  		case BINDER_TYPE_WEAK_HANDLE: {
feba3900cabb8e drivers/android/binder.c         Martijn Coenen        2017-02-03  2916  			struct flat_binder_object *fp;
0a3ffab93fe525 drivers/android/binder.c         Arve Hjønnevåg        2016-10-24  2917  
feba3900cabb8e drivers/android/binder.c         Martijn Coenen        2017-02-03  2918  			fp = to_flat_binder_object(hdr);
a056af42032e56 drivers/android/binder.c         Martijn Coenen        2017-02-03  2919  			ret = binder_translate_handle(fp, t, thread);
bb4a2e48d5100e drivers/android/binder.c         Todd Kjos             2019-06-28  2920  			if (ret < 0 ||
bb4a2e48d5100e drivers/android/binder.c         Todd Kjos             2019-06-28  2921  			    binder_alloc_copy_to_buffer(&target_proc->alloc,
bb4a2e48d5100e drivers/android/binder.c         Todd Kjos             2019-06-28  2922  							t->buffer,
bb4a2e48d5100e drivers/android/binder.c         Todd Kjos             2019-06-28  2923  							object_offset,
bb4a2e48d5100e drivers/android/binder.c         Todd Kjos             2019-06-28  2924  							fp, sizeof(*fp))) {
79af73079d753b drivers/android/binder.c         Stephen Smalley       2015-01-21  2925  				return_error = BR_FAILED_REPLY;
57ada2fb2250ea drivers/android/binder.c         Todd Kjos             2017-06-29  2926  				return_error_param = ret;
57ada2fb2250ea drivers/android/binder.c         Todd Kjos             2017-06-29  2927  				return_error_line = __LINE__;
a056af42032e56 drivers/android/binder.c         Martijn Coenen        2017-02-03  2928  				goto err_translate_failed;
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2929  			}
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2930  		} break;
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2931  
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2932  		case BINDER_TYPE_FD: {
feba3900cabb8e drivers/android/binder.c         Martijn Coenen        2017-02-03  2933  			struct binder_fd_object *fp = to_binder_fd_object(hdr);
8ced0c6231ead2 drivers/android/binder.c         Todd Kjos             2019-02-08  2934  			binder_size_t fd_offset = object_offset +
8ced0c6231ead2 drivers/android/binder.c         Todd Kjos             2019-02-08  2935  				(uintptr_t)&fp->fd - (uintptr_t)fp;
8ced0c6231ead2 drivers/android/binder.c         Todd Kjos             2019-02-08  2936  			int ret = binder_translate_fd(fp->fd, fd_offset, t,
8ced0c6231ead2 drivers/android/binder.c         Todd Kjos             2019-02-08  2937  						      thread, in_reply_to);
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2938  
bb4a2e48d5100e drivers/android/binder.c         Todd Kjos             2019-06-28  2939  			fp->pad_binder = 0;
bb4a2e48d5100e drivers/android/binder.c         Todd Kjos             2019-06-28  2940  			if (ret < 0 ||
bb4a2e48d5100e drivers/android/binder.c         Todd Kjos             2019-06-28  2941  			    binder_alloc_copy_to_buffer(&target_proc->alloc,
bb4a2e48d5100e drivers/android/binder.c         Todd Kjos             2019-06-28  2942  							t->buffer,
bb4a2e48d5100e drivers/android/binder.c         Todd Kjos             2019-06-28  2943  							object_offset,
bb4a2e48d5100e drivers/android/binder.c         Todd Kjos             2019-06-28  2944  							fp, sizeof(*fp))) {
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2945  				return_error = BR_FAILED_REPLY;
44d8047f1d87ad drivers/android/binder.c         Todd Kjos             2018-08-28  2946  				return_error_param = ret;
57ada2fb2250ea drivers/android/binder.c         Todd Kjos             2017-06-29  2947  				return_error_line = __LINE__;
a056af42032e56 drivers/android/binder.c         Martijn Coenen        2017-02-03  2948  				goto err_translate_failed;
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2949  			}
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  2950  		} break;
def95c73567dfa drivers/android/binder.c         Martijn Coenen        2017-02-03  2951  		case BINDER_TYPE_FDA: {
db6b0b810bf945 drivers/android/binder.c         Todd Kjos             2019-02-08  2952  			struct binder_object ptr_object;
db6b0b810bf945 drivers/android/binder.c         Todd Kjos             2019-02-08  2953  			binder_size_t parent_offset;
def95c73567dfa drivers/android/binder.c         Martijn Coenen        2017-02-03  2954  			struct binder_fd_array_object *fda =
def95c73567dfa drivers/android/binder.c         Martijn Coenen        2017-02-03  2955  				to_binder_fd_array_object(hdr);
16981742717b04 drivers/android/binder.c         Todd Kjos             2019-12-13  2956  			size_t num_valid = (buffer_offset - off_start_offset) /
bde4a19fc04f5f drivers/android/binder.c         Todd Kjos             2019-02-08  2957  						sizeof(binder_size_t);
def95c73567dfa drivers/android/binder.c         Martijn Coenen        2017-02-03  2958  			struct binder_buffer_object *parent =
db6b0b810bf945 drivers/android/binder.c         Todd Kjos             2019-02-08  2959  				binder_validate_ptr(target_proc, t->buffer,
db6b0b810bf945 drivers/android/binder.c         Todd Kjos             2019-02-08  2960  						    &ptr_object, fda->parent,
db6b0b810bf945 drivers/android/binder.c         Todd Kjos             2019-02-08  2961  						    off_start_offset,
db6b0b810bf945 drivers/android/binder.c         Todd Kjos             2019-02-08  2962  						    &parent_offset,
bde4a19fc04f5f drivers/android/binder.c         Todd Kjos             2019-02-08  2963  						    num_valid);
def95c73567dfa drivers/android/binder.c         Martijn Coenen        2017-02-03  2964  			if (!parent) {
def95c73567dfa drivers/android/binder.c         Martijn Coenen        2017-02-03  2965  				binder_user_error("%d:%d got transaction with invalid parent offset or type\n",
def95c73567dfa drivers/android/binder.c         Martijn Coenen        2017-02-03  2966  						  proc->pid, thread->pid);
def95c73567dfa drivers/android/binder.c         Martijn Coenen        2017-02-03  2967  				return_error = BR_FAILED_REPLY;
57ada2fb2250ea drivers/android/binder.c         Todd Kjos             2017-06-29  2968  				return_error_param = -EINVAL;
57ada2fb2250ea drivers/android/binder.c         Todd Kjos             2017-06-29  2969  				return_error_line = __LINE__;
def95c73567dfa drivers/android/binder.c         Martijn Coenen        2017-02-03  2970  				goto err_bad_parent;
def95c73567dfa drivers/android/binder.c         Martijn Coenen        2017-02-03  2971  			}
db6b0b810bf945 drivers/android/binder.c         Todd Kjos             2019-02-08  2972  			if (!binder_validate_fixup(target_proc, t->buffer,
db6b0b810bf945 drivers/android/binder.c         Todd Kjos             2019-02-08  2973  						   off_start_offset,
db6b0b810bf945 drivers/android/binder.c         Todd Kjos             2019-02-08  2974  						   parent_offset,
db6b0b810bf945 drivers/android/binder.c         Todd Kjos             2019-02-08  2975  						   fda->parent_offset,
db6b0b810bf945 drivers/android/binder.c         Todd Kjos             2019-02-08  2976  						   last_fixup_obj_off,
def95c73567dfa drivers/android/binder.c         Martijn Coenen        2017-02-03  2977  						   last_fixup_min_off)) {
def95c73567dfa drivers/android/binder.c         Martijn Coenen        2017-02-03  2978  				binder_user_error("%d:%d got transaction with out-of-order buffer fixup\n",
def95c73567dfa drivers/android/binder.c         Martijn Coenen        2017-02-03  2979  						  proc->pid, thread->pid);
def95c73567dfa drivers/android/binder.c         Martijn Coenen        2017-02-03  2980  				return_error = BR_FAILED_REPLY;
57ada2fb2250ea drivers/android/binder.c         Todd Kjos             2017-06-29  2981  				return_error_param = -EINVAL;
57ada2fb2250ea drivers/android/binder.c         Todd Kjos             2017-06-29  2982  				return_error_line = __LINE__;
def95c73567dfa drivers/android/binder.c         Martijn Coenen        2017-02-03  2983  				goto err_bad_parent;
def95c73567dfa drivers/android/binder.c         Martijn Coenen        2017-02-03  2984  			}
def95c73567dfa drivers/android/binder.c         Martijn Coenen        2017-02-03  2985  			ret = binder_translate_fd_array(fda, parent, t, thread,
def95c73567dfa drivers/android/binder.c         Martijn Coenen        2017-02-03  2986  							in_reply_to);
d51c5e7a3791e9 drivers/android/binder.c         Todd Kjos             2021-11-23  2987  			if (ret < 0 ||
d51c5e7a3791e9 drivers/android/binder.c         Todd Kjos             2021-11-23  2988  			    binder_alloc_copy_to_buffer(&target_proc->alloc,
d51c5e7a3791e9 drivers/android/binder.c         Todd Kjos             2021-11-23  2989  							t->buffer,
d51c5e7a3791e9 drivers/android/binder.c         Todd Kjos             2021-11-23  2990  							object_offset,
d51c5e7a3791e9 drivers/android/binder.c         Todd Kjos             2021-11-23  2991  							fda, sizeof(*fda))) {
def95c73567dfa drivers/android/binder.c         Martijn Coenen        2017-02-03  2992  				return_error = BR_FAILED_REPLY;
57ada2fb2250ea drivers/android/binder.c         Todd Kjos             2017-06-29  2993  				return_error_param = ret;
57ada2fb2250ea drivers/android/binder.c         Todd Kjos             2017-06-29  2994  				return_error_line = __LINE__;
def95c73567dfa drivers/android/binder.c         Martijn Coenen        2017-02-03  2995  				goto err_translate_failed;
def95c73567dfa drivers/android/binder.c         Martijn Coenen        2017-02-03  2996  			}
db6b0b810bf945 drivers/android/binder.c         Todd Kjos             2019-02-08  2997  			last_fixup_obj_off = parent_offset;
def95c73567dfa drivers/android/binder.c         Martijn Coenen        2017-02-03  2998  			last_fixup_min_off =
def95c73567dfa drivers/android/binder.c         Martijn Coenen        2017-02-03  2999  				fda->parent_offset + sizeof(u32) * fda->num_fds;
def95c73567dfa drivers/android/binder.c         Martijn Coenen        2017-02-03  3000  		} break;
7980240b6d63e0 drivers/android/binder.c         Martijn Coenen        2017-02-03  3001  		case BINDER_TYPE_PTR: {
7980240b6d63e0 drivers/android/binder.c         Martijn Coenen        2017-02-03  3002  			struct binder_buffer_object *bp =
7980240b6d63e0 drivers/android/binder.c         Martijn Coenen        2017-02-03  3003  				to_binder_buffer_object(hdr);
bde4a19fc04f5f drivers/android/binder.c         Todd Kjos             2019-02-08  3004  			size_t buf_left = sg_buf_end_offset - sg_buf_offset;
bde4a19fc04f5f drivers/android/binder.c         Todd Kjos             2019-02-08  3005  			size_t num_valid;
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  3006  
7980240b6d63e0 drivers/android/binder.c         Martijn Coenen        2017-02-03  3007  			if (bp->length > buf_left) {
7980240b6d63e0 drivers/android/binder.c         Martijn Coenen        2017-02-03  3008  				binder_user_error("%d:%d got transaction with too large buffer\n",
7980240b6d63e0 drivers/android/binder.c         Martijn Coenen        2017-02-03  3009  						  proc->pid, thread->pid);
7980240b6d63e0 drivers/android/binder.c         Martijn Coenen        2017-02-03  3010  				return_error = BR_FAILED_REPLY;
57ada2fb2250ea drivers/android/binder.c         Todd Kjos             2017-06-29  3011  				return_error_param = -EINVAL;
57ada2fb2250ea drivers/android/binder.c         Todd Kjos             2017-06-29  3012  				return_error_line = __LINE__;
7980240b6d63e0 drivers/android/binder.c         Martijn Coenen        2017-02-03  3013  				goto err_bad_offset;
7980240b6d63e0 drivers/android/binder.c         Martijn Coenen        2017-02-03  3014  			}
1a7c3d9bb7a926 drivers/android/binder.c         Todd Kjos             2019-02-08  3015  			if (binder_alloc_copy_user_to_buffer(
1a7c3d9bb7a926 drivers/android/binder.c         Todd Kjos             2019-02-08  3016  						&target_proc->alloc,
1a7c3d9bb7a926 drivers/android/binder.c         Todd Kjos             2019-02-08  3017  						t->buffer,
1a7c3d9bb7a926 drivers/android/binder.c         Todd Kjos             2019-02-08  3018  						sg_buf_offset,
1a7c3d9bb7a926 drivers/android/binder.c         Todd Kjos             2019-02-08  3019  						(const void __user *)
1a7c3d9bb7a926 drivers/android/binder.c         Todd Kjos             2019-02-08  3020  							(uintptr_t)bp->buffer,
1a7c3d9bb7a926 drivers/android/binder.c         Todd Kjos             2019-02-08  3021  						bp->length)) {
7980240b6d63e0 drivers/android/binder.c         Martijn Coenen        2017-02-03  3022  				binder_user_error("%d:%d got transaction with invalid offsets ptr\n",
7980240b6d63e0 drivers/android/binder.c         Martijn Coenen        2017-02-03  3023  						  proc->pid, thread->pid);
57ada2fb2250ea drivers/android/binder.c         Todd Kjos             2017-06-29  3024  				return_error_param = -EFAULT;
7980240b6d63e0 drivers/android/binder.c         Martijn Coenen        2017-02-03  3025  				return_error = BR_FAILED_REPLY;
57ada2fb2250ea drivers/android/binder.c         Todd Kjos             2017-06-29  3026  				return_error_line = __LINE__;
7980240b6d63e0 drivers/android/binder.c         Martijn Coenen        2017-02-03  3027  				goto err_copy_data_failed;
7980240b6d63e0 drivers/android/binder.c         Martijn Coenen        2017-02-03  3028  			}
7980240b6d63e0 drivers/android/binder.c         Martijn Coenen        2017-02-03  3029  			/* Fixup buffer pointer to target proc address space */
bde4a19fc04f5f drivers/android/binder.c         Todd Kjos             2019-02-08  3030  			bp->buffer = (uintptr_t)
bde4a19fc04f5f drivers/android/binder.c         Todd Kjos             2019-02-08  3031  				t->buffer->user_data + sg_buf_offset;
bde4a19fc04f5f drivers/android/binder.c         Todd Kjos             2019-02-08  3032  			sg_buf_offset += ALIGN(bp->length, sizeof(u64));
7980240b6d63e0 drivers/android/binder.c         Martijn Coenen        2017-02-03  3033  
16981742717b04 drivers/android/binder.c         Todd Kjos             2019-12-13  3034  			num_valid = (buffer_offset - off_start_offset) /
bde4a19fc04f5f drivers/android/binder.c         Todd Kjos             2019-02-08  3035  					sizeof(binder_size_t);
db6b0b810bf945 drivers/android/binder.c         Todd Kjos             2019-02-08  3036  			ret = binder_fixup_parent(t, thread, bp,
db6b0b810bf945 drivers/android/binder.c         Todd Kjos             2019-02-08  3037  						  off_start_offset,
bde4a19fc04f5f drivers/android/binder.c         Todd Kjos             2019-02-08  3038  						  num_valid,
db6b0b810bf945 drivers/android/binder.c         Todd Kjos             2019-02-08  3039  						  last_fixup_obj_off,
7980240b6d63e0 drivers/android/binder.c         Martijn Coenen        2017-02-03  3040  						  last_fixup_min_off);
bb4a2e48d5100e drivers/android/binder.c         Todd Kjos             2019-06-28  3041  			if (ret < 0 ||
bb4a2e48d5100e drivers/android/binder.c         Todd Kjos             2019-06-28  3042  			    binder_alloc_copy_to_buffer(&target_proc->alloc,
bb4a2e48d5100e drivers/android/binder.c         Todd Kjos             2019-06-28  3043  							t->buffer,
bb4a2e48d5100e drivers/android/binder.c         Todd Kjos             2019-06-28  3044  							object_offset,
bb4a2e48d5100e drivers/android/binder.c         Todd Kjos             2019-06-28  3045  							bp, sizeof(*bp))) {
7980240b6d63e0 drivers/android/binder.c         Martijn Coenen        2017-02-03  3046  				return_error = BR_FAILED_REPLY;
57ada2fb2250ea drivers/android/binder.c         Todd Kjos             2017-06-29  3047  				return_error_param = ret;
57ada2fb2250ea drivers/android/binder.c         Todd Kjos             2017-06-29  3048  				return_error_line = __LINE__;
7980240b6d63e0 drivers/android/binder.c         Martijn Coenen        2017-02-03  3049  				goto err_translate_failed;
7980240b6d63e0 drivers/android/binder.c         Martijn Coenen        2017-02-03  3050  			}
db6b0b810bf945 drivers/android/binder.c         Todd Kjos             2019-02-08  3051  			last_fixup_obj_off = object_offset;
7980240b6d63e0 drivers/android/binder.c         Martijn Coenen        2017-02-03  3052  			last_fixup_min_off = 0;
7980240b6d63e0 drivers/android/binder.c         Martijn Coenen        2017-02-03  3053  		} break;
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  3054  		default:
64dcfe6b84d410 drivers/staging/android/binder.c Serban Constantinescu 2013-07-04  3055  			binder_user_error("%d:%d got transaction with invalid object type, %x\n",
feba3900cabb8e drivers/android/binder.c         Martijn Coenen        2017-02-03  3056  				proc->pid, thread->pid, hdr->type);
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  3057  			return_error = BR_FAILED_REPLY;
57ada2fb2250ea drivers/android/binder.c         Todd Kjos             2017-06-29  3058  			return_error_param = -EINVAL;
57ada2fb2250ea drivers/android/binder.c         Todd Kjos             2017-06-29  3059  			return_error_line = __LINE__;
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  3060  			goto err_bad_object_type;
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  3061  		}
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  3062  	}
d51c5e7a3791e9 drivers/android/binder.c         Todd Kjos             2021-11-23  3063  	/* Done processing objects, copy the rest of the buffer */
d51c5e7a3791e9 drivers/android/binder.c         Todd Kjos             2021-11-23  3064  	if (binder_alloc_copy_user_to_buffer(
d51c5e7a3791e9 drivers/android/binder.c         Todd Kjos             2021-11-23  3065  				&target_proc->alloc,
d51c5e7a3791e9 drivers/android/binder.c         Todd Kjos             2021-11-23  3066  				t->buffer, user_offset,
d51c5e7a3791e9 drivers/android/binder.c         Todd Kjos             2021-11-23  3067  				user_buffer + user_offset,
d51c5e7a3791e9 drivers/android/binder.c         Todd Kjos             2021-11-23  3068  				tr->data_size - user_offset)) {
d51c5e7a3791e9 drivers/android/binder.c         Todd Kjos             2021-11-23  3069  		binder_user_error("%d:%d got transaction with invalid data ptr\n",
d51c5e7a3791e9 drivers/android/binder.c         Todd Kjos             2021-11-23  3070  				proc->pid, thread->pid);
d51c5e7a3791e9 drivers/android/binder.c         Todd Kjos             2021-11-23  3071  		return_error = BR_FAILED_REPLY;
d51c5e7a3791e9 drivers/android/binder.c         Todd Kjos             2021-11-23  3072  		return_error_param = -EFAULT;
d51c5e7a3791e9 drivers/android/binder.c         Todd Kjos             2021-11-23  3073  		return_error_line = __LINE__;
d51c5e7a3791e9 drivers/android/binder.c         Todd Kjos             2021-11-23  3074  		goto err_copy_data_failed;
d51c5e7a3791e9 drivers/android/binder.c         Todd Kjos             2021-11-23  3075  	}
a7dc1e6f99df59 drivers/android/binder.c         Hang Lu               2021-04-09  3076  	if (t->buffer->oneway_spam_suspect)
a7dc1e6f99df59 drivers/android/binder.c         Hang Lu               2021-04-09  3077  		tcomplete->type = BINDER_WORK_TRANSACTION_ONEWAY_SPAM_SUSPECT;
a7dc1e6f99df59 drivers/android/binder.c         Hang Lu               2021-04-09  3078  	else
ccae6f676001d0 drivers/android/binder.c         Todd Kjos             2017-06-29  3079  		tcomplete->type = BINDER_WORK_TRANSACTION_COMPLETE;
673068eee8560d drivers/android/binder.c         Todd Kjos             2017-06-29  3080  	t->work.type = BINDER_WORK_TRANSACTION;
ccae6f676001d0 drivers/android/binder.c         Todd Kjos             2017-06-29  3081  
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  3082  	if (reply) {
148ade2c4d4f46 drivers/android/binder.c         Martijn Coenen        2017-11-15  3083  		binder_enqueue_thread_work(thread, tcomplete);
0b89d69a962588 drivers/android/binder.c         Martijn Coenen        2017-06-29  3084  		binder_inner_proc_lock(target_proc);
b564171ade7057 drivers/android/binder.c         Li Li                 2021-09-10  3085  		if (target_thread->is_dead) {
b564171ade7057 drivers/android/binder.c         Li Li                 2021-09-10  3086  			return_error = BR_DEAD_REPLY;
0b89d69a962588 drivers/android/binder.c         Martijn Coenen        2017-06-29  3087  			binder_inner_proc_unlock(target_proc);
7a4408c6bd3eb1 drivers/android/binder.c         Todd Kjos             2017-06-29  3088  			goto err_dead_proc_or_thread;
0b89d69a962588 drivers/android/binder.c         Martijn Coenen        2017-06-29  3089  		}
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  3090  		BUG_ON(t->buffer->async_transaction != 0);
0b89d69a962588 drivers/android/binder.c         Martijn Coenen        2017-06-29  3091  		binder_pop_transaction_ilocked(target_thread, in_reply_to);
148ade2c4d4f46 drivers/android/binder.c         Martijn Coenen        2017-11-15  3092  		binder_enqueue_thread_work_ilocked(target_thread, &t->work);
432ff1e91694e4 drivers/android/binder.c         Marco Ballesio        2021-03-15  3093  		target_proc->outstanding_txns++;
0b89d69a962588 drivers/android/binder.c         Martijn Coenen        2017-06-29  3094  		binder_inner_proc_unlock(target_proc);
408c68b17aea2f drivers/android/binder.c         Martijn Coenen        2017-08-31  3095  		wake_up_interruptible_sync(&target_thread->wait);
b6d282cea3f3ed drivers/android/binder.c         Todd Kjos             2017-06-29  3096  		binder_free_transaction(in_reply_to);
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  3097  	} else if (!(t->flags & TF_ONE_WAY)) {
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  3098  		BUG_ON(t->buffer->async_transaction != 0);
0b89d69a962588 drivers/android/binder.c         Martijn Coenen        2017-06-29  3099  		binder_inner_proc_lock(proc);
148ade2c4d4f46 drivers/android/binder.c         Martijn Coenen        2017-11-15  3100  		/*
148ade2c4d4f46 drivers/android/binder.c         Martijn Coenen        2017-11-15  3101  		 * Defer the TRANSACTION_COMPLETE, so we don't return to
148ade2c4d4f46 drivers/android/binder.c         Martijn Coenen        2017-11-15  3102  		 * userspace immediately; this allows the target process to
148ade2c4d4f46 drivers/android/binder.c         Martijn Coenen        2017-11-15  3103  		 * immediately start processing this transaction, reducing
148ade2c4d4f46 drivers/android/binder.c         Martijn Coenen        2017-11-15  3104  		 * latency. We will then return the TRANSACTION_COMPLETE when
148ade2c4d4f46 drivers/android/binder.c         Martijn Coenen        2017-11-15  3105  		 * the target replies (or there is an error).
148ade2c4d4f46 drivers/android/binder.c         Martijn Coenen        2017-11-15  3106  		 */
148ade2c4d4f46 drivers/android/binder.c         Martijn Coenen        2017-11-15  3107  		binder_enqueue_deferred_thread_work_ilocked(thread, tcomplete);
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  3108  		t->need_reply = 1;
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  3109  		t->from_parent = thread->transaction_stack;
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  3110  		thread->transaction_stack = t;
0b89d69a962588 drivers/android/binder.c         Martijn Coenen        2017-06-29  3111  		binder_inner_proc_unlock(proc);
432ff1e91694e4 drivers/android/binder.c         Marco Ballesio        2021-03-15  3112  		return_error = binder_proc_transaction(t,
432ff1e91694e4 drivers/android/binder.c         Marco Ballesio        2021-03-15  3113  				target_proc, target_thread);
432ff1e91694e4 drivers/android/binder.c         Marco Ballesio        2021-03-15  3114  		if (return_error) {
0b89d69a962588 drivers/android/binder.c         Martijn Coenen        2017-06-29  3115  			binder_inner_proc_lock(proc);
0b89d69a962588 drivers/android/binder.c         Martijn Coenen        2017-06-29  3116  			binder_pop_transaction_ilocked(thread, t);
0b89d69a962588 drivers/android/binder.c         Martijn Coenen        2017-06-29  3117  			binder_inner_proc_unlock(proc);
7a4408c6bd3eb1 drivers/android/binder.c         Todd Kjos             2017-06-29  3118  			goto err_dead_proc_or_thread;
7a4408c6bd3eb1 drivers/android/binder.c         Todd Kjos             2017-06-29  3119  		}
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  3120  	} else {
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  3121  		BUG_ON(target_node == NULL);
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  3122  		BUG_ON(t->buffer->async_transaction != 1);
148ade2c4d4f46 drivers/android/binder.c         Martijn Coenen        2017-11-15  3123  		binder_enqueue_thread_work(thread, tcomplete);
432ff1e91694e4 drivers/android/binder.c         Marco Ballesio        2021-03-15  3124  		return_error = binder_proc_transaction(t, target_proc, NULL);
432ff1e91694e4 drivers/android/binder.c         Marco Ballesio        2021-03-15  3125  		if (return_error)
7a4408c6bd3eb1 drivers/android/binder.c         Todd Kjos             2017-06-29  3126  			goto err_dead_proc_or_thread;
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  3127  	}
7a4408c6bd3eb1 drivers/android/binder.c         Todd Kjos             2017-06-29  3128  	if (target_thread)
7a4408c6bd3eb1 drivers/android/binder.c         Todd Kjos             2017-06-29  3129  		binder_thread_dec_tmpref(target_thread);
7a4408c6bd3eb1 drivers/android/binder.c         Todd Kjos             2017-06-29  3130  	binder_proc_dec_tmpref(target_proc);
512cf465ee01eb drivers/android/binder.c         Todd Kjos             2017-09-29  3131  	if (target_node)
512cf465ee01eb drivers/android/binder.c         Todd Kjos             2017-09-29  3132  		binder_dec_node_tmpref(target_node);
d99c7333ab1c9d drivers/android/binder.c         Todd Kjos             2017-06-29  3133  	/*
d99c7333ab1c9d drivers/android/binder.c         Todd Kjos             2017-06-29  3134  	 * write barrier to synchronize with initialization
d99c7333ab1c9d drivers/android/binder.c         Todd Kjos             2017-06-29  3135  	 * of log entry
d99c7333ab1c9d drivers/android/binder.c         Todd Kjos             2017-06-29  3136  	 */
d99c7333ab1c9d drivers/android/binder.c         Todd Kjos             2017-06-29  3137  	smp_wmb();
d99c7333ab1c9d drivers/android/binder.c         Todd Kjos             2017-06-29  3138  	WRITE_ONCE(e->debug_id_done, t_debug_id);
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  3139  	return;
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  3140  
7a4408c6bd3eb1 drivers/android/binder.c         Todd Kjos             2017-06-29  3141  err_dead_proc_or_thread:
7a4408c6bd3eb1 drivers/android/binder.c         Todd Kjos             2017-06-29  3142  	return_error_line = __LINE__;
d53bebdf4d7794 drivers/android/binder.c         Xu YiPing             2017-09-05  3143  	binder_dequeue_work(proc, tcomplete);
a056af42032e56 drivers/android/binder.c         Martijn Coenen        2017-02-03  3144  err_translate_failed:
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  3145  err_bad_object_type:
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  3146  err_bad_offset:
def95c73567dfa drivers/android/binder.c         Martijn Coenen        2017-02-03  3147  err_bad_parent:
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  3148  err_copy_data_failed:
44d8047f1d87ad drivers/android/binder.c         Todd Kjos             2018-08-28  3149  	binder_free_txn_fixups(t);
975a1ac9a9fe65 drivers/staging/android/binder.c Arve Hjønnevåg        2012-10-16  3150  	trace_binder_transaction_failed_buffer_release(t->buffer);
5fdb55c1ac9585 drivers/android/binder.c         Todd Kjos             2021-08-30  3151  	binder_transaction_buffer_release(target_proc, NULL, t->buffer,
bde4a19fc04f5f drivers/android/binder.c         Todd Kjos             2019-02-08  3152  					  buffer_offset, true);
512cf465ee01eb drivers/android/binder.c         Todd Kjos             2017-09-29  3153  	if (target_node)
512cf465ee01eb drivers/android/binder.c         Todd Kjos             2017-09-29  3154  		binder_dec_node_tmpref(target_node);
eb34983ba170f2 drivers/android/binder.c         Todd Kjos             2017-06-29  3155  	target_node = NULL;
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  3156  	t->buffer->transaction = NULL;
19c987241ca121 drivers/android/binder.c         Todd Kjos             2017-06-29  3157  	binder_alloc_free_buf(&target_proc->alloc, t->buffer);
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  3158  err_binder_alloc_buf_failed:
0b0509508beff6 drivers/android/binder.c         Todd Kjos             2019-04-24  3159  err_bad_extra_size:
ec74136ded792d drivers/android/binder.c         Todd Kjos             2019-01-14  3160  	if (secctx)
ec74136ded792d drivers/android/binder.c         Todd Kjos             2019-01-14  3161  		security_release_secctx(secctx, secctx_sz);
ec74136ded792d drivers/android/binder.c         Todd Kjos             2019-01-14  3162  err_get_secctx_failed:
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  3163  	kfree(tcomplete);
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  3164  	binder_stats_deleted(BINDER_STAT_TRANSACTION_COMPLETE);
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  3165  err_alloc_tcomplete_failed:
1987f112f1425c drivers/android/binder.c         Frankie.Chang         2020-11-11  3166  	if (trace_binder_txn_latency_free_enabled())
1987f112f1425c drivers/android/binder.c         Frankie.Chang         2020-11-11  3167  		binder_txn_latency_free(t);
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  3168  	kfree(t);
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  3169  	binder_stats_deleted(BINDER_STAT_TRANSACTION);
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  3170  err_alloc_t_failed:
44b73962cb25f1 drivers/android/binder.c         Sherry Yang           2018-08-13  3171  err_bad_todo_list:
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  3172  err_bad_call_stack:
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  3173  err_empty_call_stack:
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  3174  err_dead_binder:
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  3175  err_invalid_target_handle:
7a4408c6bd3eb1 drivers/android/binder.c         Todd Kjos             2017-06-29  3176  	if (target_thread)
7a4408c6bd3eb1 drivers/android/binder.c         Todd Kjos             2017-06-29  3177  		binder_thread_dec_tmpref(target_thread);
7a4408c6bd3eb1 drivers/android/binder.c         Todd Kjos             2017-06-29  3178  	if (target_proc)
7a4408c6bd3eb1 drivers/android/binder.c         Todd Kjos             2017-06-29  3179  		binder_proc_dec_tmpref(target_proc);
512cf465ee01eb drivers/android/binder.c         Todd Kjos             2017-09-29  3180  	if (target_node) {
eb34983ba170f2 drivers/android/binder.c         Todd Kjos             2017-06-29  3181  		binder_dec_node(target_node, 1, 0);
512cf465ee01eb drivers/android/binder.c         Todd Kjos             2017-09-29  3182  		binder_dec_node_tmpref(target_node);
512cf465ee01eb drivers/android/binder.c         Todd Kjos             2017-09-29  3183  	}
eb34983ba170f2 drivers/android/binder.c         Todd Kjos             2017-06-29  3184  
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  3185  	binder_debug(BINDER_DEBUG_FAILED_TRANSACTION,
57ada2fb2250ea drivers/android/binder.c         Todd Kjos             2017-06-29  3186  		     "%d:%d transaction failed %d/%d, size %lld-%lld line %d\n",
57ada2fb2250ea drivers/android/binder.c         Todd Kjos             2017-06-29  3187  		     proc->pid, thread->pid, return_error, return_error_param,
57ada2fb2250ea drivers/android/binder.c         Todd Kjos             2017-06-29  3188  		     (u64)tr->data_size, (u64)tr->offsets_size,
57ada2fb2250ea drivers/android/binder.c         Todd Kjos             2017-06-29  3189  		     return_error_line);
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  3190  
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  3191  	{
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  3192  		struct binder_transaction_log_entry *fe;
10f62861b4a2f2 drivers/staging/android/binder.c Seunghun Lee          2014-05-01  3193  
57ada2fb2250ea drivers/android/binder.c         Todd Kjos             2017-06-29  3194  		e->return_error = return_error;
57ada2fb2250ea drivers/android/binder.c         Todd Kjos             2017-06-29  3195  		e->return_error_param = return_error_param;
57ada2fb2250ea drivers/android/binder.c         Todd Kjos             2017-06-29  3196  		e->return_error_line = return_error_line;
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  3197  		fe = binder_transaction_log_add(&binder_transaction_log_failed);
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  3198  		*fe = *e;
d99c7333ab1c9d drivers/android/binder.c         Todd Kjos             2017-06-29  3199  		/*
d99c7333ab1c9d drivers/android/binder.c         Todd Kjos             2017-06-29  3200  		 * write barrier to synchronize with initialization
d99c7333ab1c9d drivers/android/binder.c         Todd Kjos             2017-06-29  3201  		 * of log entry
d99c7333ab1c9d drivers/android/binder.c         Todd Kjos             2017-06-29  3202  		 */
d99c7333ab1c9d drivers/android/binder.c         Todd Kjos             2017-06-29  3203  		smp_wmb();
d99c7333ab1c9d drivers/android/binder.c         Todd Kjos             2017-06-29  3204  		WRITE_ONCE(e->debug_id_done, t_debug_id);
d99c7333ab1c9d drivers/android/binder.c         Todd Kjos             2017-06-29  3205  		WRITE_ONCE(fe->debug_id_done, t_debug_id);
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  3206  	}
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  3207  
26549d17741035 drivers/android/binder.c         Todd Kjos             2017-06-29  3208  	BUG_ON(thread->return_error.cmd != BR_OK);
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  3209  	if (in_reply_to) {
26549d17741035 drivers/android/binder.c         Todd Kjos             2017-06-29  3210  		thread->return_error.cmd = BR_TRANSACTION_COMPLETE;
148ade2c4d4f46 drivers/android/binder.c         Martijn Coenen        2017-11-15  3211  		binder_enqueue_thread_work(thread, &thread->return_error.work);
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  3212  		binder_send_failed_reply(in_reply_to, return_error);
26549d17741035 drivers/android/binder.c         Todd Kjos             2017-06-29  3213  	} else {
26549d17741035 drivers/android/binder.c         Todd Kjos             2017-06-29  3214  		thread->return_error.cmd = return_error;
148ade2c4d4f46 drivers/android/binder.c         Martijn Coenen        2017-11-15  3215  		binder_enqueue_thread_work(thread, &thread->return_error.work);
26549d17741035 drivers/android/binder.c         Todd Kjos             2017-06-29  3216  	}
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  3217  }
355b0502f6efea drivers/staging/android/binder.c Greg Kroah-Hartman    2011-11-30  3218  

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org

^ permalink raw reply	[flat|nested] 20+ messages in thread

end of thread, other threads:[~2021-11-25 12:24 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-11-23 19:17 [PATCH 0/3] binder: Prevent untranslated sender data from being copied to target Todd Kjos
2021-11-23 19:17 ` [PATCH 1/3] binder: avoid potential data leakage when copying txn Todd Kjos
2021-11-24  7:50   ` Martijn Coenen
2021-11-24 13:01   ` Dan Carpenter
2021-11-24 20:11     ` Todd Kjos
2021-11-25  2:05   ` kernel test robot
2021-11-25 12:18   ` kernel test robot
2021-11-23 19:17 ` [PATCH 2/3] binder: read pre-translated fds from sender buffer Todd Kjos
2021-11-24  7:50   ` Martijn Coenen
2021-11-24 12:37   ` Dan Carpenter
2021-11-24 20:33     ` Todd Kjos
2021-11-25  6:37       ` Dan Carpenter
2021-11-23 19:17 ` [PATCH 3/3] binder: defer copies of pre-patched txn data Todd Kjos
2021-11-24  7:50   ` Martijn Coenen
2021-11-24 11:09   ` Dan Carpenter
2021-11-24 20:39     ` Todd Kjos
2021-11-24 12:43   ` Dan Carpenter
2021-11-24 20:37     ` Todd Kjos
2021-11-24  8:08 ` [PATCH 0/3] binder: Prevent untranslated sender data from being copied to target Greg KH
2021-11-24 15:54   ` Todd Kjos

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).