diff options
author | Eric Biggers <ebiggers@google.com> | 2018-01-11 22:10:40 -0500 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2018-01-11 22:10:40 -0500 |
commit | 6a9269c83851993ee679c17b7254a9f675581134 (patch) | |
tree | ea4b941467d20c0ee8db1894ef512f0d50a1b247 | |
parent | 78e1060c9474da8760ac91fa2deea70bd41d2821 (diff) |
ext4: switch to fscrypt_get_symlink()
Signed-off-by: Eric Biggers <ebiggers@google.com>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
-rw-r--r-- | fs/ext4/symlink.c | 43 |
1 files changed, 6 insertions, 37 deletions
diff --git a/fs/ext4/symlink.c b/fs/ext4/symlink.c index a2006c9af1d9..dd05af983092 100644 --- a/fs/ext4/symlink.c +++ b/fs/ext4/symlink.c | |||
@@ -28,59 +28,28 @@ static const char *ext4_encrypted_get_link(struct dentry *dentry, | |||
28 | struct delayed_call *done) | 28 | struct delayed_call *done) |
29 | { | 29 | { |
30 | struct page *cpage = NULL; | 30 | struct page *cpage = NULL; |
31 | char *caddr, *paddr = NULL; | 31 | const void *caddr; |
32 | struct fscrypt_str cstr, pstr; | 32 | unsigned int max_size; |
33 | struct fscrypt_symlink_data *sd; | 33 | const char *paddr; |
34 | int res; | ||
35 | u32 max_size = inode->i_sb->s_blocksize; | ||
36 | 34 | ||
37 | if (!dentry) | 35 | if (!dentry) |
38 | return ERR_PTR(-ECHILD); | 36 | return ERR_PTR(-ECHILD); |
39 | 37 | ||
40 | res = fscrypt_get_encryption_info(inode); | ||
41 | if (res) | ||
42 | return ERR_PTR(res); | ||
43 | |||
44 | if (ext4_inode_is_fast_symlink(inode)) { | 38 | if (ext4_inode_is_fast_symlink(inode)) { |
45 | caddr = (char *) EXT4_I(inode)->i_data; | 39 | caddr = EXT4_I(inode)->i_data; |
46 | max_size = sizeof(EXT4_I(inode)->i_data); | 40 | max_size = sizeof(EXT4_I(inode)->i_data); |
47 | } else { | 41 | } else { |
48 | cpage = read_mapping_page(inode->i_mapping, 0, NULL); | 42 | cpage = read_mapping_page(inode->i_mapping, 0, NULL); |
49 | if (IS_ERR(cpage)) | 43 | if (IS_ERR(cpage)) |
50 | return ERR_CAST(cpage); | 44 | return ERR_CAST(cpage); |
51 | caddr = page_address(cpage); | 45 | caddr = page_address(cpage); |
46 | max_size = inode->i_sb->s_blocksize; | ||
52 | } | 47 | } |
53 | 48 | ||
54 | /* Symlink is encrypted */ | 49 | paddr = fscrypt_get_symlink(inode, caddr, max_size, done); |
55 | sd = (struct fscrypt_symlink_data *)caddr; | ||
56 | cstr.name = sd->encrypted_path; | ||
57 | cstr.len = le16_to_cpu(sd->len); | ||
58 | if ((cstr.len + sizeof(struct fscrypt_symlink_data) - 1) > max_size) { | ||
59 | /* Symlink data on the disk is corrupted */ | ||
60 | res = -EFSCORRUPTED; | ||
61 | goto errout; | ||
62 | } | ||
63 | |||
64 | res = fscrypt_fname_alloc_buffer(inode, cstr.len, &pstr); | ||
65 | if (res) | ||
66 | goto errout; | ||
67 | paddr = pstr.name; | ||
68 | |||
69 | res = fscrypt_fname_disk_to_usr(inode, 0, 0, &cstr, &pstr); | ||
70 | if (res) | ||
71 | goto errout; | ||
72 | |||
73 | /* Null-terminate the name */ | ||
74 | paddr[pstr.len] = '\0'; | ||
75 | if (cpage) | 50 | if (cpage) |
76 | put_page(cpage); | 51 | put_page(cpage); |
77 | set_delayed_call(done, kfree_link, paddr); | ||
78 | return paddr; | 52 | return paddr; |
79 | errout: | ||
80 | if (cpage) | ||
81 | put_page(cpage); | ||
82 | kfree(paddr); | ||
83 | return ERR_PTR(res); | ||
84 | } | 53 | } |
85 | 54 | ||
86 | const struct inode_operations ext4_encrypted_symlink_inode_operations = { | 55 | const struct inode_operations ext4_encrypted_symlink_inode_operations = { |