summaryrefslogtreecommitdiffstats
path: root/fs/ext4/symlink.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ext4/symlink.c')
-rw-r--r--fs/ext4/symlink.c35
1 files changed, 15 insertions, 20 deletions
diff --git a/fs/ext4/symlink.c b/fs/ext4/symlink.c
index 75ed5c2f0c16..4d83d9e05f2e 100644
--- a/fs/ext4/symlink.c
+++ b/fs/ext4/symlink.c
@@ -22,23 +22,22 @@
22#include "ext4.h" 22#include "ext4.h"
23#include "xattr.h" 23#include "xattr.h"
24 24
25#ifdef CONFIG_EXT4_FS_ENCRYPTION
26static const char *ext4_encrypted_get_link(struct dentry *dentry, 25static const char *ext4_encrypted_get_link(struct dentry *dentry,
27 struct inode *inode, 26 struct inode *inode,
28 struct delayed_call *done) 27 struct delayed_call *done)
29{ 28{
30 struct page *cpage = NULL; 29 struct page *cpage = NULL;
31 char *caddr, *paddr = NULL; 30 char *caddr, *paddr = NULL;
32 struct ext4_str cstr, pstr; 31 struct fscrypt_str cstr, pstr;
33 struct ext4_encrypted_symlink_data *sd; 32 struct fscrypt_symlink_data *sd;
34 loff_t size = min_t(loff_t, i_size_read(inode), PAGE_SIZE - 1); 33 loff_t size = min_t(loff_t, i_size_read(inode), PAGE_SIZE - 1);
35 int res; 34 int res;
36 u32 plen, max_size = inode->i_sb->s_blocksize; 35 u32 max_size = inode->i_sb->s_blocksize;
37 36
38 if (!dentry) 37 if (!dentry)
39 return ERR_PTR(-ECHILD); 38 return ERR_PTR(-ECHILD);
40 39
41 res = ext4_get_encryption_info(inode); 40 res = fscrypt_get_encryption_info(inode);
42 if (res) 41 if (res)
43 return ERR_PTR(res); 42 return ERR_PTR(res);
44 43
@@ -54,30 +53,27 @@ static const char *ext4_encrypted_get_link(struct dentry *dentry,
54 } 53 }
55 54
56 /* Symlink is encrypted */ 55 /* Symlink is encrypted */
57 sd = (struct ext4_encrypted_symlink_data *)caddr; 56 sd = (struct fscrypt_symlink_data *)caddr;
58 cstr.name = sd->encrypted_path; 57 cstr.name = sd->encrypted_path;
59 cstr.len = le16_to_cpu(sd->len); 58 cstr.len = le16_to_cpu(sd->len);
60 if ((cstr.len + 59 if ((cstr.len + sizeof(struct fscrypt_symlink_data) - 1) > max_size) {
61 sizeof(struct ext4_encrypted_symlink_data) - 1) >
62 max_size) {
63 /* Symlink data on the disk is corrupted */ 60 /* Symlink data on the disk is corrupted */
64 res = -EFSCORRUPTED; 61 res = -EFSCORRUPTED;
65 goto errout; 62 goto errout;
66 } 63 }
67 plen = (cstr.len < EXT4_FNAME_CRYPTO_DIGEST_SIZE*2) ? 64
68 EXT4_FNAME_CRYPTO_DIGEST_SIZE*2 : cstr.len; 65 res = fscrypt_fname_alloc_buffer(inode, cstr.len, &pstr);
69 paddr = kmalloc(plen + 1, GFP_NOFS); 66 if (res)
70 if (!paddr) {
71 res = -ENOMEM;
72 goto errout; 67 goto errout;
73 } 68
74 pstr.name = paddr; 69 res = fscrypt_fname_disk_to_usr(inode, 0, 0, &cstr, &pstr);
75 pstr.len = plen;
76 res = _ext4_fname_disk_to_usr(inode, NULL, &cstr, &pstr);
77 if (res < 0) 70 if (res < 0)
78 goto errout; 71 goto errout;
72
73 paddr = pstr.name;
74
79 /* Null-terminate the name */ 75 /* Null-terminate the name */
80 if (res <= plen) 76 if (res <= pstr.len)
81 paddr[res] = '\0'; 77 paddr[res] = '\0';
82 if (cpage) 78 if (cpage)
83 put_page(cpage); 79 put_page(cpage);
@@ -99,7 +95,6 @@ const struct inode_operations ext4_encrypted_symlink_inode_operations = {
99 .listxattr = ext4_listxattr, 95 .listxattr = ext4_listxattr,
100 .removexattr = generic_removexattr, 96 .removexattr = generic_removexattr,
101}; 97};
102#endif
103 98
104const struct inode_operations ext4_symlink_inode_operations = { 99const struct inode_operations ext4_symlink_inode_operations = {
105 .readlink = generic_readlink, 100 .readlink = generic_readlink,