Commit 408bd629 authored by Al Viro's avatar Al Viro

get rid of pointless allocations and copying in ecryptfs_follow_link()

switch to generic_readlink(), while we are at it
Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent 28fe3c19
...@@ -660,11 +660,10 @@ static int ecryptfs_readlink_lower(struct dentry *dentry, char **buf, ...@@ -660,11 +660,10 @@ static int ecryptfs_readlink_lower(struct dentry *dentry, char **buf,
{ {
struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry); struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry);
char *lower_buf; char *lower_buf;
size_t lower_bufsiz = PATH_MAX;
mm_segment_t old_fs; mm_segment_t old_fs;
int rc; int rc;
lower_buf = kmalloc(lower_bufsiz, GFP_KERNEL); lower_buf = kmalloc(PATH_MAX, GFP_KERNEL);
if (!lower_buf) { if (!lower_buf) {
rc = -ENOMEM; rc = -ENOMEM;
goto out; goto out;
...@@ -673,58 +672,29 @@ static int ecryptfs_readlink_lower(struct dentry *dentry, char **buf, ...@@ -673,58 +672,29 @@ static int ecryptfs_readlink_lower(struct dentry *dentry, char **buf,
set_fs(get_ds()); set_fs(get_ds());
rc = lower_dentry->d_inode->i_op->readlink(lower_dentry, rc = lower_dentry->d_inode->i_op->readlink(lower_dentry,
(char __user *)lower_buf, (char __user *)lower_buf,
lower_bufsiz); PATH_MAX);
set_fs(old_fs); set_fs(old_fs);
if (rc < 0) if (rc < 0)
goto out; goto out;
lower_bufsiz = rc;
rc = ecryptfs_decode_and_decrypt_filename(buf, bufsiz, dentry, rc = ecryptfs_decode_and_decrypt_filename(buf, bufsiz, dentry,
lower_buf, lower_bufsiz); lower_buf, rc);
out: out:
kfree(lower_buf); kfree(lower_buf);
return rc; return rc;
} }
static int static void *ecryptfs_follow_link(struct dentry *dentry, struct nameidata *nd)
ecryptfs_readlink(struct dentry *dentry, char __user *buf, int bufsiz)
{ {
char *kbuf; char *buf;
size_t kbufsiz, copied; size_t len = PATH_MAX;
int rc; int rc;
rc = ecryptfs_readlink_lower(dentry, &kbuf, &kbufsiz); rc = ecryptfs_readlink_lower(dentry, &buf, &len);
if (rc) if (rc)
goto out; goto out;
copied = min_t(size_t, bufsiz, kbufsiz);
rc = copy_to_user(buf, kbuf, copied) ? -EFAULT : copied;
kfree(kbuf);
fsstack_copy_attr_atime(dentry->d_inode, fsstack_copy_attr_atime(dentry->d_inode,
ecryptfs_dentry_to_lower(dentry)->d_inode); ecryptfs_dentry_to_lower(dentry)->d_inode);
out: buf[len] = '\0';
return rc;
}
static void *ecryptfs_follow_link(struct dentry *dentry, struct nameidata *nd)
{
char *buf;
int len = PAGE_SIZE, rc;
mm_segment_t old_fs;
/* Released in ecryptfs_put_link(); only release here on error */
buf = kmalloc(len, GFP_KERNEL);
if (!buf) {
buf = ERR_PTR(-ENOMEM);
goto out;
}
old_fs = get_fs();
set_fs(get_ds());
rc = dentry->d_inode->i_op->readlink(dentry, (char __user *)buf, len);
set_fs(old_fs);
if (rc < 0) {
kfree(buf);
buf = ERR_PTR(rc);
} else
buf[rc] = '\0';
out: out:
nd_set_link(nd, buf); nd_set_link(nd, buf);
return NULL; return NULL;
...@@ -1153,7 +1123,7 @@ static int ecryptfs_removexattr(struct dentry *dentry, const char *name) ...@@ -1153,7 +1123,7 @@ static int ecryptfs_removexattr(struct dentry *dentry, const char *name)
} }
const struct inode_operations ecryptfs_symlink_iops = { const struct inode_operations ecryptfs_symlink_iops = {
.readlink = ecryptfs_readlink, .readlink = generic_readlink,
.follow_link = ecryptfs_follow_link, .follow_link = ecryptfs_follow_link,
.put_link = ecryptfs_put_link, .put_link = ecryptfs_put_link,
.permission = ecryptfs_permission, .permission = ecryptfs_permission,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment