summaryrefslogtreecommitdiffstats
path: root/fs/crypto
diff options
context:
space:
mode:
Diffstat (limited to 'fs/crypto')
-rw-r--r--fs/crypto/crypto.c10
-rw-r--r--fs/crypto/fname.c2
-rw-r--r--fs/crypto/fscrypt_private.h4
-rw-r--r--fs/crypto/keyinfo.c52
4 files changed, 11 insertions, 57 deletions
diff --git a/fs/crypto/crypto.c b/fs/crypto/crypto.c
index 02a7a9286449..6d6eca394d4d 100644
--- a/fs/crypto/crypto.c
+++ b/fs/crypto/crypto.c
@@ -327,7 +327,6 @@ EXPORT_SYMBOL(fscrypt_decrypt_page);
327static int fscrypt_d_revalidate(struct dentry *dentry, unsigned int flags) 327static int fscrypt_d_revalidate(struct dentry *dentry, unsigned int flags)
328{ 328{
329 struct dentry *dir; 329 struct dentry *dir;
330 struct fscrypt_info *ci;
331 int dir_has_key, cached_with_key; 330 int dir_has_key, cached_with_key;
332 331
333 if (flags & LOOKUP_RCU) 332 if (flags & LOOKUP_RCU)
@@ -339,18 +338,11 @@ static int fscrypt_d_revalidate(struct dentry *dentry, unsigned int flags)
339 return 0; 338 return 0;
340 } 339 }
341 340
342 ci = d_inode(dir)->i_crypt_info;
343 if (ci && ci->ci_keyring_key &&
344 (ci->ci_keyring_key->flags & ((1 << KEY_FLAG_INVALIDATED) |
345 (1 << KEY_FLAG_REVOKED) |
346 (1 << KEY_FLAG_DEAD))))
347 ci = NULL;
348
349 /* this should eventually be an flag in d_flags */ 341 /* this should eventually be an flag in d_flags */
350 spin_lock(&dentry->d_lock); 342 spin_lock(&dentry->d_lock);
351 cached_with_key = dentry->d_flags & DCACHE_ENCRYPTED_WITH_KEY; 343 cached_with_key = dentry->d_flags & DCACHE_ENCRYPTED_WITH_KEY;
352 spin_unlock(&dentry->d_lock); 344 spin_unlock(&dentry->d_lock);
353 dir_has_key = (ci != NULL); 345 dir_has_key = (d_inode(dir)->i_crypt_info != NULL);
354 dput(dir); 346 dput(dir);
355 347
356 /* 348 /*
diff --git a/fs/crypto/fname.c b/fs/crypto/fname.c
index 13052b85c393..37b49894c762 100644
--- a/fs/crypto/fname.c
+++ b/fs/crypto/fname.c
@@ -350,7 +350,7 @@ int fscrypt_setup_filename(struct inode *dir, const struct qstr *iname,
350 fname->disk_name.len = iname->len; 350 fname->disk_name.len = iname->len;
351 return 0; 351 return 0;
352 } 352 }
353 ret = fscrypt_get_crypt_info(dir); 353 ret = fscrypt_get_encryption_info(dir);
354 if (ret && ret != -EOPNOTSUPP) 354 if (ret && ret != -EOPNOTSUPP)
355 return ret; 355 return ret;
356 356
diff --git a/fs/crypto/fscrypt_private.h b/fs/crypto/fscrypt_private.h
index fdbb8af32eaf..e39696e64494 100644
--- a/fs/crypto/fscrypt_private.h
+++ b/fs/crypto/fscrypt_private.h
@@ -67,7 +67,6 @@ struct fscrypt_info {
67 u8 ci_filename_mode; 67 u8 ci_filename_mode;
68 u8 ci_flags; 68 u8 ci_flags;
69 struct crypto_skcipher *ci_ctfm; 69 struct crypto_skcipher *ci_ctfm;
70 struct key *ci_keyring_key;
71 u8 ci_master_key[FS_KEY_DESCRIPTOR_SIZE]; 70 u8 ci_master_key[FS_KEY_DESCRIPTOR_SIZE];
72}; 71};
73 72
@@ -101,7 +100,4 @@ extern int fscrypt_do_page_crypto(const struct inode *inode,
101extern struct page *fscrypt_alloc_bounce_page(struct fscrypt_ctx *ctx, 100extern struct page *fscrypt_alloc_bounce_page(struct fscrypt_ctx *ctx,
102 gfp_t gfp_flags); 101 gfp_t gfp_flags);
103 102
104/* keyinfo.c */
105extern int fscrypt_get_crypt_info(struct inode *);
106
107#endif /* _FSCRYPT_PRIVATE_H */ 103#endif /* _FSCRYPT_PRIVATE_H */
diff --git a/fs/crypto/keyinfo.c b/fs/crypto/keyinfo.c
index 02eb6b9e4438..cb3e82abf034 100644
--- a/fs/crypto/keyinfo.c
+++ b/fs/crypto/keyinfo.c
@@ -95,6 +95,7 @@ static int validate_user_key(struct fscrypt_info *crypt_info,
95 kfree(description); 95 kfree(description);
96 if (IS_ERR(keyring_key)) 96 if (IS_ERR(keyring_key))
97 return PTR_ERR(keyring_key); 97 return PTR_ERR(keyring_key);
98 down_read(&keyring_key->sem);
98 99
99 if (keyring_key->type != &key_type_logon) { 100 if (keyring_key->type != &key_type_logon) {
100 printk_once(KERN_WARNING 101 printk_once(KERN_WARNING
@@ -102,11 +103,9 @@ static int validate_user_key(struct fscrypt_info *crypt_info,
102 res = -ENOKEY; 103 res = -ENOKEY;
103 goto out; 104 goto out;
104 } 105 }
105 down_read(&keyring_key->sem);
106 ukp = user_key_payload(keyring_key); 106 ukp = user_key_payload(keyring_key);
107 if (ukp->datalen != sizeof(struct fscrypt_key)) { 107 if (ukp->datalen != sizeof(struct fscrypt_key)) {
108 res = -EINVAL; 108 res = -EINVAL;
109 up_read(&keyring_key->sem);
110 goto out; 109 goto out;
111 } 110 }
112 master_key = (struct fscrypt_key *)ukp->data; 111 master_key = (struct fscrypt_key *)ukp->data;
@@ -117,17 +116,11 @@ static int validate_user_key(struct fscrypt_info *crypt_info,
117 "%s: key size incorrect: %d\n", 116 "%s: key size incorrect: %d\n",
118 __func__, master_key->size); 117 __func__, master_key->size);
119 res = -ENOKEY; 118 res = -ENOKEY;
120 up_read(&keyring_key->sem);
121 goto out; 119 goto out;
122 } 120 }
123 res = derive_key_aes(ctx->nonce, master_key->raw, raw_key); 121 res = derive_key_aes(ctx->nonce, master_key->raw, raw_key);
124 up_read(&keyring_key->sem);
125 if (res)
126 goto out;
127
128 crypt_info->ci_keyring_key = keyring_key;
129 return 0;
130out: 122out:
123 up_read(&keyring_key->sem);
131 key_put(keyring_key); 124 key_put(keyring_key);
132 return res; 125 return res;
133} 126}
@@ -169,12 +162,11 @@ static void put_crypt_info(struct fscrypt_info *ci)
169 if (!ci) 162 if (!ci)
170 return; 163 return;
171 164
172 key_put(ci->ci_keyring_key);
173 crypto_free_skcipher(ci->ci_ctfm); 165 crypto_free_skcipher(ci->ci_ctfm);
174 kmem_cache_free(fscrypt_info_cachep, ci); 166 kmem_cache_free(fscrypt_info_cachep, ci);
175} 167}
176 168
177int fscrypt_get_crypt_info(struct inode *inode) 169int fscrypt_get_encryption_info(struct inode *inode)
178{ 170{
179 struct fscrypt_info *crypt_info; 171 struct fscrypt_info *crypt_info;
180 struct fscrypt_context ctx; 172 struct fscrypt_context ctx;
@@ -184,21 +176,15 @@ int fscrypt_get_crypt_info(struct inode *inode)
184 u8 *raw_key = NULL; 176 u8 *raw_key = NULL;
185 int res; 177 int res;
186 178
179 if (inode->i_crypt_info)
180 return 0;
181
187 res = fscrypt_initialize(inode->i_sb->s_cop->flags); 182 res = fscrypt_initialize(inode->i_sb->s_cop->flags);
188 if (res) 183 if (res)
189 return res; 184 return res;
190 185
191 if (!inode->i_sb->s_cop->get_context) 186 if (!inode->i_sb->s_cop->get_context)
192 return -EOPNOTSUPP; 187 return -EOPNOTSUPP;
193retry:
194 crypt_info = ACCESS_ONCE(inode->i_crypt_info);
195 if (crypt_info) {
196 if (!crypt_info->ci_keyring_key ||
197 key_validate(crypt_info->ci_keyring_key) == 0)
198 return 0;
199 fscrypt_put_encryption_info(inode, crypt_info);
200 goto retry;
201 }
202 188
203 res = inode->i_sb->s_cop->get_context(inode, &ctx, sizeof(ctx)); 189 res = inode->i_sb->s_cop->get_context(inode, &ctx, sizeof(ctx));
204 if (res < 0) { 190 if (res < 0) {
@@ -229,7 +215,6 @@ retry:
229 crypt_info->ci_data_mode = ctx.contents_encryption_mode; 215 crypt_info->ci_data_mode = ctx.contents_encryption_mode;
230 crypt_info->ci_filename_mode = ctx.filenames_encryption_mode; 216 crypt_info->ci_filename_mode = ctx.filenames_encryption_mode;
231 crypt_info->ci_ctfm = NULL; 217 crypt_info->ci_ctfm = NULL;
232 crypt_info->ci_keyring_key = NULL;
233 memcpy(crypt_info->ci_master_key, ctx.master_key_descriptor, 218 memcpy(crypt_info->ci_master_key, ctx.master_key_descriptor,
234 sizeof(crypt_info->ci_master_key)); 219 sizeof(crypt_info->ci_master_key));
235 220
@@ -273,14 +258,8 @@ retry:
273 if (res) 258 if (res)
274 goto out; 259 goto out;
275 260
276 kzfree(raw_key); 261 if (cmpxchg(&inode->i_crypt_info, NULL, crypt_info) == NULL)
277 raw_key = NULL; 262 crypt_info = NULL;
278 if (cmpxchg(&inode->i_crypt_info, NULL, crypt_info) != NULL) {
279 put_crypt_info(crypt_info);
280 goto retry;
281 }
282 return 0;
283
284out: 263out:
285 if (res == -ENOKEY) 264 if (res == -ENOKEY)
286 res = 0; 265 res = 0;
@@ -288,6 +267,7 @@ out:
288 kzfree(raw_key); 267 kzfree(raw_key);
289 return res; 268 return res;
290} 269}
270EXPORT_SYMBOL(fscrypt_get_encryption_info);
291 271
292void fscrypt_put_encryption_info(struct inode *inode, struct fscrypt_info *ci) 272void fscrypt_put_encryption_info(struct inode *inode, struct fscrypt_info *ci)
293{ 273{
@@ -305,17 +285,3 @@ void fscrypt_put_encryption_info(struct inode *inode, struct fscrypt_info *ci)
305 put_crypt_info(ci); 285 put_crypt_info(ci);
306} 286}
307EXPORT_SYMBOL(fscrypt_put_encryption_info); 287EXPORT_SYMBOL(fscrypt_put_encryption_info);
308
309int fscrypt_get_encryption_info(struct inode *inode)
310{
311 struct fscrypt_info *ci = inode->i_crypt_info;
312
313 if (!ci ||
314 (ci->ci_keyring_key &&
315 (ci->ci_keyring_key->flags & ((1 << KEY_FLAG_INVALIDATED) |
316 (1 << KEY_FLAG_REVOKED) |
317 (1 << KEY_FLAG_DEAD)))))
318 return fscrypt_get_crypt_info(inode);
319 return 0;
320}
321EXPORT_SYMBOL(fscrypt_get_encryption_info);