linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] binder: add flag to clear buffer on txn complete
@ 2020-11-20 23:37 Todd Kjos
  2020-11-21  7:14 ` Greg KH
  0 siblings, 1 reply; 3+ messages in thread
From: Todd Kjos @ 2020-11-20 23:37 UTC (permalink / raw)
  To: tkjos, gregkh, christian, arve, devel, linux-kernel, maco
  Cc: joel, kernel-team, smoreland

Add a per-transaction flag to indicate that the buffer
must be cleared when the transaction is complete to
prevent copies of sensitive data from being preserved
in memory.

Signed-off-by: Todd Kjos <tkjos@google.com>
---
 drivers/android/binder.c            |  1 +
 drivers/android/binder_alloc.c      | 48 +++++++++++++++++++++++++++++
 drivers/android/binder_alloc.h      |  4 ++-
 include/uapi/linux/android/binder.h |  1 +
 4 files changed, 53 insertions(+), 1 deletion(-)

diff --git a/drivers/android/binder.c b/drivers/android/binder.c
index b5117576792b..2a3952925855 100644
--- a/drivers/android/binder.c
+++ b/drivers/android/binder.c
@@ -3146,6 +3146,7 @@ static void binder_transaction(struct binder_proc *proc,
 	t->buffer->debug_id = t->debug_id;
 	t->buffer->transaction = t;
 	t->buffer->target_node = target_node;
+	t->buffer->clear_on_free = !!(t->flags & TF_CLEAR_BUF);
 	trace_binder_transaction_alloc_buf(t->buffer);
 
 	if (binder_alloc_copy_user_to_buffer(
diff --git a/drivers/android/binder_alloc.c b/drivers/android/binder_alloc.c
index 2f846b7ae8b8..7caf74ad2405 100644
--- a/drivers/android/binder_alloc.c
+++ b/drivers/android/binder_alloc.c
@@ -696,6 +696,8 @@ static void binder_free_buf_locked(struct binder_alloc *alloc,
 	binder_insert_free_buffer(alloc, buffer);
 }
 
+static void binder_alloc_clear_buf(struct binder_alloc *alloc,
+				   struct binder_buffer *buffer);
 /**
  * binder_alloc_free_buf() - free a binder buffer
  * @alloc:	binder_alloc for this proc
@@ -706,6 +708,18 @@ static void binder_free_buf_locked(struct binder_alloc *alloc,
 void binder_alloc_free_buf(struct binder_alloc *alloc,
 			    struct binder_buffer *buffer)
 {
+	/*
+	 * We could eliminate the call to binder_alloc_clear_buf()
+	 * from binder_alloc_deferred_release() by moving this to
+	 * binder_alloc_free_buf_locked(). However, that could
+	 * increase contention for the alloc mutex if clear_on_free
+	 * is used frequently for large buffers. The mutex is not
+	 * needed for correctness here.
+	 */
+	if (buffer->clear_on_free) {
+		binder_alloc_clear_buf(alloc, buffer);
+		buffer->clear_on_free = false;
+	}
 	mutex_lock(&alloc->mutex);
 	binder_free_buf_locked(alloc, buffer);
 	mutex_unlock(&alloc->mutex);
@@ -802,6 +816,10 @@ void binder_alloc_deferred_release(struct binder_alloc *alloc)
 		/* Transaction should already have been freed */
 		BUG_ON(buffer->transaction);
 
+		if (buffer->clear_on_free) {
+			binder_alloc_clear_buf(alloc, buffer);
+			buffer->clear_on_free = false;
+		}
 		binder_free_buf_locked(alloc, buffer);
 		buffers++;
 	}
@@ -1135,6 +1153,36 @@ static struct page *binder_alloc_get_page(struct binder_alloc *alloc,
 	return lru_page->page_ptr;
 }
 
+/**
+ * binder_alloc_clear_buf() - zero out buffer
+ * @alloc: binder_alloc for this proc
+ * @buffer: binder buffer to be cleared
+ *
+ * memset the given buffer to 0
+ */
+static void binder_alloc_clear_buf(struct binder_alloc *alloc,
+				   struct binder_buffer *buffer)
+{
+	size_t bytes = binder_alloc_buffer_size(alloc, buffer);
+	binder_size_t buffer_offset = 0;
+
+	while (bytes) {
+		unsigned long size;
+		struct page *page;
+		pgoff_t pgoff;
+		void *kptr;
+
+		page = binder_alloc_get_page(alloc, buffer,
+					     buffer_offset, &pgoff);
+		size = min_t(size_t, bytes, PAGE_SIZE - pgoff);
+		kptr = kmap(page) + pgoff;
+		memset(kptr, 0, size);
+		kunmap(page);
+		bytes -= size;
+		buffer_offset += size;
+	}
+}
+
 /**
  * binder_alloc_copy_user_to_buffer() - copy src user to tgt user
  * @alloc: binder_alloc for this proc
diff --git a/drivers/android/binder_alloc.h b/drivers/android/binder_alloc.h
index 55d8b4106766..6e8e001381af 100644
--- a/drivers/android/binder_alloc.h
+++ b/drivers/android/binder_alloc.h
@@ -23,6 +23,7 @@ struct binder_transaction;
  * @entry:              entry alloc->buffers
  * @rb_node:            node for allocated_buffers/free_buffers rb trees
  * @free:               %true if buffer is free
+ * @clear_on_free:      %true if buffer must be zeroed after use
  * @allow_user_free:    %true if user is allowed to free buffer
  * @async_transaction:  %true if buffer is in use for an async txn
  * @debug_id:           unique ID for debugging
@@ -41,9 +42,10 @@ struct binder_buffer {
 	struct rb_node rb_node; /* free entry by size or allocated entry */
 				/* by address */
 	unsigned free:1;
+	unsigned clear_on_free:1;
 	unsigned allow_user_free:1;
 	unsigned async_transaction:1;
-	unsigned debug_id:29;
+	unsigned debug_id:28;
 
 	struct binder_transaction *transaction;
 
diff --git a/include/uapi/linux/android/binder.h b/include/uapi/linux/android/binder.h
index f1ce2c4c077e..ec84ad106568 100644
--- a/include/uapi/linux/android/binder.h
+++ b/include/uapi/linux/android/binder.h
@@ -248,6 +248,7 @@ enum transaction_flags {
 	TF_ROOT_OBJECT	= 0x04,	/* contents are the component's root object */
 	TF_STATUS_CODE	= 0x08,	/* contents are a 32-bit status code */
 	TF_ACCEPT_FDS	= 0x10,	/* allow replies with file descriptors */
+	TF_CLEAR_BUF	= 0x20,	/* clear buffer on txn complete */
 };
 
 struct binder_transaction_data {
-- 
2.29.2.454.gaff20da3a2-goog


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

* Re: [PATCH] binder: add flag to clear buffer on txn complete
  2020-11-20 23:37 [PATCH] binder: add flag to clear buffer on txn complete Todd Kjos
@ 2020-11-21  7:14 ` Greg KH
  2020-11-21 17:11   ` Todd Kjos
  0 siblings, 1 reply; 3+ messages in thread
From: Greg KH @ 2020-11-21  7:14 UTC (permalink / raw)
  To: Todd Kjos
  Cc: christian, arve, devel, linux-kernel, maco, joel, kernel-team, smoreland

On Fri, Nov 20, 2020 at 03:37:43PM -0800, Todd Kjos wrote:
> Add a per-transaction flag to indicate that the buffer
> must be cleared when the transaction is complete to
> prevent copies of sensitive data from being preserved
> in memory.
> 
> Signed-off-by: Todd Kjos <tkjos@google.com>
> ---

DOes this need to be backported to stable kernels as well?

thanks,

greg k-h

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

* Re: [PATCH] binder: add flag to clear buffer on txn complete
  2020-11-21  7:14 ` Greg KH
