diff options
| author | Török Edwin <edwintorok@gmail.com> | 2008-11-23 12:39:07 +0200 | 
|---|---|---|
| committer | Ingo Molnar <mingo@elte.hu> | 2008-11-23 11:53:49 +0100 | 
| commit | cffa10aecb6891f090a4d53a075bc40c082c45fc (patch) | |
| tree | 825b264f70bc5c5aaa2882e8dfba75e366238b1e | |
| parent | 8d7c6a96164651dbbab449ef0b5c20ae1f76a3a1 (diff) | |
| download | olio-linux-3.10-cffa10aecb6891f090a4d53a075bc40c082c45fc.tar.xz olio-linux-3.10-cffa10aecb6891f090a4d53a075bc40c082c45fc.zip  | |
tracing/stack-tracer: fix locking and refcounts
Impact: fix refcounting/object-access bug
Hold mmap_sem while looking up/accessing vma.
Hold the RCU lock while using the task we looked up.
Signed-off-by: Török Edwin <edwintorok@gmail.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
| -rw-r--r-- | kernel/trace/trace.c | 9 | 
1 files changed, 6 insertions, 3 deletions
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index dedf35f3697..4c3bd82cec4 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -1462,11 +1462,15 @@ static inline int seq_print_user_ip(struct trace_seq *s, struct mm_struct *mm,  	int ret = 1;  	if (mm) { -		const struct vm_area_struct *vma = find_vma(mm, ip); +		const struct vm_area_struct *vma; + +		down_read(&mm->mmap_sem); +		vma = find_vma(mm, ip);  		if (vma) {  			file = vma->vm_file;  			vmstart = vma->vm_start;  		} +		up_read(&mm->mmap_sem);  	}  	if (file) {  		ret = trace_seq_path(s, &file->f_path); @@ -1494,10 +1498,9 @@ seq_print_userip_objs(const struct userstack_entry *entry, struct trace_seq *s,  		 */  		rcu_read_lock();  		task = find_task_by_vpid(entry->ent.tgid); -		rcu_read_unlock(); -  		if (task)  			mm = get_task_mm(task); +		rcu_read_unlock();  	}  	for (i = 0; i < FTRACE_STACK_ENTRIES; i++) {  |