]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
proc: fix task_struct memleak
authorVasiliy Kulikov <segoon@openwall.com>
Fri, 16 Dec 2011 04:50:43 +0000 (15:50 +1100)
committerStephen Rothwell <sfr@canb.auug.org.au>
Wed, 21 Dec 2011 06:02:07 +0000 (17:02 +1100)
proc_pid_permission() doesn't put task_struct on every /proc/$pid/
access.  A demo from Hugh Dickins:

while :; do ps; grep KernelStack /proc/meminfo; sleep 1; done

Reported-by: Hugh Dickins <hughd@google.com>
Tested-by: Hugh Dickins <hughd@google.com>
Signed-off-by: Vasiliy Kulikov <segoon@openwall.com>
Cc: Alexey Dobriyan <adobriyan@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
fs/proc/base.c

index f201e6431dfab2e3c0ff13397eeaff927d4a82ba..22524d0adfe8a3d05a54780f7d80d7e9b4db6916 100644 (file)
@@ -650,9 +650,14 @@ static bool has_pid_permissions(struct pid_namespace *pid,
 static int proc_pid_permission(struct inode *inode, int mask)
 {
        struct pid_namespace *pid = inode->i_sb->s_fs_info;
-       struct task_struct *task = get_proc_task(inode);
+       struct task_struct *task;
+       bool has_perms;
+
+       task = get_proc_task(inode);
+       has_perms = has_pid_permissions(pid, task, 1);
+       put_task_struct(task);
 
-       if (!has_pid_permissions(pid, task, 1)) {
+       if (!has_perms) {
                if (pid->hide_pid == 2) {
                        /*
                         * Let's make getdents(), stat(), and open()