add patch reserve-xattr-index-for-gnu-hurd
[ext4-patch-queue.git] / crypto-rename-ext4_get_encryption_info
blob638ecd988d844483e43f6753dc7fb7554169d5d1
1 ---
2  fs/ext4/crypto.c        | 15 +++++++++++----
3  fs/ext4/crypto_fname.c  | 64 +++++++++++++++++++++++++++++++++++++++++-----------------------
4  fs/ext4/crypto_key.c    |  2 +-
5  fs/ext4/crypto_policy.c | 43 ++++++++++++++++++++++---------------------
6  fs/ext4/dir.c           |  8 ++++++--
7  fs/ext4/ext4.h          | 37 ++++++++++++++++++++++---------------
8  fs/ext4/file.c          | 12 +++++-------
9  fs/ext4/ialloc.c        |  6 +++---
10  fs/ext4/namei.c         | 17 +++--------------
11  fs/ext4/symlink.c       |  4 ----
12  10 files changed, 114 insertions(+), 94 deletions(-)
14 diff --git a/fs/ext4/crypto.c b/fs/ext4/crypto.c
15 index c802120..e38908d 100644
16 --- a/fs/ext4/crypto.c
17 +++ b/fs/ext4/crypto.c
18 @@ -98,9 +98,8 @@ struct ext4_crypto_ctx *ext4_get_crypto_ctx(struct inode *inode)
19         struct ext4_crypto_ctx *ctx = NULL;
20         int res = 0;
21         unsigned long flags;
22 -       struct ext4_crypt_info *ci = EXT4_I(inode)->i_crypt_info;
24 -       if (ci == NULL)
25 +       if (EXT4_I(inode)->i_crypt_info == NULL)
26                 return ERR_PTR(-ENOKEY);
28         /*
29 @@ -264,10 +263,18 @@ static int ext4_page_crypto(struct inode *inode,
30         struct ablkcipher_request *req = NULL;
31         DECLARE_EXT4_COMPLETION_RESULT(ecr);
32         struct scatterlist dst, src;
33 -       struct ext4_crypt_info *ci = EXT4_I(inode)->i_crypt_info;
34 -       struct crypto_ablkcipher *tfm = ci->ci_ctfm;
35 +       struct ext4_crypt_info *ci;
36 +       struct crypto_ablkcipher *tfm;
37         int res = 0;
39 +       rcu_read_lock();
40 +       ci = EXT4_I(inode)->i_crypt_info;
41 +       if (ci == NULL) {
42 +               rcu_read_unlock();
43 +               return -ENOKEY;
44 +       }
45 +       tfm = ci->ci_ctfm;
47         req = ablkcipher_request_alloc(tfm, GFP_NOFS);
48         if (!req) {
49                 printk_ratelimited(KERN_ERR
50 diff --git a/fs/ext4/crypto_fname.c b/fs/ext4/crypto_fname.c
51 index 2fbef8a..db2d134 100644
52 --- a/fs/ext4/crypto_fname.c
53 +++ b/fs/ext4/crypto_fname.c
54 @@ -61,13 +61,13 @@ static unsigned max_name_len(struct inode *inode)
55   * allocate sufficient memory to oname string.
56   */
57  static int ext4_fname_encrypt(struct inode *inode,
58 +                             struct ext4_crypt_info *ci,
59                               const struct qstr *iname,
60                               struct ext4_str *oname)
61  {
62         u32 ciphertext_len;
63         struct ablkcipher_request *req = NULL;
64         DECLARE_EXT4_COMPLETION_RESULT(ecr);
65 -       struct ext4_crypt_info *ci = EXT4_I(inode)->i_crypt_info;
66         struct crypto_ablkcipher *tfm = ci->ci_ctfm;
67         int res = 0;
68         char iv[EXT4_CRYPTO_BLOCK_SIZE];
69 @@ -141,6 +141,7 @@ static int ext4_fname_encrypt(struct inode *inode,
70   *     We trust the caller to allocate sufficient memory to oname string.
71   */
72  static int ext4_fname_decrypt(struct inode *inode,
73 +                             struct ext4_crypt_info *ci,
74                               const struct ext4_str *iname,
75                               struct ext4_str *oname)
76  {
77 @@ -148,7 +149,6 @@ static int ext4_fname_decrypt(struct inode *inode,
78         struct ablkcipher_request *req = NULL;
79         DECLARE_EXT4_COMPLETION_RESULT(ecr);
80         struct scatterlist src_sg, dst_sg;
81 -       struct ext4_crypt_info *ci = EXT4_I(inode)->i_crypt_info;
82         struct crypto_ablkcipher *tfm = ci->ci_ctfm;
83         int res = 0;
84         char iv[EXT4_CRYPTO_BLOCK_SIZE];
85 @@ -261,11 +261,13 @@ u32 ext4_fname_crypto_round_up(u32 size, u32 blksize)
87  unsigned ext4_fname_encrypted_size(struct inode *inode, u32 ilen)
88  {
89 -       struct ext4_crypt_info *ci = EXT4_I(inode)->i_crypt_info;
90 +       struct ext4_crypt_info *ci;
91         int padding = 32;
93 -       if (ci)
94 +       ci = ext4_get_crypt_info_rcu(inode);
95 +       if (!IS_ERR(ci) && ci)
96                 padding = 4 << (ci->ci_flags & EXT4_POLICY_FLAGS_PAD_MASK);
97 +       rcu_read_unlock();
98         if (ilen < EXT4_CRYPTO_BLOCK_SIZE)
99                 ilen = EXT4_CRYPTO_BLOCK_SIZE;
100         return ext4_fname_crypto_round_up(ilen, padding);
101 @@ -316,6 +318,7 @@ int _ext4_fname_disk_to_usr(struct inode *inode,
103         char buf[24];
104         int ret;
105 +       struct ext4_crypt_info *ci;
107         if (iname->len < 3) {
108                 /*Check for . and .. */
109 @@ -330,8 +333,15 @@ int _ext4_fname_disk_to_usr(struct inode *inode,
110                 EXT4_ERROR_INODE(inode, "encrypted inode too small");
111                 return -EUCLEAN;
112         }
113 -       if (EXT4_I(inode)->i_crypt_info)
114 -               return ext4_fname_decrypt(inode, iname, oname);
115 +       ci = ext4_get_crypt_info_rcu(inode);
116 +       if (IS_ERR(ci))
117 +               return PTR_ERR(ci);
118 +       if (ci) {
119 +               int ret = ext4_fname_decrypt(inode, ci, iname, oname);
121 +               rcu_read_unlock();
122 +               return ret;
123 +       }
125         if (iname->len <= EXT4_FNAME_CRYPTO_DIGEST_SIZE) {
126                 ret = digest_encode(iname->name, iname->len, oname->name);
127 @@ -369,8 +379,7 @@ int ext4_fname_usr_to_disk(struct inode *inode,
128                            const struct qstr *iname,
129                            struct ext4_str *oname)
131 -       int res;
132 -       struct ext4_crypt_info *ci = EXT4_I(inode)->i_crypt_info;
133 +       struct ext4_crypt_info *ci;
135         if (iname->len < 3) {
136                 /*Check for . and .. */
137 @@ -382,8 +391,13 @@ int ext4_fname_usr_to_disk(struct inode *inode,
138                         return oname->len;
139                 }
140         }
141 +       ci = ext4_get_crypt_info_rcu(inode);
142 +       if (IS_ERR(ci))
143 +               return PTR_ERR(ci);
144         if (ci) {
145 -               res = ext4_fname_encrypt(inode, iname, oname);
146 +               int res = ext4_fname_encrypt(inode, ci, iname, oname);
148 +               rcu_read_unlock();
149                 return res;
150         }
151         /* Without a proper key, a user is not allowed to modify the filenames
152 @@ -409,24 +423,29 @@ int ext4_fname_setup_filename(struct inode *dir, const struct qstr *iname,
153                 fname->disk_name.len = iname->len;
154                 return 0;
155         }
156 -       ret = ext4_get_encryption_info(dir);
157 +       ret = ext4_fname_crypto_alloc_buffer(dir, iname->len,
158 +                                            &fname->crypto_buf);
159         if (ret)
160                 return ret;
161 -       ci = EXT4_I(dir)->i_crypt_info;
163 +       ci = ext4_get_crypt_info_rcu(dir);
164 +       if (IS_ERR(ci)) {
165 +               ret = PTR_ERR(ci);
166 +               goto errout;
167 +       }
168         if (ci) {
169 -               ret = ext4_fname_crypto_alloc_buffer(dir, iname->len,
170 -                                                    &fname->crypto_buf);
171 -               if (ret < 0)
172 -                       return ret;
173 -               ret = ext4_fname_encrypt(dir, iname, &fname->crypto_buf);
174 +               ret = ext4_fname_encrypt(dir, ci, iname, &fname->crypto_buf);
175 +               rcu_read_unlock();
176                 if (ret < 0)
177                         goto errout;
178                 fname->disk_name.name = fname->crypto_buf.name;
179                 fname->disk_name.len = fname->crypto_buf.len;
180                 return 0;
181         }
182 -       if (!lookup)
183 -               return -EACCES;
184 +       if (!lookup) {
185 +               ret = -EACCES;
186 +               goto errout;
187 +       }
189         /* We don't have the key and we are doing a lookup; decode the
190          * user-supplied name
191 @@ -434,12 +453,11 @@ int ext4_fname_setup_filename(struct inode *dir, const struct qstr *iname,
192         if (iname->name[0] == '_')
193                 bigname = 1;
194         if ((bigname && (iname->len != 33)) ||
195 -           (!bigname && (iname->len > 43)))
196 -               return -ENOENT;
197 +           (!bigname && (iname->len > 43))) {
198 +               ret = -ENOENT;
199 +               goto errout;
200 +       }
202 -       fname->crypto_buf.name = kmalloc(32, GFP_KERNEL);
203 -       if (fname->crypto_buf.name == NULL)
204 -               return -ENOMEM;
205         ret = digest_decode(iname->name + bigname, iname->len - bigname,
206                             fname->crypto_buf.name);
207         if (ret < 0) {
208 diff --git a/fs/ext4/crypto_key.c b/fs/ext4/crypto_key.c
209 index 9a16d1e..d9b4cc0 100644
210 --- a/fs/ext4/crypto_key.c
211 +++ b/fs/ext4/crypto_key.c
212 @@ -111,7 +111,7 @@ void ext4_free_encryption_info(struct inode *inode,
213         ext4_free_crypt_info(ci);
216 -int _ext4_get_encryption_info(struct inode *inode)
217 +int ext4_setup_encryption_info(struct inode *inode)
219         struct ext4_inode_info *ei = EXT4_I(inode);
220         struct ext4_crypt_info *crypt_info;
221 diff --git a/fs/ext4/crypto_policy.c b/fs/ext4/crypto_policy.c
222 index ad05069..2f5743f 100644
223 --- a/fs/ext4/crypto_policy.c
224 +++ b/fs/ext4/crypto_policy.c
225 @@ -159,25 +159,26 @@ int ext4_is_child_context_consistent_with_parent(struct inode *parent,
226         /* if the child directory is not encrypted, this is always a problem */
227         if (!ext4_encrypted_inode(child))
228                 return 0;
229 -       res = ext4_get_encryption_info(parent);
230 -       if (res)
231 +       parent_ci = ext4_get_crypt_info_rcu(parent);
232 +       if (IS_ERR(parent_ci))
233                 return 0;
234 -       res = ext4_get_encryption_info(child);
235 -       if (res)
236 +       child_ci = ext4_get_crypt_info_rcu(child);
237 +       if (IS_ERR(child_ci))
238                 return 0;
239 -       parent_ci = EXT4_I(parent)->i_crypt_info;
240 -       child_ci = EXT4_I(child)->i_crypt_info;
241         if (!parent_ci && !child_ci)
242 -               return 1;
243 -       if (!parent_ci || !child_ci)
244 -               return 0;
246 -       return (memcmp(parent_ci->ci_master_key,
247 -                      child_ci->ci_master_key,
248 -                      EXT4_KEY_DESCRIPTOR_SIZE) == 0 &&
249 -               (parent_ci->ci_data_mode == child_ci->ci_data_mode) &&
250 -               (parent_ci->ci_filename_mode == child_ci->ci_filename_mode) &&
251 -               (parent_ci->ci_flags == child_ci->ci_flags));
252 +               res = 1;
253 +       else if (!parent_ci || !child_ci)
254 +               res = 0;
255 +       else
256 +               res = (memcmp(parent_ci->ci_master_key,
257 +                             child_ci->ci_master_key,
258 +                             EXT4_KEY_DESCRIPTOR_SIZE) == 0 &&
259 +                      (parent_ci->ci_data_mode == child_ci->ci_data_mode) &&
260 +                      (parent_ci->ci_filename_mode ==
261 +                       child_ci->ci_filename_mode) &&
262 +                      (parent_ci->ci_flags == child_ci->ci_flags));
263 +       rcu_read_unlock();
264 +       return res;
267  /**
268 @@ -193,10 +194,9 @@ int ext4_inherit_context(struct inode *parent, struct inode *child)
269         struct ext4_crypt_info *ci;
270         int res;
272 -       res = ext4_get_encryption_info(parent);
273 -       if (res < 0)
274 -               return res;
275 -       ci = EXT4_I(parent)->i_crypt_info;
276 +       ci = ext4_get_crypt_info_rcu(parent);
277 +       if (IS_ERR(ci))
278 +               return PTR_ERR(ci);
279         if (ci == NULL)
280                 return -ENOKEY;
282 @@ -216,6 +216,7 @@ int ext4_inherit_context(struct inode *parent, struct inode *child)
283                 memcpy(ctx.master_key_descriptor, ci->ci_master_key,
284                        EXT4_KEY_DESCRIPTOR_SIZE);
285         }
286 +       rcu_read_unlock();
287         get_random_bytes(ctx.nonce, EXT4_KEY_DERIVATION_NONCE_SIZE);
288         res = ext4_xattr_set(child, EXT4_XATTR_INDEX_ENCRYPTION,
289                              EXT4_XATTR_NAME_ENCRYPTION_CONTEXT, &ctx,
290 @@ -223,7 +224,7 @@ int ext4_inherit_context(struct inode *parent, struct inode *child)
291         if (!res) {
292                 ext4_set_inode_flag(child, EXT4_INODE_ENCRYPT);
293                 ext4_clear_inode_state(child, EXT4_STATE_MAY_INLINE_DATA);
294 -               res = ext4_get_encryption_info(child);
295 +               res = ext4_setup_encryption_info(child);
296         }
297         return res;
299 diff --git a/fs/ext4/dir.c b/fs/ext4/dir.c
300 index 1d1bca7..f4dba17 100644
301 --- a/fs/ext4/dir.c
302 +++ b/fs/ext4/dir.c
303 @@ -594,8 +594,12 @@ finished:
305  static int ext4_dir_open(struct inode * inode, struct file * filp)
307 -       if (ext4_encrypted_inode(inode))
308 -               return ext4_get_encryption_info(inode) ? -EACCES : 0;
309 +       if (ext4_encrypted_inode(inode)) {
310 +               int ret = ext4_setup_encryption_info(inode);
312 +               if (ret && ret != -ENOKEY)
313 +                       return -EACCES;
314 +       }
315         return 0;
318 diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
319 index edbe347..16ca80d 100644
320 --- a/fs/ext4/ext4.h
321 +++ b/fs/ext4/ext4.h
322 @@ -2327,39 +2327,46 @@ static inline void ext4_fname_free_filename(struct ext4_filename *fname) { }
323  /* crypto_key.c */
324  void ext4_free_crypt_info(struct ext4_crypt_info *ci);
325  void ext4_free_encryption_info(struct inode *inode, struct ext4_crypt_info *ci);
326 -int _ext4_get_encryption_info(struct inode *inode);
327 +int ext4_setup_encryption_info(struct inode *inode);
329  #ifdef CONFIG_EXT4_FS_ENCRYPTION
330  int ext4_has_encryption_key(struct inode *inode);
332 -static inline int ext4_get_encryption_info(struct inode *inode)
333 +static inline
334 +struct ext4_crypt_info *ext4_get_crypt_info_rcu(struct inode *inode)
336 -       struct ext4_crypt_info *ci = EXT4_I(inode)->i_crypt_info;
337 +       int ret;
338 +       struct ext4_crypt_info *ci;
340 +       rcu_read_lock();
341 +       ci = EXT4_I(inode)->i_crypt_info;
342         if (!ci ||
343             (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 -               return _ext4_get_encryption_info(inode);
348 -       return 0;
351 -static inline struct ext4_crypt_info *ext4_encryption_info(struct inode *inode)
353 -       return EXT4_I(inode)->i_crypt_info;
354 +                                          (1 << KEY_FLAG_DEAD))))) {
355 +               rcu_read_unlock();
356 +               ret = ext4_setup_encryption_info(inode);
357 +               if (ret && ret != -ENOKEY) {
358 +                       return ERR_PTR(ret);
359 +               }
360 +               rcu_read_lock();
361 +       }
362 +       ci = EXT4_I(inode)->i_crypt_info;
363 +       if (ci == NULL)
364 +               rcu_read_unlock();
365 +       return ci;
368  #else
369  static inline int ext4_has_encryption_key(struct inode *inode)
371         return 0;
373 -static inline int ext4_get_encryption_info(struct inode *inode)
374 +static inline int ext4_setup_encryption_info(struct inode *inode)
376 -       return 0;
377 +       return -ENOKEY;
379 -static inline struct ext4_crypt_info *ext4_encryption_info(struct inode *inode)
380 +struct ext4_crypt_info *ext4_get_crypt_info_rcu(struct inode *inode)
382         return NULL;
384 diff --git a/fs/ext4/file.c b/fs/ext4/file.c
385 index 749b222..c977c7a 100644
386 --- a/fs/ext4/file.c
387 +++ b/fs/ext4/file.c
388 @@ -327,11 +327,9 @@ static int ext4_file_mmap(struct file *file, struct vm_area_struct *vma)
389         struct inode *inode = file->f_mapping->host;
391         if (ext4_encrypted_inode(inode)) {
392 -               int err = ext4_get_encryption_info(inode);
393 +               int err = ext4_setup_encryption_info(inode);
394                 if (err)
395 -                       return 0;
396 -               if (ext4_encryption_info(inode) == NULL)
397 -                       return -ENOKEY;
398 +                       return err;
399         }
400         file_accessed(file);
401         if (IS_DAX(file_inode(file))) {
402 @@ -385,11 +383,11 @@ static int ext4_file_open(struct inode * inode, struct file * filp)
403                 }
404         }
405         if (ext4_encrypted_inode(inode)) {
406 -               ret = ext4_get_encryption_info(inode);
407 +               ret = ext4_setup_encryption_info(inode);
408 +               if (ret == -ENOKEY)
409 +                       return ret;
410                 if (ret)
411                         return -EACCES;
412 -               if (ext4_encryption_info(inode) == NULL)
413 -                       return -ENOKEY;
414         }
415         /*
416          * Set up the jbd2_inode if we are opening the inode for
417 diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c
418 index 3fcfd50..3abf659 100644
419 --- a/fs/ext4/ialloc.c
420 +++ b/fs/ext4/ialloc.c
421 @@ -765,11 +765,11 @@ struct inode *__ext4_new_inode(handle_t *handle, struct inode *dir,
422         if ((ext4_encrypted_inode(dir) ||
423              DUMMY_ENCRYPTION_ENABLED(EXT4_SB(dir->i_sb))) &&
424             (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode))) {
425 -               err = ext4_get_encryption_info(dir);
426 +               err = ext4_setup_encryption_info(dir);
427 +               if (err == -ENOKEY)
428 +                       return ERR_PTR(-EPERM);
429                 if (err)
430                         return ERR_PTR(err);
431 -               if (ext4_encryption_info(dir) == NULL)
432 -                       return ERR_PTR(-EPERM);
433                 if (!handle)
434                         nblocks += EXT4_DATA_TRANS_BLOCKS(dir->i_sb);
435                 encrypt = 1;
436 diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
437 index 2047ff7..9992a22 100644
438 --- a/fs/ext4/namei.c
439 +++ b/fs/ext4/namei.c
440 @@ -618,12 +618,6 @@ static struct stats dx_show_leaf(struct inode *dir,
442                                 name  = de->name;
443                                 len = de->name_len;
444 -                               if (ext4_encrypted_inode(inode))
445 -                                       res = ext4_get_encryption_info(dir);
446 -                               if (res) {
447 -                                       printk(KERN_WARNING "Error setting up"
448 -                                              " fname crypto: %d\n", res);
449 -                               }
450                                 if (ctx == NULL) {
451                                         /* Directory is not encrypted */
452                                         ext4fs_dirhash(de->name,
453 @@ -967,11 +961,6 @@ static int htree_dirblock_to_tree(struct file *dir_file,
454  #ifdef CONFIG_EXT4_FS_ENCRYPTION
455         /* Check if the directory is encrypted */
456         if (ext4_encrypted_inode(dir)) {
457 -               err = ext4_get_encryption_info(dir);
458 -               if (err < 0) {
459 -                       brelse(bh);
460 -                       return err;
461 -               }
462                 err = ext4_fname_crypto_alloc_buffer(dir, EXT4_NAME_LEN,
463                                                      &fname_crypto_str);
464                 if (err < 0) {
465 @@ -3058,11 +3047,11 @@ static int ext4_symlink(struct inode *dir,
466         encryption_required = (ext4_encrypted_inode(dir) ||
467                                DUMMY_ENCRYPTION_ENABLED(EXT4_SB(dir->i_sb)));
468         if (encryption_required) {
469 -               err = ext4_get_encryption_info(dir);
470 +               err = ext4_setup_encryption_info(dir);
471 +               if (err == -ENOKEY)
472 +                       return -EPERM;
473                 if (err)
474                         return err;
475 -               if (ext4_encryption_info(dir) == NULL)
476 -                       return -EPERM;
477                 disk_link.len = (ext4_fname_encrypted_size(dir, len) +
478                                  sizeof(struct ext4_encrypted_symlink_data));
479                 sd = kzalloc(disk_link.len, GFP_KERNEL);
480 diff --git a/fs/ext4/symlink.c b/fs/ext4/symlink.c
481 index e8e7af6..a9b5777 100644
482 --- a/fs/ext4/symlink.c
483 +++ b/fs/ext4/symlink.c
484 @@ -34,10 +34,6 @@ static const char *ext4_encrypted_follow_link(struct dentry *dentry, void **cook
485         int res;
486         u32 plen, max_size = inode->i_sb->s_blocksize;
488 -       res = ext4_get_encryption_info(inode);
489 -       if (res)
490 -               return ERR_PTR(res);
492         if (ext4_inode_is_fast_symlink(inode)) {
493                 caddr = (char *) EXT4_I(inode)->i_data;
494                 max_size = sizeof(EXT4_I(inode)->i_data);