procfs: fix error handling of proc_register()
authorDebabrata Banerjee <dbanerje@akamai.com>
Wed, 10 Dec 2014 23:45:04 +0000 (15:45 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 11 Dec 2014 01:41:09 +0000 (17:41 -0800)
proc_register() error paths are leaking inodes and directory refcounts.

Signed-off-by: Debabrata Banerjee <dbanerje@akamai.com>
Cc: Alexander Viro <viro@zeniv.linux.org.uk>
Acked-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
fs/proc/generic.c

index 9f8fa1e5e8aa82b02318862ed8558252ec2c7a4e..be39c6feb3e56c5f12bd1afab9c7b1867959b77c 100644 (file)
@@ -369,14 +369,21 @@ static int proc_register(struct proc_dir_entry * dir, struct proc_dir_entry * dp
                dp->proc_iops = &proc_file_inode_operations;
        } else {
                WARN_ON(1);
+               proc_free_inum(dp->low_ino);
                return -EINVAL;
        }
 
        spin_lock(&proc_subdir_lock);
        dp->parent = dir;
-       if (pde_subdir_insert(dir, dp) == false)
+       if (pde_subdir_insert(dir, dp) == false) {
                WARN(1, "proc_dir_entry '%s/%s' already registered\n",
                     dir->name, dp->name);
+               spin_unlock(&proc_subdir_lock);
+               if (S_ISDIR(dp->mode))
+                       dir->nlink--;
+               proc_free_inum(dp->low_ino);
+               return -EEXIST;
+       }
        spin_unlock(&proc_subdir_lock);
 
        return 0;