aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOGAWA Hirofumi <hirofumi@mail.parknet.co.jp>2010-01-11 13:36:14 -0500
committerAl Viro <viro@zeniv.linux.org.uk>2010-01-14 09:05:26 -0500
commit806892e9e12e731a0ca76c8f62ad95cf8eea9614 (patch)
treea063df1524ed862ef2475052e1cc1c66de390dc2
parent6d125529c6cbfe570ce3bf9a0728548f087499da (diff)
ecryptfs: Fix refcnt leak on ecryptfs_follow_link() error path
If ->follow_link handler return the error, it should decrement nd->path refcnt. But, ecryptfs_follow_link() doesn't decrement. This patch fix it by using usual nd_set_link() style error handling, instead of playing with nd->path. Signed-off-by: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r--fs/ecryptfs/inode.c24
1 files changed, 12 insertions, 12 deletions
diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c
index 429ca0b3ba08..7f8545032930 100644
--- a/fs/ecryptfs/inode.c
+++ b/fs/ecryptfs/inode.c
@@ -715,31 +715,31 @@ static void *ecryptfs_follow_link(struct dentry *dentry, struct nameidata *nd)
715 /* Released in ecryptfs_put_link(); only release here on error */ 715 /* Released in ecryptfs_put_link(); only release here on error */
716 buf = kmalloc(len, GFP_KERNEL); 716 buf = kmalloc(len, GFP_KERNEL);
717 if (!buf) { 717 if (!buf) {
718 rc = -ENOMEM; 718 buf = ERR_PTR(-ENOMEM);
719 goto out; 719 goto out;
720 } 720 }
721 old_fs = get_fs(); 721 old_fs = get_fs();
722 set_fs(get_ds()); 722 set_fs(get_ds());
723 rc = dentry->d_inode->i_op->readlink(dentry, (char __user *)buf, len); 723 rc = dentry->d_inode->i_op->readlink(dentry, (char __user *)buf, len);
724 set_fs(old_fs); 724 set_fs(old_fs);
725 if (rc < 0) 725 if (rc < 0) {
726 goto out_free; 726 kfree(buf);
727 else 727 buf = ERR_PTR(rc);
728 } else
728 buf[rc] = '\0'; 729 buf[rc] = '\0';
729 rc = 0;
730 nd_set_link(nd, buf);
731 goto out;
732out_free:
733 kfree(buf);
734out: 730out:
735 return ERR_PTR(rc); 731 nd_set_link(nd, buf);
732 return NULL;
736} 733}
737 734
738static void 735static void
739ecryptfs_put_link(struct dentry *dentry, struct nameidata *nd, void *ptr) 736ecryptfs_put_link(struct dentry *dentry, struct nameidata *nd, void *ptr)
740{ 737{
741 /* Free the char* */ 738 char *buf = nd_get_link(nd);
742 kfree(nd_get_link(nd)); 739 if (!IS_ERR(buf)) {
740 /* Free the char* */
741 kfree(buf);
742 }
743} 743}
744 744
745/** 745/**