fs/proc/task_nommu.c: don't use priv->task->mm
I do not know if CONFIG_PREEMPT/SMP is possible without CONFIG_MMU but the usage of task->mm in m_stop(). The task can exit/exec before we take mmap_sem, in this case m_stop() can hit NULL or unlock the wrong rw_semaphore. Also, this code uses priv->task != NULL to decide whether we need up_read/mmput. This is correct, but we will probably kill priv->task. Change m_start/m_stop to rely on IS_ERR_OR_NULL() like task_mmu.c does. Signed-off-by: Oleg Nesterov <oleg@redhat.com> Cc: Kirill A. Shutemov <kirill.shutemov@linux.intel.com> Cc: Cyrill Gorcunov <gorcunov@openvz.org> Cc: "Eric W. Biederman" <ebiederm@xmission.com> Acked-by: Greg Ungerer <gerg@uclinux.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
27692cd56e
commit
47fecca15c
1 changed files with 10 additions and 8 deletions
|
@ -217,17 +217,17 @@ static void *m_start(struct seq_file *m, loff_t *pos)
|
||||||
return ERR_PTR(-ESRCH);
|
return ERR_PTR(-ESRCH);
|
||||||
|
|
||||||
mm = priv->mm;
|
mm = priv->mm;
|
||||||
if (!mm || !atomic_inc_not_zero(&mm->mm_users)) {
|
if (!mm || !atomic_inc_not_zero(&mm->mm_users))
|
||||||
put_task_struct(priv->task);
|
|
||||||
priv->task = NULL;
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
|
||||||
down_read(&mm->mmap_sem);
|
|
||||||
|
|
||||||
|
down_read(&mm->mmap_sem);
|
||||||
/* start from the Nth VMA */
|
/* start from the Nth VMA */
|
||||||
for (p = rb_first(&mm->mm_rb); p; p = rb_next(p))
|
for (p = rb_first(&mm->mm_rb); p; p = rb_next(p))
|
||||||
if (n-- == 0)
|
if (n-- == 0)
|
||||||
return p;
|
return p;
|
||||||
|
|
||||||
|
up_read(&mm->mmap_sem);
|
||||||
|
mmput(mm);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -235,11 +235,13 @@ static void m_stop(struct seq_file *m, void *_vml)
|
||||||
{
|
{
|
||||||
struct proc_maps_private *priv = m->private;
|
struct proc_maps_private *priv = m->private;
|
||||||
|
|
||||||
|
if (!IS_ERR_OR_NULL(_vml)) {
|
||||||
|
up_read(&priv->mm->mmap_sem);
|
||||||
|
mmput(priv->mm);
|
||||||
|
}
|
||||||
if (priv->task) {
|
if (priv->task) {
|
||||||
struct mm_struct *mm = priv->task->mm;
|
|
||||||
up_read(&mm->mmap_sem);
|
|
||||||
mmput(mm);
|
|
||||||
put_task_struct(priv->task);
|
put_task_struct(priv->task);
|
||||||
|
priv->task = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue