Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 806892e9 authored by OGAWA Hirofumi's avatar OGAWA Hirofumi Committed by Al Viro
Browse files

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: default avatarOGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent 6d125529
Loading
Loading
Loading
Loading
+12 −12
Original line number Original line Diff line number Diff line
@@ -715,31 +715,31 @@ static void *ecryptfs_follow_link(struct dentry *dentry, struct nameidata *nd)
	/* Released in ecryptfs_put_link(); only release here on error */
	/* Released in ecryptfs_put_link(); only release here on error */
	buf = kmalloc(len, GFP_KERNEL);
	buf = kmalloc(len, GFP_KERNEL);
	if (!buf) {
	if (!buf) {
		rc = -ENOMEM;
		buf = ERR_PTR(-ENOMEM);
		goto out;
		goto out;
	}
	}
	old_fs = get_fs();
	old_fs = get_fs();
	set_fs(get_ds());
	set_fs(get_ds());
	rc = dentry->d_inode->i_op->readlink(dentry, (char __user *)buf, len);
	rc = dentry->d_inode->i_op->readlink(dentry, (char __user *)buf, len);
	set_fs(old_fs);
	set_fs(old_fs);
	if (rc < 0)
	if (rc < 0) {
		goto out_free;
	else
		buf[rc] = '\0';
	rc = 0;
	nd_set_link(nd, buf);
	goto out;
out_free:
		kfree(buf);
		kfree(buf);
		buf = ERR_PTR(rc);
	} else
		buf[rc] = '\0';
out:
out:
	return ERR_PTR(rc);
	nd_set_link(nd, buf);
	return NULL;
}
}


static void
static void
ecryptfs_put_link(struct dentry *dentry, struct nameidata *nd, void *ptr)
ecryptfs_put_link(struct dentry *dentry, struct nameidata *nd, void *ptr)
{
{
	char *buf = nd_get_link(nd);
	if (!IS_ERR(buf)) {
		/* Free the char* */
		/* Free the char* */
	kfree(nd_get_link(nd));
		kfree(buf);
	}
}
}


/**
/**