diff options
author | Debabrata Banerjee <dbanerje@akamai.com> | 2014-12-10 18:45:04 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-12-10 20:41:09 -0500 |
commit | b208d54b75399b276b05f9e70cce8d3a59a42547 (patch) | |
tree | 6fceaa2169ca97be38c6dd7561542194dbca553b /fs/proc/generic.c | |
parent | 710585d4922fd315f2cada8fbe550ae8ed23e994 (diff) |
procfs: fix error handling of proc_register()
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>
Diffstat (limited to 'fs/proc/generic.c')
-rw-r--r-- | fs/proc/generic.c | 9 |
1 files changed, 8 insertions, 1 deletions
diff --git a/fs/proc/generic.c b/fs/proc/generic.c index 9f8fa1e5e8aa..be39c6feb3e5 100644 --- a/fs/proc/generic.c +++ b/fs/proc/generic.c | |||
@@ -369,14 +369,21 @@ static int proc_register(struct proc_dir_entry * dir, struct proc_dir_entry * dp | |||
369 | dp->proc_iops = &proc_file_inode_operations; | 369 | dp->proc_iops = &proc_file_inode_operations; |
370 | } else { | 370 | } else { |
371 | WARN_ON(1); | 371 | WARN_ON(1); |
372 | proc_free_inum(dp->low_ino); | ||
372 | return -EINVAL; | 373 | return -EINVAL; |
373 | } | 374 | } |
374 | 375 | ||
375 | spin_lock(&proc_subdir_lock); | 376 | spin_lock(&proc_subdir_lock); |
376 | dp->parent = dir; | 377 | dp->parent = dir; |
377 | if (pde_subdir_insert(dir, dp) == false) | 378 | if (pde_subdir_insert(dir, dp) == false) { |
378 | WARN(1, "proc_dir_entry '%s/%s' already registered\n", | 379 | WARN(1, "proc_dir_entry '%s/%s' already registered\n", |
379 | dir->name, dp->name); | 380 | dir->name, dp->name); |
381 | spin_unlock(&proc_subdir_lock); | ||
382 | if (S_ISDIR(dp->mode)) | ||
383 | dir->nlink--; | ||
384 | proc_free_inum(dp->low_ino); | ||
385 | return -EEXIST; | ||
386 | } | ||
380 | spin_unlock(&proc_subdir_lock); | 387 | spin_unlock(&proc_subdir_lock); |
381 | 388 | ||
382 | return 0; | 389 | return 0; |