binder: make FIFO inheritance a per-context option

Add a new ioctl to binder to control whether FIFO inheritance should happen.
In particular, hwbinder should inherit FIFO priority from callers, but standard
binder threads should not.

Test: boots

bug 36516194

Signed-off-by: Tim Murray <timmurray@google.com>
Change-Id: I8100c4364b7d15d1bf00a8ca5c286e4d4b23ce85
diff --git a/drivers/staging/android/binder.c b/drivers/staging/android/binder.c
index 08752e0..d14584d 100644
--- a/drivers/staging/android/binder.c
+++ b/drivers/staging/android/binder.c
@@ -243,6 +243,7 @@
 	struct binder_node *binder_context_mgr_node;
 	kuid_t binder_context_mgr_uid;
 	const char *name;
+	bool inherit_fifo_prio;
 };
 
 struct binder_device {
@@ -623,11 +624,12 @@
 	struct binder_transaction *t, struct binder_node *target_node)
 {
 	bool oneway = !!(t->flags & TF_ONE_WAY);
+	bool inherit_fifo = target_node->proc->context->inherit_fifo_prio;
 
 	t->saved_sched_policy = current->policy;
 	t->saved_priority = task_nice(current);
 
-	if (!oneway && is_rt_policy(t->sched_policy) &&
+	if (!oneway && inherit_fifo && is_rt_policy(t->sched_policy) &&
 	    !is_rt_policy(current->policy)) {
 		/* Transaction was initiated with a real-time policy,
 		 * but we are not; temporarily upgrade this thread to RT.
@@ -3615,6 +3617,34 @@
 	return ret;
 }
 
+static int binder_ioctl_set_inherit_fifo_prio(struct file *filp)
+{
+	int ret = 0;
+	struct binder_proc *proc = filp->private_data;
+	struct binder_context *context = proc->context;
+
+	kuid_t curr_euid = current_euid();
+	mutex_lock(&binder_context_mgr_node_lock);
+
+	if (uid_valid(context->binder_context_mgr_uid)) {
+		if (!uid_eq(context->binder_context_mgr_uid, curr_euid)) {
+			pr_err("BINDER_SET_INHERIT_FIFO_PRIO bad uid %d != %d\n",
+			       from_kuid(&init_user_ns, curr_euid),
+			       from_kuid(&init_user_ns,
+					 context->binder_context_mgr_uid));
+			ret = -EPERM;
+			goto out;
+		}
+	}
+
+	context->inherit_fifo_prio = true;
+
+ out:
+	mutex_unlock(&binder_context_mgr_node_lock);
+	return ret;
+}
+
+
 static int binder_ioctl_set_ctx_mgr(struct file *filp)
 {
 	int ret = 0;
@@ -3729,6 +3759,12 @@
 		if (ret)
 			goto err;
 		break;
+	case BINDER_SET_INHERIT_FIFO_PRIO:
+		ret = binder_ioctl_set_inherit_fifo_prio(filp);
+		if (ret)
+			goto err;
+		break;
+
 	case BINDER_THREAD_EXIT:
 		binder_debug(BINDER_DEBUG_THREADS, "%d:%d exit\n",
 			     proc->pid, thread->pid);
@@ -4635,6 +4671,7 @@
 	seq_printf(m, "proc %d%s\n", proc->pid,
 			proc->is_zombie ? " (ZOMBIE)" : "");
 	seq_printf(m, "context %s\n", proc->context->name);
+	seq_printf(m, "context FIFO: %d\n", proc->context->inherit_fifo_prio);
 	seq_printf(m, "  cleared: procs=%d nodes=%d threads=%d\n",
 			cleared_procs, cleared_nodes, cleared_threads);
 	zombie_threads = zombie_nodes = zombie_refs = count = 0;
diff --git a/drivers/staging/android/uapi/binder.h b/drivers/staging/android/uapi/binder.h
index 4212aff..2c67b87 100644
--- a/drivers/staging/android/uapi/binder.h
+++ b/drivers/staging/android/uapi/binder.h
@@ -190,6 +190,7 @@
 #define BINDER_SET_CONTEXT_MGR		_IOW('b', 7, __s32)
 #define BINDER_THREAD_EXIT		_IOW('b', 8, __s32)
 #define BINDER_VERSION			_IOWR('b', 9, struct binder_version)
+#define BINDER_SET_INHERIT_FIFO_PRIO	_IO('b', 10)
 
 /*
  * NOTE: Two special error codes you should check for when calling