summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdrian Salido <salidoa@google.com>2017-03-03 12:06:36 +0100
committerBertolin, PierreX <pierrex.bertolin@intel.com>2017-03-14 01:54:01 -0700
commit1199dbf571d51510c7bf4d62d7afef2d67cccca0 (patch)
tree0ce73018e5b4ad8b203a1aeb52900648ea7c26b6
parent105faac656d3c861ab7cfe39c666d7c2a4286870 (diff)
downloadx86-1199dbf571d51510c7bf4d62d7afef2d67cccca0.tar.gz
fs/proc/array.c: make safe access to group_leader
As mentioned in commit 52ee2dfdd4f51cf422ea6a96a0846dc94244aa37 ("pids: refactor vnr/nr_ns helpers to make them safe"). *_nr_ns helpers used to be buggy. The commit addresses most of the helpers but is missing task_tgid_xxx() Without this protection there is a possible use after free reported by kasan instrumented kernel: ================================================================== BUG: KASAN: use-after-free in task_tgid_nr_ns+0x2c/0x44 at addr *** Read of size 8 by task cat/2472 CPU: 1 PID: 2472 Comm: cat Tainted: **** Hardware name: Google Tegra210 Smaug Rev 1,3+ (DT) Call trace: [<ffffffc00020ad2c>] dump_backtrace+0x0/0x17c [<ffffffc00020aec0>] show_stack+0x18/0x24 [<ffffffc0011573d0>] dump_stack+0x94/0x100 [<ffffffc0003c7dc0>] kasan_report+0x308/0x554 [<ffffffc0003c7518>] __asan_load8+0x20/0x7c [<ffffffc00025a54c>] task_tgid_nr_ns+0x28/0x44 [<ffffffc00046951c>] proc_pid_status+0x444/0x1080 [<ffffffc000460f60>] proc_single_show+0x8c/0xdc [<ffffffc0004081b0>] seq_read+0x2e8/0x6f0 [<ffffffc0003d1420>] vfs_read+0xd8/0x1e0 [<ffffffc0003d1b98>] SyS_read+0x68/0xd4 Accessing group_leader while holding rcu_lock and using the now safe helpers introduced in the commit mentioned, this race condition is addressed. Bug: 31495866 Change-Id: I8dc530762759b29f662a14b5832b5801d1e75ae2 Signed-off-by: Adrian Salido <salidoa@google.com> Signed-off-by: Louis, FabienX <fabienx.louis@intel.com> Signed-off-by: Simon Dubray <simonx.dubray@intel.com> Tracked-On: https://jira01.devtools.intel.com/browse/AW-4548 Reviewed-on: https://android.intel.com/571450 Reviewed-by: Tasayco Loarte, VictorX <victorx.tasayco.loarte@intel.com>
-rw-r--r--fs/proc/array.c12
1 files changed, 7 insertions, 5 deletions
diff --git a/fs/proc/array.c b/fs/proc/array.c
index b6c00ce0e29e..9bc0569e9c6f 100644
--- a/fs/proc/array.c
+++ b/fs/proc/array.c
@@ -147,18 +147,20 @@ static inline void task_state(struct seq_file *m, struct pid_namespace *ns,
int g;
struct task_struct *tracer;
const struct cred *cred;
- pid_t ppid, tpid = 0, tgid, ngid;
+ pid_t ppid = 0, tpid = 0, tgid, ngid;
unsigned int max_fds = 0;
+ struct task_struct *leader = NULL;
rcu_read_lock();
- ppid = pid_alive(p) ?
- task_tgid_nr_ns(rcu_dereference(p->real_parent), ns) : 0;
+ if (pid_alive(p)) {
+ ppid = task_tgid_nr_ns(rcu_dereference(p->real_parent), ns);
+ leader = p->group_leader;
+ }
tracer = ptrace_parent(p);
if (tracer)
tpid = task_pid_nr_ns(tracer, ns);
-
- tgid = task_tgid_nr_ns(p, ns);
+ tgid = leader ? task_pid_nr_ns(leader, ns) : 0;
ngid = task_numa_group_id(p);
cred = get_task_cred(p);