summaryrefslogtreecommitdiffstats
path: root/drivers/isdn/capi/capifs.c
diff options
context:
space:
mode:
authorJan Kiszka <jan.kiszka@web.de>2010-02-08 11:12:06 +0100
committerDavid S. Miller <davem@davemloft.net>2010-02-17 01:01:18 +0100
commit90926f0e58dcd9f4ca877961000568a3be787f2f (patch)
treed3c589a3debf2f692c5f5a7643a78b7f20cb7a60 /drivers/isdn/capi/capifs.c
parentCAPI: Fix leaks in capifs_new_ncci (diff)
downloadlinux-90926f0e58dcd9f4ca877961000568a3be787f2f.tar.xz
linux-90926f0e58dcd9f4ca877961000568a3be787f2f.zip
CAPI: Sanitize capifs API
Instead of looking up the dentry of an NCCI node again in capifs_free_ncci pass the pointer via the capifs user. This patch also reduces the #ifdef mess in capi.c a bit as far as capifs was causing it. Signed-off-by: Jan Kiszka <jan.kiszka@web.de> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/isdn/capi/capifs.c')
-rw-r--r--drivers/isdn/capi/capifs.c50
1 files changed, 29 insertions, 21 deletions
diff --git a/drivers/isdn/capi/capifs.c b/drivers/isdn/capi/capifs.c
index dc68fcb122a0..91aafadd413f 100644
--- a/drivers/isdn/capi/capifs.c
+++ b/drivers/isdn/capi/capifs.c
@@ -141,31 +141,32 @@ static struct file_system_type capifs_fs_type = {
.kill_sb = kill_anon_super,
};
-static struct dentry *get_node(int num)
-{
- char s[10];
- struct dentry *root = capifs_root;
- mutex_lock(&root->d_inode->i_mutex);
- return lookup_one_len(s, root, sprintf(s, "%d", num));
-}
-
-void capifs_new_ncci(unsigned int number, dev_t device)
+struct dentry *capifs_new_ncci(unsigned int number, dev_t device)
{
struct dentry *dentry;
struct inode *inode;
+ char name[10];
+ int namelen;
- dentry = get_node(number);
- if (IS_ERR(dentry))
+ mutex_lock(&capifs_root->d_inode->i_mutex);
+
+ namelen = sprintf(name, "%d", number);
+ dentry = lookup_one_len(name, capifs_root, namelen);
+ if (IS_ERR(dentry)) {
+ dentry = NULL;
goto unlock_out;
+ }
if (dentry->d_inode) {
dput(dentry);
+ dentry = NULL;
goto unlock_out;
}
inode = new_inode(capifs_mnt->mnt_sb);
if (!inode) {
dput(dentry);
+ dentry = NULL;
goto unlock_out;
}
@@ -177,24 +178,31 @@ void capifs_new_ncci(unsigned int number, dev_t device)
init_special_inode(inode, S_IFCHR|config.mode, device);
d_instantiate(dentry, inode);
+ dget(dentry);
unlock_out:
mutex_unlock(&capifs_root->d_inode->i_mutex);
+
+ return dentry;
}
-void capifs_free_ncci(unsigned int number)
+void capifs_free_ncci(struct dentry *dentry)
{
- struct dentry *dentry = get_node(number);
-
- if (!IS_ERR(dentry)) {
- struct inode *inode = dentry->d_inode;
- if (inode) {
- inode->i_nlink--;
- d_delete(dentry);
- dput(dentry);
- }
+ struct inode *inode;
+
+ if (!dentry)
+ return;
+
+ mutex_lock(&capifs_root->d_inode->i_mutex);
+
+ inode = dentry->d_inode;
+ if (inode) {
+ drop_nlink(inode);
+ d_delete(dentry);
dput(dentry);
}
+ dput(dentry);
+
mutex_unlock(&capifs_root->d_inode->i_mutex);
}