diff options
| author | Debabrata Banerjee <dbanerje@akamai.com> | 2014-12-10 15:45:04 -0800 | 
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-12-10 17:41:09 -0800 | 
| 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  		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; | 
