diff options
author | Török Edwin <edwintorok@gmail.com> | 2008-11-23 05:39:07 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-11-23 05:53:49 -0500 |
commit | cffa10aecb6891f090a4d53a075bc40c082c45fc (patch) | |
tree | 825b264f70bc5c5aaa2882e8dfba75e366238b1e /kernel/trace | |
parent | 8d7c6a96164651dbbab449ef0b5c20ae1f76a3a1 (diff) |
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>
Diffstat (limited to 'kernel/trace')
-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 dedf35f36971..4c3bd82cec49 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, | |||
1462 | int ret = 1; | 1462 | int ret = 1; |
1463 | 1463 | ||
1464 | if (mm) { | 1464 | if (mm) { |
1465 | const struct vm_area_struct *vma = find_vma(mm, ip); | 1465 | const struct vm_area_struct *vma; |
1466 | |||
1467 | down_read(&mm->mmap_sem); | ||
1468 | vma = find_vma(mm, ip); | ||
1466 | if (vma) { | 1469 | if (vma) { |
1467 | file = vma->vm_file; | 1470 | file = vma->vm_file; |
1468 | vmstart = vma->vm_start; | 1471 | vmstart = vma->vm_start; |
1469 | } | 1472 | } |
1473 | up_read(&mm->mmap_sem); | ||
1470 | } | 1474 | } |
1471 | if (file) { | 1475 | if (file) { |
1472 | ret = trace_seq_path(s, &file->f_path); | 1476 | 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, | |||
1494 | */ | 1498 | */ |
1495 | rcu_read_lock(); | 1499 | rcu_read_lock(); |
1496 | task = find_task_by_vpid(entry->ent.tgid); | 1500 | task = find_task_by_vpid(entry->ent.tgid); |
1497 | rcu_read_unlock(); | ||
1498 | |||
1499 | if (task) | 1501 | if (task) |
1500 | mm = get_task_mm(task); | 1502 | mm = get_task_mm(task); |
1503 | rcu_read_unlock(); | ||
1501 | } | 1504 | } |
1502 | 1505 | ||
1503 | for (i = 0; i < FTRACE_STACK_ENTRIES; i++) { | 1506 | for (i = 0; i < FTRACE_STACK_ENTRIES; i++) { |