From patchwork Fri Feb 3 22:40:46 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: John Stultz X-Patchwork-Id: 93322 Delivered-To: patches@linaro.org Received: by 10.140.20.99 with SMTP id 90csp805015qgi; Fri, 3 Feb 2017 14:41:04 -0800 (PST) X-Received: by 10.99.184.18 with SMTP id p18mr21197141pge.20.1486161664754; Fri, 03 Feb 2017 14:41:04 -0800 (PST) Return-Path: Received: from mail-pg0-x22f.google.com (mail-pg0-x22f.google.com. [2607:f8b0:400e:c05::22f]) by mx.google.com with ESMTPS id m124si21967023pgm.123.2017.02.03.14.41.04 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 03 Feb 2017 14:41:04 -0800 (PST) Received-SPF: pass (google.com: domain of john.stultz@linaro.org designates 2607:f8b0:400e:c05::22f as permitted sender) client-ip=2607:f8b0:400e:c05::22f; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org; spf=pass (google.com: domain of john.stultz@linaro.org designates 2607:f8b0:400e:c05::22f as permitted sender) smtp.mailfrom=john.stultz@linaro.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: by mail-pg0-x22f.google.com with SMTP id v184so10009063pgv.3 for ; Fri, 03 Feb 2017 14:41:04 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=IPw/0Y9cJZiBRr4SzjoG1Ms6CktvqInmIZqMjtgui7U=; b=fOWuLN8ovJtHD/rASI6uCFe3hanxRxvDyK6D31vQkIHMjahQjS+GKE/pUbMtXEJbES ddPGP1q4vTtxL6UIe0P6dzP9Ju+uJ/IDFS0XgOh/rBForYyrQ37T9jgYHeUxxCOpKhso isSVO+yk3VejvBtVRRDGKIBQWUiuCRCgiExEA= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=IPw/0Y9cJZiBRr4SzjoG1Ms6CktvqInmIZqMjtgui7U=; b=BdWk1sqOkHI+yav8yXqFySkerGYMkGEAypfSY31ssBhJfY2Fjs0wg/aau32gu5pKXG pdp9KWLoyeYLBt8ySX6Avtw1fHUwsQOFD6qoDWZduiUs61iKvPmUnfft5YP9i+n/+c3V Gm54CJJsvjUe+wPfmag4BLX/5jqvx7EL8qlXkrXhc6XJRG3TetacVKs2Wm/0hLH7a8d8 swvdgJJrD59UUy0pM1nLdpx5OkTGWPzgdr72ojE/1pNGCYPaV7KY9NW1wjN3U2IBK3M/ fjmICm9YgpWxSl9MQifi12qThYhNfzJe6L6i8DH8CkVGcgey7vXKrPuct63BEsW2hcz4 +P/Q== X-Gm-Message-State: AIkVDXKrJwp9ejwz1UOoz90llnrHRpLorCBidUthGzGy9figNpkgZAO1snd0YQ0WSqXfoPGpjp4= X-Received: by 10.84.173.168 with SMTP id p37mr24594711plb.30.1486161664435; Fri, 03 Feb 2017 14:41:04 -0800 (PST) Return-Path: Received: from localhost.localdomain ([2601:1c2:1002:83f0:4e72:b9ff:fe99:466a]) by smtp.gmail.com with ESMTPSA id p26sm70102163pgn.39.2017.02.03.14.41.02 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 03 Feb 2017 14:41:03 -0800 (PST) From: John Stultz To: lkml Cc: Martijn Coenen , Greg Kroah-Hartman , =?utf-8?q?Arve_Hj=C3=B8nnev=C3=A5g?= , Amit Pundir , Serban Constantinescu , Dmitry Shmidt , Rom Lemarchand , Android Kernel Team , John Stultz Subject: [PATCH 2/8] binder: Support multiple context managers Date: Fri, 3 Feb 2017 14:40:46 -0800 Message-Id: <1486161652-2612-3-git-send-email-john.stultz@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1486161652-2612-1-git-send-email-john.stultz@linaro.org> References: <1486161652-2612-1-git-send-email-john.stultz@linaro.org> MIME-Version: 1.0 From: Martijn Coenen Move the context manager state into a separate struct context, and allow for each process to have its own context associated with it. Cc: Greg Kroah-Hartman Cc: Martijn Coenen Cc: Arve Hjønnevåg Cc: Amit Pundir Cc: Serban Constantinescu Cc: Dmitry Shmidt Cc: Rom Lemarchand Cc: Android Kernel Team Signed-off-by: Martijn Coenen [jstultz: Minor checkpatch fix] Signed-off-by: John Stultz --- drivers/android/binder.c | 59 +++++++++++++++++++++++++++++++----------------- 1 file changed, 38 insertions(+), 21 deletions(-) -- 2.7.4 diff --git a/drivers/android/binder.c b/drivers/android/binder.c index 331d2ab..59cb6d9 100644 --- a/drivers/android/binder.c +++ b/drivers/android/binder.c @@ -56,8 +56,6 @@ static HLIST_HEAD(binder_dead_nodes); static struct dentry *binder_debugfs_dir_entry_root; static struct dentry *binder_debugfs_dir_entry_proc; -static struct binder_node *binder_context_mgr_node; -static kuid_t binder_context_mgr_uid = INVALID_UID; static int binder_last_id; #define BINDER_DEBUG_ENTRY(name) \ @@ -215,6 +213,15 @@ static struct binder_transaction_log_entry *binder_transaction_log_add( return e; } +struct binder_context { + struct binder_node *binder_context_mgr_node; + kuid_t binder_context_mgr_uid; +}; + +static struct binder_context global_context = { + .binder_context_mgr_uid = INVALID_UID, +}; + struct binder_work { struct list_head entry; enum { @@ -330,6 +337,7 @@ struct binder_proc { int ready_threads; long default_priority; struct dentry *debugfs_entry; + struct binder_context *context; }; enum { @@ -934,8 +942,9 @@ static int binder_inc_node(struct binder_node *node, int strong, int internal, if (internal) { if (target_list == NULL && node->internal_strong_refs == 0 && - !(node == binder_context_mgr_node && - node->has_strong_ref)) { + !(node->proc && + node == node->proc->context->binder_context_mgr_node && + node->has_strong_ref)) { pr_err("invalid inc strong node for %d\n", node->debug_id); return -EINVAL; @@ -1036,6 +1045,7 @@ static struct binder_ref *binder_get_ref_for_node(struct binder_proc *proc, struct rb_node **p = &proc->refs_by_node.rb_node; struct rb_node *parent = NULL; struct binder_ref *ref, *new_ref; + struct binder_context *context = proc->context; while (*p) { parent = *p; @@ -1058,7 +1068,7 @@ static struct binder_ref *binder_get_ref_for_node(struct binder_proc *proc, rb_link_node(&new_ref->rb_node_node, parent, p); rb_insert_color(&new_ref->rb_node_node, &proc->refs_by_node); - new_ref->desc = (node == binder_context_mgr_node) ? 0 : 1; + new_ref->desc = (node == context->binder_context_mgr_node) ? 0 : 1; for (n = rb_first(&proc->refs_by_desc); n != NULL; n = rb_next(n)) { ref = rb_entry(n, struct binder_ref, rb_node_desc); if (ref->desc > new_ref->desc) @@ -1388,6 +1398,7 @@ static void binder_transaction(struct binder_proc *proc, struct binder_transaction *in_reply_to = NULL; struct binder_transaction_log_entry *e; uint32_t return_error; + struct binder_context *context = proc->context; e = binder_transaction_log_add(&binder_transaction_log); e->call_type = reply ? 2 : !!(tr->flags & TF_ONE_WAY); @@ -1448,7 +1459,7 @@ static void binder_transaction(struct binder_proc *proc, } target_node = ref->node; } else { - target_node = binder_context_mgr_node; + target_node = context->binder_context_mgr_node; if (target_node == NULL) { return_error = BR_DEAD_REPLY; goto err_no_context_mgr_node; @@ -1839,6 +1850,7 @@ static int binder_thread_write(struct binder_proc *proc, binder_size_t *consumed) { uint32_t cmd; + struct binder_context *context = proc->context; void __user *buffer = (void __user *)(uintptr_t)binder_buffer; void __user *ptr = buffer + *consumed; void __user *end = buffer + size; @@ -1865,10 +1877,10 @@ static int binder_thread_write(struct binder_proc *proc, if (get_user(target, (uint32_t __user *)ptr)) return -EFAULT; ptr += sizeof(uint32_t); - if (target == 0 && binder_context_mgr_node && + if (target == 0 && context->binder_context_mgr_node && (cmd == BC_INCREFS || cmd == BC_ACQUIRE)) { ref = binder_get_ref_for_node(proc, - binder_context_mgr_node); + context->binder_context_mgr_node); if (ref->desc != target) { binder_user_error("%d:%d tried to acquire reference to desc 0, got %d instead\n", proc->pid, thread->pid, @@ -2774,9 +2786,11 @@ static int binder_ioctl_set_ctx_mgr(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(); - if (binder_context_mgr_node != NULL) { + if (context->binder_context_mgr_node) { pr_err("BINDER_SET_CONTEXT_MGR already set\n"); ret = -EBUSY; goto out; @@ -2784,27 +2798,27 @@ static int binder_ioctl_set_ctx_mgr(struct file *filp) ret = security_binder_set_context_mgr(proc->tsk); if (ret < 0) goto out; - if (uid_valid(binder_context_mgr_uid)) { - if (!uid_eq(binder_context_mgr_uid, curr_euid)) { + if (uid_valid(context->binder_context_mgr_uid)) { + if (!uid_eq(context->binder_context_mgr_uid, curr_euid)) { pr_err("BINDER_SET_CONTEXT_MGR bad uid %d != %d\n", from_kuid(&init_user_ns, curr_euid), from_kuid(&init_user_ns, - binder_context_mgr_uid)); + context->binder_context_mgr_uid)); ret = -EPERM; goto out; } } else { - binder_context_mgr_uid = curr_euid; + context->binder_context_mgr_uid = curr_euid; } - binder_context_mgr_node = binder_new_node(proc, 0, 0); - if (binder_context_mgr_node == NULL) { + context->binder_context_mgr_node = binder_new_node(proc, 0, 0); + if (!context->binder_context_mgr_node) { ret = -ENOMEM; goto out; } - binder_context_mgr_node->local_weak_refs++; - binder_context_mgr_node->local_strong_refs++; - binder_context_mgr_node->has_strong_ref = 1; - binder_context_mgr_node->has_weak_ref = 1; + context->binder_context_mgr_node->local_weak_refs++; + context->binder_context_mgr_node->local_strong_refs++; + context->binder_context_mgr_node->has_strong_ref = 1; + context->binder_context_mgr_node->has_weak_ref = 1; out: return ret; } @@ -3039,6 +3053,7 @@ static int binder_open(struct inode *nodp, struct file *filp) get_task_struct(current); proc->tsk = current; proc->vma_vm_mm = current->mm; + proc->context = &global_context; INIT_LIST_HEAD(&proc->todo); init_waitqueue_head(&proc->wait); proc->default_priority = task_nice(current); @@ -3151,6 +3166,7 @@ static int binder_node_release(struct binder_node *node, int refs) static void binder_deferred_release(struct binder_proc *proc) { struct binder_transaction *t; + struct binder_context *context = proc->context; struct rb_node *n; int threads, nodes, incoming_refs, outgoing_refs, buffers, active_transactions, page_count; @@ -3160,11 +3176,12 @@ static void binder_deferred_release(struct binder_proc *proc) hlist_del(&proc->proc_node); - if (binder_context_mgr_node && binder_context_mgr_node->proc == proc) { + if (context->binder_context_mgr_node && + context->binder_context_mgr_node->proc == proc) { binder_debug(BINDER_DEBUG_DEAD_BINDER, "%s: %d context_mgr_node gone\n", __func__, proc->pid); - binder_context_mgr_node = NULL; + context->binder_context_mgr_node = NULL; } threads = 0;