All of lore.kernel.org
 help / color / mirror / Atom feed
From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: linux-kernel@vger.kernel.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	stable@vger.kernel.org, Todd Kjos <tkjos@google.com>,
	"Joel Fernandes (Google)" <joel@joelfernandes.org>
Subject: [PATCH 5.0 03/46] binder: create node flag to request senders security context
Date: Fri,  8 Mar 2019 13:49:36 +0100	[thread overview]
Message-ID: <20190308124902.462820025@linuxfoundation.org> (raw)
In-Reply-To: <20190308124902.257040783@linuxfoundation.org>

5.0-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Todd Kjos <tkjos@android.com>

commit ec74136ded792deed80780a2f8baf3521eeb72f9 upstream.

To allow servers to verify client identity, allow a node
flag to be set that causes the sender's security context
to be delivered with the transaction. The BR_TRANSACTION
command is extended in BR_TRANSACTION_SEC_CTX to
contain a pointer to the security context string.

Signed-off-by: Todd Kjos <tkjos@google.com>
Reviewed-by: Joel Fernandes (Google) <joel@joelfernandes.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

---
 drivers/android/binder.c            |  106 ++++++++++++++++++++++++++++--------
 include/uapi/linux/android/binder.h |   19 ++++++
 2 files changed, 102 insertions(+), 23 deletions(-)

