Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=59cd0cbc75367b82f704f63b104117462275060d
Commit:     59cd0cbc75367b82f704f63b104117462275060d
Parent:     7695650a924a6859910c8c19dfa43b4d08224d66
Author:     Darrick J. Wong <[EMAIL PROTECTED]>
AuthorDate: Tue May 8 00:25:47 2007 -0700
Committer:  Linus Torvalds <[EMAIL PROTECTED]>
CommitDate: Tue May 8 11:15:02 2007 -0700

    Fix race between proc_readdir and remove_proc_entry
    
    Fix the following race:
    
    proc_readdir                                remove_proc_entry
    ============                                =================
    
    spin_lock(&proc_subdir_lock);
    [choose PDE to start filldir from]
    spin_unlock(&proc_subdir_lock);
                                        spin_lock(&proc_subdir_lock);
                                        [find PDE]
                                        [free PDE, refcount is 0]
                                        spin_unlock(&proc_subdir_lock);
                    /* boom */
    if (filldir(dirent, de->name, ...
    
    [de_put on error path --adobriyan]
    Signed-off-by: Darrick J. Wong <[EMAIL PROTECTED]>
    Signed-off-by: Alexey Dobriyan <[EMAIL PROTECTED]>
    Cc: "Eric W. Biederman" <[EMAIL PROTECTED]>
    Signed-off-by: Andrew Morton <[EMAIL PROTECTED]>
    Signed-off-by: Linus Torvalds <[EMAIL PROTECTED]>
---
 fs/proc/generic.c |   11 +++++++++--
 1 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/fs/proc/generic.c b/fs/proc/generic.c
index 22a08ff..8a40e15 100644
--- a/fs/proc/generic.c
+++ b/fs/proc/generic.c
@@ -478,14 +478,21 @@ int proc_readdir(struct file * filp,
                        }
 
                        do {
+                               struct proc_dir_entry *next;
+
                                /* filldir passes info to user space */
+                               de_get(de);
                                spin_unlock(&proc_subdir_lock);
                                if (filldir(dirent, de->name, de->namelen, 
filp->f_pos,
-                                           de->low_ino, de->mode >> 12) < 0)
+                                           de->low_ino, de->mode >> 12) < 0) {
+                                       de_put(de);
                                        goto out;
+                               }
                                spin_lock(&proc_subdir_lock);
                                filp->f_pos++;
-                               de = de->next;
+                               next = de->next;
+                               de_put(de);
+                               de = next;
                        } while (de);
                        spin_unlock(&proc_subdir_lock);
        }
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to