@ 2020-11-21 17:11   ` Todd Kjos
  0 siblings, 0 replies; 3+ messages in thread
From: Todd Kjos @ 2020-11-21 17:11 UTC (permalink / raw)
  To: Greg KH
  Cc: Christian Brauner, Arve Hjønnevåg,
	open list:ANDROID DRIVERS, LKML, Martijn Coenen,
	Joel Fernandes (Google),
	Android Kernel Team, Steven Moreland

On Fri, Nov 20, 2020 at 11:14 PM Greg KH <gregkh@linuxfoundation.org> wrote:
>
> On Fri, Nov 20, 2020 at 03:37:43PM -0800, Todd Kjos wrote:
> > Add a per-transaction flag to indicate that the buffer
> > must be cleared when the transaction is complete to
> > prevent copies of sensitive data from being preserved
> > in memory.
> >
> > Signed-off-by: Todd Kjos <tkjos@google.com>
> > ---
>
> DOes this need to be backported to stable kernels as well?

It doesn't technically qualify for stable since it is a new feature --
not a bug fix. We will want it for Android S launch devices (5.4+), so
it would be handy to have it in 5.4.y and later.

>
> thanks,
>
> greg k-h
>
> --
> 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] 3+ messages in thread

end of thread, other threads:[~2020-11-21 17:12 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-11-20 23:37 [PATCH] binder: add flag to clear buffer on txn complete Todd Kjos
2020-11-21  7:14 ` Greg KH
2020-11-21 17:11   ` 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).