diff options
Diffstat (limited to 'fs/ext4/symlink.c')
-rw-r--r-- | fs/ext4/symlink.c | 35 |
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 | ||
26 | static const char *ext4_encrypted_get_link(struct dentry *dentry, | 25 | static 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 | ||
104 | const struct inode_operations ext4_symlink_inode_operations = { | 99 | const struct inode_operations ext4_symlink_inode_operations = { |
105 | .readlink = generic_readlink, | 100 | .readlink = generic_readlink, |