kernel_optimize_test/fs/proc
Oleg Nesterov 940fe4793a proc: fix the potential use-after-free in first_tid()
proc_task_readdir() verifies that the result of get_proc_task() is
pid_alive() and thus its ->group_leader is fine too.  However this is not
necessarily true after rcu_read_unlock(), we need to recheck this again
after first_tid() does rcu_read_lock().  Otherwise
leader->thread_group.next (used by next_thread()) can be invalid if the
rcu grace period expires in between.

The race is subtle and unlikely, but still it is possible afaics.  To
simplify lets ignore the "likely" case when tid != 0, f_version can be
cleared by proc_task_operations->llseek().

Suppose we have a main thread M and its subthread T.  Suppose that f_pos
== 3, iow first_tid() should return T.  Now suppose that the following
happens between rcu_read_unlock() and rcu_read_lock():

	1. T execs and becomes the new leader. This removes M from
	    ->thread_group but next_thread(M) is still T.

	2. T creates another thread X which does exec as well, T
	   goes away.

	3. X creates another subthread, this increments nr_threads.

	4. first_tid() does next_thread(M) and returns the already
	   dead T.

Note also that we need 2.  and 3.  only because of get_nr_threads() check,
and this check was supposed to be optimization only.

Signed-off-by: Oleg Nesterov <oleg@redhat.com>
Cc: "Eric W. Biederman" <ebiederm@xmission.com>
Cc: Michal Hocko <mhocko@suse.cz>
Cc: Sameer Nanda <snanda@chromium.org>
Cc: Sergey Dyasly <dserrg@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2014-01-23 16:37:01 -08:00
..
array.c proc: cleanup/simplify get_task_state/task_state_array 2014-01-23 16:37:01 -08:00
base.c proc: fix the potential use-after-free in first_tid() 2014-01-23 16:37:01 -08:00
cmdline.c
consoles.c seq_file: remove "%n" usage from seq_file users 2013-11-15 09:32:20 +09:00
cpuinfo.c
devices.c
fd.c
fd.h
generic.c consolidate simple ->d_delete() instances 2013-11-15 22:04:17 -05:00
inode.c procfs: also fix proc_reg_get_unmapped_area() for !MMU case 2013-12-12 18:19:26 -08:00
internal.h
interrupts.c
Kconfig
kcore.c
kmsg.c
loadavg.c
Makefile
meminfo.c /proc/meminfo: provide estimated available memory 2014-01-21 16:19:43 -08:00
namespaces.c consolidate simple ->d_delete() instances 2013-11-15 22:04:17 -05:00
nommu.c seq_file: remove "%n" usage from seq_file users 2013-11-15 09:32:20 +09:00
page.c fs/proc/page.c: add PageAnon check to surely detect thp 2014-01-23 16:36:50 -08:00
proc_devtree.c
proc_net.c
proc_sysctl.c
proc_tty.c
root.c
self.c
softirqs.c
stat.c
task_mmu.c seq_file: remove "%n" usage from seq_file users 2013-11-15 09:32:20 +09:00
task_nommu.c seq_file: remove "%n" usage from seq_file users 2013-11-15 09:32:20 +09:00
uptime.c
version.c
vmcore.c