lkml.org 
[lkml]   [2007]   [Nov]   [17]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[PATCH] task_pid_nr_ns() breaks proc_pid_readdir()
    proc_pid_readdir:

    for (...; ...; task = next_tgid(tgid + 1, ns)) {
    tgid = task_pid_nr_ns(task, ns);
    ... use tgid ...

    The first problem is that task_pid_nr_ns() can race with RCU and read the
    freed memory.

    However, rcu_read_lock() can't help. next_tgid() returns a pinned task_struct,
    but the task can be released (and it's pid detached) before task_pid_nr_ns()
    reads the pid_t value. In that case task_pid_nr_ns() returns 0 thus breaking
    the whole logic.

    Make sure that task_pid_nr_ns() returns !0 before updating tgid. Note that
    next_tgid(tgid + 1) can find the same "struct pid" again, but we shouldn't
    go into the endless loop because pid_task(PIDTYPE_PID) must return NULL in
    this case, so next_tgid() can't return the same task.

    Signed-off-by: Oleg Nesterov <oleg@tv-sign.ru>

    --- 24/fs/proc/base.c~pprd 2007-10-25 16:22:11.000000000 +0400
    +++ 24/fs/proc/base.c 2007-11-17 20:58:14.000000000 +0300
    @@ -2481,7 +2481,15 @@ int proc_pid_readdir(struct file * filp,
    for (task = next_tgid(tgid, ns);
    task;
    put_task_struct(task), task = next_tgid(tgid + 1, ns)) {
    - tgid = task_pid_nr_ns(task, ns);
    + int nr;
    +
    + rcu_read_lock();
    + nr = task_pid_nr_ns(task, ns);
    + rcu_read_unlock();
    + if (!nr)
    + continue;
    +
    + tgid = nr;
    filp->f_pos = tgid + TGID_OFFSET;
    if (proc_pid_fill_cache(filp, dirent, filldir, task, tgid) < 0) {
    put_task_struct(task);
    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

    \
     
     \ /
      Last update: 2007-11-17 19:19    [W:0.021 / U:118.960 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site