summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Kiszka <jan.kiszka@web.de>2010-02-08 13:12:05 +0300
committerDavid S. Miller <davem@davemloft.net>2010-02-17 03:01:17 +0300
commitc947862f9126983537a4cc11e07d26882d60b7e7 (patch)
tree335ae3483ea540877ff5230c3f43288847300417
parent54716e3beb0ab20c49471348dfe399a71bfc8fd3 (diff)
downloadlinux-c947862f9126983537a4cc11e07d26882d60b7e7.tar.xz
CAPI: Fix leaks in capifs_new_ncci
When something went wrong during capifs_new_ncci, the looked up dentry was not properly released. Neither was the allocated inode. Refactor the function to avoid leaks. Signed-off-by: Jan Kiszka <jan.kiszka@web.de> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/isdn/capi/capifs.c25
1 files changed, 18 insertions, 7 deletions
diff --git a/drivers/isdn/capi/capifs.c b/drivers/isdn/capi/capifs.c
index 9f8f67b6c07f..dc68fcb122a0 100644
--- a/drivers/isdn/capi/capifs.c
+++ b/drivers/isdn/capi/capifs.c
@@ -152,22 +152,33 @@ static struct dentry *get_node(int num)
void capifs_new_ncci(unsigned int number, dev_t device)
{
struct dentry *dentry;
- struct inode *inode = new_inode(capifs_mnt->mnt_sb);
- if (!inode)
- return;
- inode->i_ino = number+2;
+ struct inode *inode;
dentry = get_node(number);
+ if (IS_ERR(dentry))
+ goto unlock_out;
+
+ if (dentry->d_inode) {
+ dput(dentry);
+ goto unlock_out;
+ }
+
+ inode = new_inode(capifs_mnt->mnt_sb);
+ if (!inode) {
+ dput(dentry);
+ goto unlock_out;
+ }
/* config contents is protected by root's i_mutex */
inode->i_uid = config.setuid ? config.uid : current_fsuid();
inode->i_gid = config.setgid ? config.gid : current_fsgid();
inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
+ inode->i_ino = number + 2;
init_special_inode(inode, S_IFCHR|config.mode, device);
- //inode->i_op = &capifs_file_inode_operations;
- if (!IS_ERR(dentry) && !dentry->d_inode)
- d_instantiate(dentry, inode);
+ d_instantiate(dentry, inode);
+
+unlock_out:
mutex_unlock(&capifs_root->d_inode->i_mutex);
}