add patch minor-cleanup-of-ext4_da_reserve_space
[ext4-patch-queue.git] / encrypt-tmpdir-files
blob90991945543266a5477c873a63b762f4f72b37a4
1 ext4 crypto: encrypt tmpfile located in encryption protected directory
3 Factor out calls to ext4_inherit_context() and move them to
4 __ext4_new_inode(); this fixes a problem where ext4_tmpfile() wasn't
5 calling calling ext4_inherit_context(), so the temporary file wasn't
6 getting protected.  Since the blocks for the tmpfile could end up on
7 disk, they really should be protected if the tmpfile is created within
8 the context of an encrypted directory.
10 Signed-off-by: Theodore Ts'o <tytso@mit.edu>
11 ---
12  fs/ext4/ext4.h   |  9 +++++++++
13  fs/ext4/ialloc.c | 26 ++++++++++++++++++++------
14  fs/ext4/namei.c  | 29 +----------------------------
15  3 files changed, 30 insertions(+), 34 deletions(-)
17 diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
18 index 2eaa83d..4a019aa 100644
19 --- a/fs/ext4/ext4.h
20 +++ b/fs/ext4/ext4.h
21 @@ -2149,6 +2149,11 @@ static inline int ext4_get_encryption_info(struct inode *inode)
22         return 0;
23  }
25 +static inline struct ext4_crypt_info *ext4_encryption_info(struct inode *inode)
27 +       return EXT4_I(inode)->i_crypt_info;
30  #else
31  static inline int ext4_has_encryption_key(struct inode *inode)
32  {
33 @@ -2158,6 +2163,10 @@ static inline int ext4_get_encryption_info(struct inode *inode)
34  {
35         return 0;
36  }
37 +static inline struct ext4_crypt_info *ext4_encryption_info(struct inode *inode)
39 +       return NULL;
41  #endif
44 diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c
45 index 8fa00d3..5697994 100644
46 --- a/fs/ext4/ialloc.c
47 +++ b/fs/ext4/ialloc.c
48 @@ -726,11 +726,25 @@ struct inode *__ext4_new_inode(handle_t *handle, struct inode *dir,
49         ext4_group_t i;
50         ext4_group_t flex_group;
51         struct ext4_group_info *grp;
52 +       int encrypt = 0;
54         /* Cannot create files in a deleted directory */
55         if (!dir || !dir->i_nlink)
56                 return ERR_PTR(-EPERM);
58 +       if ((ext4_encrypted_inode(dir) ||
59 +            DUMMY_ENCRYPTION_ENABLED(EXT4_SB(dir->i_sb))) &&
60 +           (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode))) {
61 +               err = ext4_get_encryption_info(dir);
62 +               if (err)
63 +                       return ERR_PTR(err);
64 +               if (ext4_encryption_info(dir) == NULL)
65 +                       return ERR_PTR(-EPERM);
66 +               if (!handle)
67 +                       nblocks += EXT4_DATA_TRANS_BLOCKS(dir->i_sb);
68 +               encrypt = 1;
69 +       }
71         sb = dir->i_sb;
72         ngroups = ext4_get_groups_count(sb);
73         trace_ext4_request_inode(dir, mode);
74 @@ -996,12 +1010,6 @@ got:
75         ei->i_block_group = group;
76         ei->i_last_alloc_group = ~0;
78 -       /* If the directory encrypted, then we should encrypt the inode. */
79 -       if ((S_ISDIR(mode) || S_ISREG(mode) || S_ISLNK(mode)) &&
80 -           (ext4_encrypted_inode(dir) ||
81 -            DUMMY_ENCRYPTION_ENABLED(sbi)))
82 -               ext4_set_inode_flag(inode, EXT4_INODE_ENCRYPT);
84         ext4_set_inode_flags(inode);
85         if (IS_DIRSYNC(inode))
86                 ext4_handle_sync(handle);
87 @@ -1063,6 +1071,12 @@ got:
88                 ei->i_datasync_tid = handle->h_transaction->t_tid;
89         }
91 +       if (encrypt) {
92 +               err = ext4_inherit_context(dir, inode);
93 +               if (err)
94 +                       goto fail_free_drop;
95 +       }
97         err = ext4_mark_inode_dirty(handle, inode);
98         if (err) {
99                 ext4_std_error(sb, err);
100 diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
101 index cab7f02..8888977 100644
102 --- a/fs/ext4/namei.c
103 +++ b/fs/ext4/namei.c
104 @@ -2440,20 +2440,7 @@ retry:
105                 else
106                         inode->i_fop = &ext4_file_operations;
107                 ext4_set_aops(inode);
108 -               err = 0;
109 -#ifdef CONFIG_EXT4_FS_ENCRYPTION
110 -               if (!err && (ext4_encrypted_inode(dir) ||
111 -                            DUMMY_ENCRYPTION_ENABLED(EXT4_SB(dir->i_sb)))) {
112 -                       err = ext4_inherit_context(dir, inode);
113 -                       if (err) {
114 -                               clear_nlink(inode);
115 -                               unlock_new_inode(inode);
116 -                               iput(inode);
117 -                       }
118 -               }
119 -#endif
120 -               if (!err)
121 -                       err = ext4_add_nondir(handle, dentry, inode);
122 +               err = ext4_add_nondir(handle, dentry, inode);
123                 if (!err && IS_DIRSYNC(dir))
124                         ext4_handle_sync(handle);
125         }
126 @@ -2637,14 +2624,6 @@ retry:
127         err = ext4_init_new_dir(handle, dir, inode);
128         if (err)
129                 goto out_clear_inode;
130 -#ifdef CONFIG_EXT4_FS_ENCRYPTION
131 -       if (ext4_encrypted_inode(dir) ||
132 -           DUMMY_ENCRYPTION_ENABLED(EXT4_SB(dir->i_sb))) {
133 -               err = ext4_inherit_context(dir, inode);
134 -               if (err)
135 -                       goto out_clear_inode;
136 -       }
137 -#endif
138         err = ext4_mark_inode_dirty(handle, inode);
139         if (!err)
140                 err = ext4_add_entry(handle, dentry, inode);
141 @@ -3112,12 +3091,6 @@ static int ext4_symlink(struct inode *dir,
142                         err = -ENOMEM;
143                         goto err_drop_inode;
144                 }
145 -               err = ext4_inherit_context(dir, inode);
146 -               if (err)
147 -                       goto err_drop_inode;
148 -               err = ext4_get_encryption_info(inode);
149 -               if (err)
150 -                       goto err_drop_inode;
151                 istr.name = (const unsigned char *) symname;
152                 istr.len = len;
153                 ostr.name = sd->encrypted_path;