--- a/drivers/android/binder.c
+++ b/drivers/android/binder.c
@@ -329,6 +329,8 @@ struct binder_error {
  *                        (invariant after initialized)
  * @min_priority:         minimum scheduling priority
  *                        (invariant after initialized)
+ * @txn_security_ctx:     require sender's security context
+ *                        (invariant after initialized)
  * @async_todo:           list of async work items
  *                        (protected by @proc->inner_lock)
  *
@@ -365,6 +367,7 @@ struct binder_node {
 		 * invariant after initialization
 		 */
 		u8 accept_fds:1;
+		u8 txn_security_ctx:1;
 		u8 min_priority;
 	};
 	bool has_async_transaction;
@@ -615,6 +618,7 @@ struct binder_transaction {
 	long	saved_priority;
 	kuid_t	sender_euid;
 	struct list_head fd_fixups;
+	binder_uintptr_t security_ctx;
 	/**
 	 * @lock:  protects @from, @to_proc, and @to_thread
 	 *
@@ -1152,6 +1156,7 @@ static struct binder_node *binder_init_n
 	node->work.type = BINDER_WORK_NODE;
 	node->min_priority = flags & FLAT_BINDER_FLAG_PRIORITY_MASK;
 	node->accept_fds = !!(flags & FLAT_BINDER_FLAG_ACCEPTS_FDS);
+	node->txn_security_ctx = !!(flags & FLAT_BINDER_FLAG_TXN_SECURITY_CTX);
 	spin_lock_init(&node->lock);
 	INIT_LIST_HEAD(&node->work.entry);
 	INIT_LIST_HEAD(&node->async_todo);
@@ -2778,6 +2783,8 @@ static void binder_transaction(struct bi
 	binder_size_t last_fixup_min_off = 0;
 	struct binder_context *context = proc->context;
 	int t_debug_id = atomic_inc_return(&binder_last_id);
+	char *secctx = NULL;
+	u32 secctx_sz = 0;
 
 	e = binder_transaction_log_add(&binder_transaction_log);
 	e->debug_id = t_debug_id;
@@ -3020,6 +3027,20 @@ static void binder_transaction(struct bi
 	t->flags = tr->flags;
 	t->priority = task_nice(current);
 
+	if (target_node && target_node->txn_security_ctx) {
+		u32 secid;
+
+		security_task_getsecid(proc->tsk, &secid);
+		ret = security_secid_to_secctx(secid, &secctx, &secctx_sz);
+		if (ret) {
+			return_error = BR_FAILED_REPLY;
+			return_error_param = ret;
+			return_error_line = __LINE__;
+			goto err_get_secctx_failed;
+		}
+		extra_buffers_size += ALIGN(secctx_sz, sizeof(u64));
+	}
+
 	trace_binder_transaction(reply, t, target_node);
 
 	t->buffer = binder_alloc_new_buf(&target_proc->alloc, tr->data_size,
@@ -3036,6 +3057,19 @@ static void binder_transaction(struct bi
 		t->buffer = NULL;
 		goto err_binder_alloc_buf_failed;
 	}
+	if (secctx) {
+		size_t buf_offset = ALIGN(tr->data_size, sizeof(void *)) +
+				    ALIGN(tr->offsets_size, sizeof(void *)) +
+				    ALIGN(extra_buffers_size, sizeof(void *)) -
+				    ALIGN(secctx_sz, sizeof(u64));
+		char *kptr = t->buffer->data + buf_offset;
+
+		t->security_ctx = (uintptr_t)kptr +
+		    binder_alloc_get_user_buffer_offset(&target_proc->alloc);
+		memcpy(kptr, secctx, secctx_sz);
+		security_release_secctx(secctx, secctx_sz);
+		secctx = NULL;
+	}
 	t->buffer->debug_id = t->debug_id;
 	t->buffer->transaction = t;
 	t->buffer->target_node = target_node;
@@ -3305,6 +3339,9 @@ err_copy_data_failed:
 	t->buffer->transaction = NULL;
 	binder_alloc_free_buf(&target_proc->alloc, t->buffer);
 err_binder_alloc_buf_failed:
+	if (secctx)
+		security_release_secctx(secctx, secctx_sz);
+err_get_secctx_failed:
 	kfree(tcomplete);
 	binder_stats_deleted(BINDER_STAT_TRANSACTION_COMPLETE);
 err_alloc_tcomplete_failed:
@@ -4036,11 +4073,13 @@ retry:
 
 	while (1) {
 		uint32_t cmd;
-		struct binder_transaction_data tr;
+		struct binder_transaction_data_secctx tr;
+		struct binder_transaction_data *trd = &tr.transaction_data;
 		struct binder_work *w = NULL;
 		struct list_head *list = NULL;
 		struct binder_transaction *t = NULL;
 		struct binder_thread *t_from;
+		size_t trsize = sizeof(*trd);
 
 		binder_inner_proc_lock(proc);
 		if (!binder_worklist_empty_ilocked(&thread->todo))
@@ -4240,8 +4279,8 @@ retry:
 		if (t->buffer->target_node) {
 			struct binder_node *target_node = t->buffer->target_node;
 
-			tr.target.ptr = target_node->ptr;
-			tr.cookie =  target_node->cookie;
+			trd->target.ptr = target_node->ptr;
+			trd->cookie =  target_node->cookie;
 			t->saved_priority = task_nice(current);
 			if (t->priority < target_node->min_priority &&
 			    !(t->flags & TF_ONE_WAY))
@@ -4251,22 +4290,23 @@ retry:
 				binder_set_nice(target_node->min_priority);
 			cmd = BR_TRANSACTION;
 		} else {
-			tr.target.ptr = 0;
-			tr.cookie = 0;
+			trd->target.ptr = 0;
+			trd->cookie = 0;
 			cmd = BR_REPLY;
 		}
-		tr.code = t->code;
-		tr.flags = t->flags;
-		tr.sender_euid = from_kuid(current_user_ns(), t->sender_euid);
+		trd->code = t->code;
+		trd->flags = t->flags;
+		trd->sender_euid = from_kuid(current_user_ns(), t->sender_euid);
 
 		t_from = binder_get_txn_from(t);
 		if (t_from) {
 			struct task_struct *sender = t_from->proc->tsk;
 
-			tr.sender_pid = task_tgid_nr_ns(sender,
-							task_active_pid_ns(current));
+			trd->sender_pid =
+				task_tgid_nr_ns(sender,
+						task_active_pid_ns(current));
 		} else {
-			tr.sender_pid = 0;
+			trd->sender_pid = 0;
 		}
 
 		ret = binder_apply_fd_fixups(t);
@@ -4297,15 +4337,20 @@ retry:
 			}
 			continue;
 		}
-		tr.data_size = t->buffer->data_size;
-		tr.offsets_size = t->buffer->offsets_size;
-		tr.data.ptr.buffer = (binder_uintptr_t)
+		trd->data_size = t->buffer->data_size;
+		trd->offsets_size = t->buffer->offsets_size;
+		trd->data.ptr.buffer = (binder_uintptr_t)
 			((uintptr_t)t->buffer->data +
 			binder_alloc_get_user_buffer_offset(&proc->alloc));
-		tr.data.ptr.offsets = tr.data.ptr.buffer +
+		trd->data.ptr.offsets = trd->data.ptr.buffer +
 					ALIGN(t->buffer->data_size,
 					    sizeof(void *));
 
+		tr.secctx = t->security_ctx;
+		if (t->security_ctx) {
+			cmd = BR_TRANSACTION_SEC_CTX;
+			trsize = sizeof(tr);
+		}
 		if (put_user(cmd, (uint32_t __user *)ptr)) {
 			if (t_from)
 				binder_thread_dec_tmpref(t_from);
@@ -4316,7 +4361,7 @@ retry:
 			return -EFAULT;
 		}
 		ptr += sizeof(uint32_t);
-		if (copy_to_user(ptr, &tr, sizeof(tr))) {
+		if (copy_to_user(ptr, &tr, trsize)) {
 			if (t_from)
 				binder_thread_dec_tmpref(t_from);
 
@@ -4325,7 +4370,7 @@ retry:
 
 			return -EFAULT;
 		}
-		ptr += sizeof(tr);
+		ptr += trsize;
 
 		trace_binder_transaction_received(t);
 		binder_stat_br(proc, thread, cmd);
@@ -4333,16 +4378,18 @@ retry:
 			     "%d:%d %s %d %d:%d, cmd %d size %zd-%zd ptr %016llx-%016llx\n",
 			     proc->pid, thread->pid,
 			     (cmd == BR_TRANSACTION) ? "BR_TRANSACTION" :
-			     "BR_REPLY",
+				(cmd == BR_TRANSACTION_SEC_CTX) ?
+				     "BR_TRANSACTION_SEC_CTX" : "BR_REPLY",
 			     t->debug_id, t_from ? t_from->proc->pid : 0,
 			     t_from ? t_from->pid : 0, cmd,
 			     t->buffer->data_size, t->buffer->offsets_size,
-			     (u64)tr.data.ptr.buffer, (u64)tr.data.ptr.offsets);
+			     (u64)trd->data.ptr.buffer,
+			     (u64)trd->data.ptr.offsets);
 
 		if (t_from)
 			binder_thread_dec_tmpref(t_from);
 		t->buffer->allow_user_free = 1;
-		if (cmd == BR_TRANSACTION && !(t->flags & TF_ONE_WAY)) {
+		if (cmd != BR_REPLY && !(t->flags & TF_ONE_WAY)) {
 			binder_inner_proc_lock(thread->proc);
 			t->to_parent = thread->transaction_stack;
 			t->to_thread = thread;
@@ -4690,7 +4737,8 @@ out:
 	return ret;
 }
 
-static int binder_ioctl_set_ctx_mgr(struct file *filp)
+static int binder_ioctl_set_ctx_mgr(struct file *filp,
+				    struct flat_binder_object *fbo)
 {
 	int ret = 0;
 	struct binder_proc *proc = filp->private_data;
@@ -4719,7 +4767,7 @@ static int binder_ioctl_set_ctx_mgr(stru
 	} else {
 		context->binder_context_mgr_uid = curr_euid;
 	}
-	new_node = binder_new_node(proc, NULL);
+	new_node = binder_new_node(proc, fbo);
 	if (!new_node) {
 		ret = -ENOMEM;
 		goto out;
@@ -4842,8 +4890,20 @@ static long binder_ioctl(struct file *fi
 		binder_inner_proc_unlock(proc);
 		break;
 	}
+	case BINDER_SET_CONTEXT_MGR_EXT: {
+		struct flat_binder_object fbo;
+
+		if (copy_from_user(&fbo, ubuf, sizeof(fbo))) {
+			ret = -EINVAL;
+			goto err;
+		}
+		ret = binder_ioctl_set_ctx_mgr(filp, &fbo);
+		if (ret)
+			goto err;
+		break;
+	}
 	case BINDER_SET_CONTEXT_MGR:
-		ret = binder_ioctl_set_ctx_mgr(filp);
+		ret = binder_ioctl_set_ctx_mgr(filp, NULL);
 		if (ret)
 			goto err;
 		break;
--- a/include/uapi/linux/android/binder.h
+++ b/include/uapi/linux/android/binder.h
@@ -41,6 +41,14 @@ enum {
 enum {
 	FLAT_BINDER_FLAG_PRIORITY_MASK = 0xff,
 	FLAT_BINDER_FLAG_ACCEPTS_FDS = 0x100,
+
+	/**
+	 * @FLAT_BINDER_FLAG_TXN_SECURITY_CTX: request security contexts
+	 *
+	 * Only when set, causes senders to include their security
+	 * context
+	 */
+	FLAT_BINDER_FLAG_TXN_SECURITY_CTX = 0x1000,
 };
 
 #ifdef BINDER_IPC_32BIT
@@ -218,6 +226,7 @@ struct binder_node_info_for_ref {
 #define BINDER_VERSION			_IOWR('b', 9, struct binder_version)
 #define BINDER_GET_NODE_DEBUG_INFO	_IOWR('b', 11, struct binder_node_debug_info)
 #define BINDER_GET_NODE_INFO_FOR_REF	_IOWR('b', 12, struct binder_node_info_for_ref)
+#define BINDER_SET_CONTEXT_MGR_EXT	_IOW('b', 13, struct flat_binder_object)
 
 /*
  * NOTE: Two special error codes you should check for when calling
@@ -276,6 +285,11 @@ struct binder_transaction_data {
 	} data;
 };
 
+struct binder_transaction_data_secctx {
+	struct binder_transaction_data transaction_data;
+	binder_uintptr_t secctx;
+};
+
 struct binder_transaction_data_sg {
 	struct binder_transaction_data transaction_data;
 	binder_size_t buffers_size;
@@ -311,6 +325,11 @@ enum binder_driver_return_protocol {
 	BR_OK = _IO('r', 1),
 	/* No parameters! */
 
+	BR_TRANSACTION_SEC_CTX = _IOR('r', 2,
+				      struct binder_transaction_data_secctx),
+	/*
+	 * binder_transaction_data_secctx: the received command.
+	 */
 	BR_TRANSACTION = _IOR('r', 2, struct binder_transaction_data),
 	BR_REPLY = _IOR('r', 3, struct binder_transaction_data),
 	/*



  parent reply	other threads:[~2019-03-08 12:52 UTC|newest]

Thread overview: 60+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-03-08 12:49 [PATCH 5.0 00/46] 5.0.1-stable review Greg Kroah-Hartman
2019-03-08 12:49 ` [PATCH 5.0 01/46] cpufreq: Use struct kobj_attribute instead of struct global_attr Greg Kroah-Hartman
2019-03-08 12:49 ` [PATCH 5.0 02/46] staging: erofs: fix mis-acted TAIL merging behavior Greg Kroah-Hartman
2019-03-08 12:49 ` Greg Kroah-Hartman [this message]
2019-03-08 12:49 ` [PATCH 5.0 04/46] USB: serial: option: add Telit ME910 ECM composition Greg Kroah-Hartman
2019-03-08 12:49 ` [PATCH 5.0 05/46] USB: serial: cp210x: add ID for Ingenico 3070 Greg Kroah-Hartman
2019-03-08 12:49 ` [PATCH 5.0 06/46] USB: serial: ftdi_sio: add ID for Hjelmslund Electronics USB485 Greg Kroah-Hartman
2019-03-08 12:49 ` [PATCH 5.0 07/46] driver core: Postpone DMA tear-down until after devres release Greg Kroah-Hartman
2019-03-08 12:49 ` [PATCH 5.0 08/46] staging: erofs: fix fast symlink w/o xattr when fs xattr is on Greg Kroah-Hartman
2019-03-08 12:49 ` [PATCH 5.0 09/46] staging: erofs: fix memleak of inodes shared xattr array Greg Kroah-Hartman
2019-03-08 12:49 ` [PATCH 5.0 10/46] staging: erofs: fix race of initializing xattrs of a inode at the same time Greg Kroah-Hartman
2019-03-08 12:49 ` [PATCH 5.0 11/46] staging: erofs: fix illegal address access under memory pressure Greg Kroah-Hartman
2019-03-08 12:49 ` [PATCH 5.0 12/46] staging: comedi: ni_660x: fix missing break in switch statement Greg Kroah-Hartman
2019-03-08 12:49 ` [PATCH 5.0 13/46] staging: wilc1000: fix to set correct value for vif_num Greg Kroah-Hartman
2019-03-08 12:49 ` [PATCH 5.0 14/46] staging: android: ion: fix sys heap pools gfp_flags Greg Kroah-Hartman
2019-03-08 12:49 ` [PATCH 5.0 15/46] staging: android: ashmem: Dont call fallocate() with ashmem_mutex held Greg Kroah-Hartman
2019-03-08 12:49 ` [PATCH 5.0 16/46] staging: android: ashmem: Avoid range_alloc() allocation " Greg Kroah-Hartman
2019-03-08 12:49 ` [PATCH 5.0 17/46] ip6mr: Do not call __IP6_INC_STATS() from preemptible context Greg Kroah-Hartman
2019-03-08 12:49 ` [PATCH 5.0 18/46] net: dsa: mv88e6xxx: add call to mv88e6xxx_ports_cmode_init to probe for new DSA framework Greg Kroah-Hartman
2019-03-08 12:49 ` [PATCH 5.0 19/46] net: dsa: mv88e6xxx: handle unknown duplex modes gracefully in mv88e6xxx_port_set_duplex Greg Kroah-Hartman
2019-03-08 12:49 ` [PATCH 5.0 20/46] net: dsa: mv8e6xxx: fix number of internal PHYs for 88E6x90 family Greg Kroah-Hartman
2019-03-08 12:49 ` [PATCH 5.0 21/46] net: mscc: Enable all ports in QSGMII Greg Kroah-Hartman
2019-03-08 12:49 ` [PATCH 5.0 22/46] net: sched: put back q.qlen into a single location Greg Kroah-Hartman
2019-03-08 12:49 ` [PATCH 5.0 23/46] net-sysfs: Fix mem leak in netdev_register_kobject Greg Kroah-Hartman
2019-03-08 12:49 ` [PATCH 5.0 24/46] qmi_wwan: Add support for Quectel EG12/EM12 Greg Kroah-Hartman
2019-03-08 12:49 ` [PATCH 5.0 25/46] sctp: call iov_iter_revert() after sending ABORT Greg Kroah-Hartman
2019-03-08 12:49 ` [PATCH 5.0 26/46] sky2: Disable MSI on Dell Inspiron 1545 and Gateway P-79 Greg Kroah-Hartman
2019-03-08 12:50 ` [PATCH 5.0 27/46] team: Free BPF filter when unregistering netdev Greg Kroah-Hartman
2019-03-08 12:50 ` [PATCH 5.0 28/46] tipc: fix RDM/DGRAM connect() regression Greg Kroah-Hartman
2019-03-08 12:50 ` [PATCH 5.0 29/46] x86/CPU/AMD: Set the CPB bit unconditionally on F17h Greg Kroah-Hartman
2019-03-08 12:50 ` [PATCH 5.0 30/46] x86/boot/compressed/64: Do not read legacy ROM on EFI system Greg Kroah-Hartman
2019-03-10  6:10   ` hpa
2019-03-10  6:18     ` Greg Kroah-Hartman
2019-03-11  1:44       ` hpa
2019-03-12  9:50     ` Kirill A. Shutemov
2019-03-08 12:50 ` [PATCH 5.0 31/46] tracing: Fix event filters and triggers to handle negative numbers Greg Kroah-Hartman
2019-03-08 12:50 ` [PATCH 5.0 32/46] xhci: tegra: Prevent error pointer dereference Greg Kroah-Hartman
2019-03-08 12:50 ` [PATCH 5.0 33/46] usb: xhci: Fix for Enabling USB ROLE SWITCH QUIRK on INTEL_SUNRISEPOINT_LP_XHCI Greg Kroah-Hartman
2019-03-08 12:50 ` [PATCH 5.0 34/46] applicom: Fix potential Spectre v1 vulnerabilities Greg Kroah-Hartman
2019-03-08 12:50 ` [PATCH 5.0 35/46] alpha: wire up io_pgetevents system call Greg Kroah-Hartman
2019-03-08 12:50 ` [PATCH 5.0 36/46] MIPS: irq: Allocate accurate order pages for irq stack Greg Kroah-Hartman
2019-03-08 12:50 ` [PATCH 5.0 37/46] aio: Fix locking in aio_poll() Greg Kroah-Hartman
2019-03-08 12:50 ` [PATCH 5.0 38/46] xtensa: fix get_wchan Greg Kroah-Hartman
2019-03-08 12:50 ` [PATCH 5.0 39/46] gnss: sirf: fix premature wakeup interrupt enable Greg Kroah-Hartman
2019-03-08 12:50 ` [PATCH 5.0 40/46] USB: serial: cp210x: fix GPIO in autosuspend Greg Kroah-Hartman
2019-03-08 12:50 ` [PATCH 5.0 41/46] Revert "selftests: firmware: add CONFIG_FW_LOADER_USER_HELPER_FALLBACK to config" Greg Kroah-Hartman
2019-03-08 12:50 ` [PATCH 5.0 42/46] Revert "selftests: firmware: remove use of non-standard diff -Z option" Greg Kroah-Hartman
2019-03-08 12:50 ` [PATCH 5.0 43/46] selftests: firmware: fix verify_reqs() return value Greg Kroah-Hartman
2019-03-08 12:50 ` [PATCH 5.0 44/46] Bluetooth: btrtl: Restore old logic to assume firmware is already loaded Greg Kroah-Hartman
2019-03-08 12:50 ` [PATCH 5.0 45/46] Bluetooth: Fix locking in bt_accept_enqueue() for BH context Greg Kroah-Hartman
2019-03-08 12:50 ` [PATCH 5.0 46/46] exec: Fix mem leak in kernel_read_file Greg Kroah-Hartman
2019-03-08 16:06 ` [PATCH 5.0 00/46] 5.0.1-stable review Jon Hunter
2019-03-08 16:06   ` Jon Hunter
2019-03-08 16:35   ` Greg Kroah-Hartman
2019-03-08 20:58 ` shuah
2019-03-09  6:53   ` Greg Kroah-Hartman
2019-03-09  7:10 ` Naresh Kamboju
2019-03-09  7:23   ` Greg Kroah-Hartman
2019-03-09 22:36 ` Guenter Roeck
2019-03-10  6:05   ` Greg Kroah-Hartman

Reply instructions:

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

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

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

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

  git send-email \
    --in-reply-to=20190308124902.462820025@linuxfoundation.org \
    --to=gregkh@linuxfoundation.org \
    --cc=joel@joelfernandes.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=stable@vger.kernel.org \
    --cc=tkjos@google.com \
    /path/to/YOUR_REPLY

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

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