summaryrefslogtreecommitdiffstats
path: root/fs/crypto/hooks.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/crypto/hooks.c')
-rw-r--r--fs/crypto/hooks.c68
1 files changed, 52 insertions, 16 deletions
diff --git a/fs/crypto/hooks.c b/fs/crypto/hooks.c
index 56debb1fcf5e..2dc22549d724 100644
--- a/fs/crypto/hooks.c
+++ b/fs/crypto/hooks.c
@@ -49,7 +49,8 @@ int fscrypt_file_open(struct inode *inode, struct file *filp)
49} 49}
50EXPORT_SYMBOL_GPL(fscrypt_file_open); 50EXPORT_SYMBOL_GPL(fscrypt_file_open);
51 51
52int __fscrypt_prepare_link(struct inode *inode, struct inode *dir) 52int __fscrypt_prepare_link(struct inode *inode, struct inode *dir,
53 struct dentry *dentry)
53{ 54{
54 int err; 55 int err;
55 56
@@ -57,6 +58,10 @@ int __fscrypt_prepare_link(struct inode *inode, struct inode *dir)
57 if (err) 58 if (err)
58 return err; 59 return err;
59 60
61 /* ... in case we looked up ciphertext name before key was added */
62 if (dentry->d_flags & DCACHE_ENCRYPTED_NAME)
63 return -ENOKEY;
64
60 if (!fscrypt_has_permitted_context(dir, inode)) 65 if (!fscrypt_has_permitted_context(dir, inode))
61 return -EXDEV; 66 return -EXDEV;
62 67
@@ -78,6 +83,11 @@ int __fscrypt_prepare_rename(struct inode *old_dir, struct dentry *old_dentry,
78 if (err) 83 if (err)
79 return err; 84 return err;
80 85
86 /* ... in case we looked up ciphertext name(s) before key was added */
87 if ((old_dentry->d_flags | new_dentry->d_flags) &
88 DCACHE_ENCRYPTED_NAME)
89 return -ENOKEY;
90
81 if (old_dir != new_dir) { 91 if (old_dir != new_dir) {
82 if (IS_ENCRYPTED(new_dir) && 92 if (IS_ENCRYPTED(new_dir) &&
83 !fscrypt_has_permitted_context(new_dir, 93 !fscrypt_has_permitted_context(new_dir,
@@ -94,21 +104,21 @@ int __fscrypt_prepare_rename(struct inode *old_dir, struct dentry *old_dentry,
94} 104}
95EXPORT_SYMBOL_GPL(__fscrypt_prepare_rename); 105EXPORT_SYMBOL_GPL(__fscrypt_prepare_rename);
96 106
97int __fscrypt_prepare_lookup(struct inode *dir, struct dentry *dentry) 107int __fscrypt_prepare_lookup(struct inode *dir, struct dentry *dentry,
108 struct fscrypt_name *fname)
98{ 109{
99 int err = fscrypt_get_encryption_info(dir); 110 int err = fscrypt_setup_filename(dir, &dentry->d_name, 1, fname);
100 111
101 if (err) 112 if (err && err != -ENOENT)
102 return err; 113 return err;
103 114
104 if (fscrypt_has_encryption_key(dir)) { 115 if (fname->is_ciphertext_name) {
105 spin_lock(&dentry->d_lock); 116 spin_lock(&dentry->d_lock);
106 dentry->d_flags |= DCACHE_ENCRYPTED_WITH_KEY; 117 dentry->d_flags |= DCACHE_ENCRYPTED_NAME;
107 spin_unlock(&dentry->d_lock); 118 spin_unlock(&dentry->d_lock);
119 d_set_d_op(dentry, &fscrypt_d_ops);
108 } 120 }
109 121 return err;
110 d_set_d_op(dentry, &fscrypt_d_ops);
111 return 0;
112} 122}
113EXPORT_SYMBOL_GPL(__fscrypt_prepare_lookup); 123EXPORT_SYMBOL_GPL(__fscrypt_prepare_lookup);
114 124
@@ -179,11 +189,9 @@ int __fscrypt_encrypt_symlink(struct inode *inode, const char *target,
179 sd->len = cpu_to_le16(ciphertext_len); 189 sd->len = cpu_to_le16(ciphertext_len);
180 190
181 err = fname_encrypt(inode, &iname, sd->encrypted_path, ciphertext_len); 191 err = fname_encrypt(inode, &iname, sd->encrypted_path, ciphertext_len);
182 if (err) { 192 if (err)
183 if (!disk_link->name) 193 goto err_free_sd;
184 kfree(sd); 194
185 return err;
186 }
187 /* 195 /*
188 * Null-terminating the ciphertext doesn't make sense, but we still 196 * Null-terminating the ciphertext doesn't make sense, but we still
189 * count the null terminator in the length, so we might as well 197 * count the null terminator in the length, so we might as well
@@ -191,9 +199,20 @@ int __fscrypt_encrypt_symlink(struct inode *inode, const char *target,
191 */ 199 */
192 sd->encrypted_path[ciphertext_len] = '\0'; 200 sd->encrypted_path[ciphertext_len] = '\0';
193 201
202 /* Cache the plaintext symlink target for later use by get_link() */
203 err = -ENOMEM;
204 inode->i_link = kmemdup(target, len + 1, GFP_NOFS);
205 if (!inode->i_link)
206 goto err_free_sd;
207
194 if (!disk_link->name) 208 if (!disk_link->name)
195 disk_link->name = (unsigned char *)sd; 209 disk_link->name = (unsigned char *)sd;
196 return 0; 210 return 0;
211
212err_free_sd:
213 if (!disk_link->name)
214 kfree(sd);
215 return err;
197} 216}
198EXPORT_SYMBOL_GPL(__fscrypt_encrypt_symlink); 217EXPORT_SYMBOL_GPL(__fscrypt_encrypt_symlink);
199 218
@@ -202,7 +221,7 @@ EXPORT_SYMBOL_GPL(__fscrypt_encrypt_symlink);
202 * @inode: the symlink inode 221 * @inode: the symlink inode
203 * @caddr: the on-disk contents of the symlink 222 * @caddr: the on-disk contents of the symlink
204 * @max_size: size of @caddr buffer 223 * @max_size: size of @caddr buffer
205 * @done: if successful, will be set up to free the returned target 224 * @done: if successful, will be set up to free the returned target if needed
206 * 225 *
207 * If the symlink's encryption key is available, we decrypt its target. 226 * If the symlink's encryption key is available, we decrypt its target.
208 * Otherwise, we encode its target for presentation. 227 * Otherwise, we encode its target for presentation.
@@ -217,12 +236,18 @@ const char *fscrypt_get_symlink(struct inode *inode, const void *caddr,
217{ 236{
218 const struct fscrypt_symlink_data *sd; 237 const struct fscrypt_symlink_data *sd;
219 struct fscrypt_str cstr, pstr; 238 struct fscrypt_str cstr, pstr;
239 bool has_key;
220 int err; 240 int err;
221 241
222 /* This is for encrypted symlinks only */ 242 /* This is for encrypted symlinks only */
223 if (WARN_ON(!IS_ENCRYPTED(inode))) 243 if (WARN_ON(!IS_ENCRYPTED(inode)))
224 return ERR_PTR(-EINVAL); 244 return ERR_PTR(-EINVAL);
225 245
246 /* If the decrypted target is already cached, just return it. */
247 pstr.name = READ_ONCE(inode->i_link);
248 if (pstr.name)
249 return pstr.name;
250
226 /* 251 /*
227 * Try to set up the symlink's encryption key, but we can continue 252 * Try to set up the symlink's encryption key, but we can continue
228 * regardless of whether the key is available or not. 253 * regardless of whether the key is available or not.
@@ -230,6 +255,7 @@ const char *fscrypt_get_symlink(struct inode *inode, const void *caddr,
230 err = fscrypt_get_encryption_info(inode); 255 err = fscrypt_get_encryption_info(inode);
231 if (err) 256 if (err)
232 return ERR_PTR(err); 257 return ERR_PTR(err);
258 has_key = fscrypt_has_encryption_key(inode);
233 259
234 /* 260 /*
235 * For historical reasons, encrypted symlink targets are prefixed with 261 * For historical reasons, encrypted symlink targets are prefixed with
@@ -261,7 +287,17 @@ const char *fscrypt_get_symlink(struct inode *inode, const void *caddr,
261 goto err_kfree; 287 goto err_kfree;
262 288
263 pstr.name[pstr.len] = '\0'; 289 pstr.name[pstr.len] = '\0';
264 set_delayed_call(done, kfree_link, pstr.name); 290
291 /*
292 * Cache decrypted symlink targets in i_link for later use. Don't cache
293 * symlink targets encoded without the key, since those become outdated
294 * once the key is added. This pairs with the READ_ONCE() above and in
295 * the VFS path lookup code.
296 */
297 if (!has_key ||
298 cmpxchg_release(&inode->i_link, NULL, pstr.name) != NULL)
299 set_delayed_call(done, kfree_link, pstr.name);
300
265 return pstr.name; 301 return pstr.name;
266 302
267err_kfree: 303err_kfree: