| From foo@baz Sat Nov 13 12:18:28 PM CET 2021 |
| From: Todd Kjos <tkjos@google.com> |
| Date: Wed, 10 Nov 2021 15:00:23 -0800 |
| Subject: binder: use euid from cred instead of using task |
| To: stable@vger.kernel.org, gregkh@linuxfoundation.org, arve@android.com, tkjos@android.com, maco@android.com, christian@brauner.io, jmorris@namei.org, serge@hallyn.com, paul@paul-moore.com, stephen.smalley.work@gmail.com, eparis@parisplace.org, keescook@chromium.org, jannh@google.com, jeffv@google.com, zohar@linux.ibm.com, linux-security-module@vger.kernel.org, selinux@vger.kernel.org, devel@driverdev.osuosl.org |
| Cc: joel@joelfernandes.org, kernel-team@android.com, Todd Kjos <tkjos@google.com>, Casey Schaufler <casey@schaufler-ca.com> |
| Message-ID: <20211110230025.3272776-1-tkjos@google.com> |
| |
| From: Todd Kjos <tkjos@google.com> |
| |
| commit 29bc22ac5e5bc63275e850f0c8fc549e3d0e306b upstream. |
| |
| Save the 'struct cred' associated with a binder process |
| at initial open to avoid potential race conditions |
| when converting to an euid. |
| |
| Set a transaction's sender_euid from the 'struct cred' |
| saved at binder_open() instead of looking up the euid |
| from the binder proc's 'struct task'. This ensures |
| the euid is associated with the security context that |
| of the task that opened binder. |
| |
| Cc: stable@vger.kernel.org # 4.4+ |
| Fixes: 457b9a6f09f0 ("Staging: android: add binder driver") |
| Signed-off-by: Todd Kjos <tkjos@google.com> |
| Suggested-by: Stephen Smalley <stephen.smalley.work@gmail.com> |
| Suggested-by: Jann Horn <jannh@google.com> |
| Acked-by: Casey Schaufler <casey@schaufler-ca.com> |
| Signed-off-by: Paul Moore <paul@paul-moore.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| drivers/android/binder.c | 8 +++++++- |
| 1 file changed, 7 insertions(+), 1 deletion(-) |
| |
| --- a/drivers/android/binder.c |
| +++ b/drivers/android/binder.c |
| @@ -424,6 +424,9 @@ enum binder_deferred_state { |
| * (invariant after initialized) |
| * @tsk task_struct for group_leader of process |
| * (invariant after initialized) |
| + * @cred struct cred associated with the `struct file` |
| + * in binder_open() |
| + * (invariant after initialized) |
| * @deferred_work_node: element for binder_deferred_list |
| * (protected by binder_deferred_lock) |
| * @deferred_work: bitmap of deferred work to perform |
| @@ -469,6 +472,7 @@ struct binder_proc { |
| struct list_head waiting_threads; |
| int pid; |
| struct task_struct *tsk; |
| + const struct cred *cred; |
| struct hlist_node deferred_work_node; |
| int deferred_work; |
| bool is_dead; |
| @@ -3091,7 +3095,7 @@ static void binder_transaction(struct bi |
| t->from = thread; |
| else |
| t->from = NULL; |
| - t->sender_euid = task_euid(proc->tsk); |
| + t->sender_euid = proc->cred->euid; |
| t->to_proc = target_proc; |
| t->to_thread = target_thread; |
| t->code = tr->code; |
| @@ -4707,6 +4711,7 @@ static void binder_free_proc(struct bind |
| } |
| binder_alloc_deferred_release(&proc->alloc); |
| put_task_struct(proc->tsk); |
| + put_cred(proc->cred); |
| binder_stats_deleted(BINDER_STAT_PROC); |
| kfree(proc); |
| } |
| @@ -5234,6 +5239,7 @@ static int binder_open(struct inode *nod |
| spin_lock_init(&proc->outer_lock); |
| get_task_struct(current->group_leader); |
| proc->tsk = current->group_leader; |
| + proc->cred = get_cred(filp->f_cred); |
| INIT_LIST_HEAD(&proc->todo); |
| proc->default_priority = task_nice(current); |
| /* binderfs stashes devices in i_private */ |