diff options
author | Riley Andrews <riandrews@android.com> | 2016-02-09 21:05:33 -0800 |
---|---|---|
committer | Mattias Nissler <mnissler@google.com> | 2016-07-20 16:18:21 +0200 |
commit | 42fb0043257cc3b1f5db41194feb8cd0abdd15f5 (patch) | |
tree | 8cb40ef6b8878d44e7ebf9ad90fb0451db8938e9 | |
parent | 388508a089416ad72b5ac9b7d98d4942844a728f (diff) | |
download | v4.4-42fb0043257cc3b1f5db41194feb8cd0abdd15f5.tar.gz |
UPSTREAM: android: drivers: Avoid debugfs race in binder
If a /d/binder/proc/[pid] entry is kept open after linux has
torn down the associated process, binder_proc_show can deference
an invalid binder_proc that has been stashed in the debugfs
inode. Validate that the binder_proc ptr passed into binder_proc_show
has not been freed by looking for it within the global process list
whilst the global lock is held. If the ptr is not valid, print nothing.
Cc: Colin Cross <ccross@android.com>
Cc: Arve Hjønnevåg <arve@android.com>
Cc: Dmitry Shmidt <dimitrysh@google.com>
Cc: Rom Lemarchand <romlem@google.com>
Cc: Serban Constantinescu <serban.constantinescu@arm.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Android Kernel Team <kernel-team@android.com>
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
[jstultz: Minor commit message tweaks]
Signed-off-by: John Stultz <john.stultz@linaro.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Bug: None
Patchset: binder
(cherry-picked from 83050a4e21979fe1821916fce2fca36255569ed3)
Signed-off-by: Mattias Nissler <mnissler@google.com>
Change-Id: Id3defe7e7e9fd398d75c775f93fff86295d1bdfc
-rw-r--r-- | drivers/android/binder.c | 15 |
1 files changed, 13 insertions, 2 deletions
diff --git a/drivers/android/binder.c b/drivers/android/binder.c index 25609dd7c2d0..57f52a2afa35 100644 --- a/drivers/android/binder.c +++ b/drivers/android/binder.c @@ -3600,13 +3600,24 @@ static int binder_transactions_show(struct seq_file *m, void *unused) static int binder_proc_show(struct seq_file *m, void *unused) { + struct binder_proc *itr; struct binder_proc *proc = m->private; int do_lock = !binder_debug_no_lock; + bool valid_proc = false; if (do_lock) binder_lock(__func__); - seq_puts(m, "binder proc state:\n"); - print_binder_proc(m, proc, 1); + + hlist_for_each_entry(itr, &binder_procs, proc_node) { + if (itr == proc) { + valid_proc = true; + break; + } + } + if (valid_proc) { + seq_puts(m, "binder proc state:\n"); + print_binder_proc(m, proc, 1); + } if (do_lock) binder_unlock(__func__); return 0; |