diff options
-rw-r--r-- | fs/ecryptfs/ecryptfs_kernel.h | 2 | ||||
-rw-r--r-- | fs/ecryptfs/file.c | 71 | ||||
-rw-r--r-- | fs/ecryptfs/inode.c | 4 |
3 files changed, 49 insertions, 28 deletions
diff --git a/fs/ecryptfs/ecryptfs_kernel.h b/fs/ecryptfs/ecryptfs_kernel.h index 0deb4f24957a..9f77ff818173 100644 --- a/fs/ecryptfs/ecryptfs_kernel.h +++ b/fs/ecryptfs/ecryptfs_kernel.h | |||
@@ -563,6 +563,8 @@ struct ecryptfs_open_req { | |||
563 | struct inode *ecryptfs_get_inode(struct inode *lower_inode, | 563 | struct inode *ecryptfs_get_inode(struct inode *lower_inode, |
564 | struct super_block *sb); | 564 | struct super_block *sb); |
565 | void ecryptfs_i_size_init(const char *page_virt, struct inode *inode); | 565 | void ecryptfs_i_size_init(const char *page_virt, struct inode *inode); |
566 | int ecryptfs_initialize_file(struct dentry *ecryptfs_dentry, | ||
567 | struct inode *ecryptfs_inode); | ||
566 | int ecryptfs_decode_and_decrypt_filename(char **decrypted_name, | 568 | int ecryptfs_decode_and_decrypt_filename(char **decrypted_name, |
567 | size_t *decrypted_name_size, | 569 | size_t *decrypted_name_size, |
568 | struct dentry *ecryptfs_dentry, | 570 | struct dentry *ecryptfs_dentry, |
diff --git a/fs/ecryptfs/file.c b/fs/ecryptfs/file.c index 2b17f2f9b121..baf8b0550391 100644 --- a/fs/ecryptfs/file.c +++ b/fs/ecryptfs/file.c | |||
@@ -161,6 +161,48 @@ static int ecryptfs_file_mmap(struct file *file, struct vm_area_struct *vma) | |||
161 | 161 | ||
162 | struct kmem_cache *ecryptfs_file_info_cache; | 162 | struct kmem_cache *ecryptfs_file_info_cache; |
163 | 163 | ||
164 | static int read_or_initialize_metadata(struct dentry *dentry) | ||
165 | { | ||
166 | struct inode *inode = dentry->d_inode; | ||
167 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat; | ||
168 | struct ecryptfs_crypt_stat *crypt_stat; | ||
169 | int rc; | ||
170 | |||
171 | crypt_stat = &ecryptfs_inode_to_private(inode)->crypt_stat; | ||
172 | mount_crypt_stat = &ecryptfs_superblock_to_private( | ||
173 | inode->i_sb)->mount_crypt_stat; | ||
174 | mutex_lock(&crypt_stat->cs_mutex); | ||
175 | |||
176 | if (crypt_stat->flags & ECRYPTFS_POLICY_APPLIED && | ||
177 | crypt_stat->flags & ECRYPTFS_KEY_VALID) { | ||
178 | rc = 0; | ||
179 | goto out; | ||
180 | } | ||
181 | |||
182 | rc = ecryptfs_read_metadata(dentry); | ||
183 | if (!rc) | ||
184 | goto out; | ||
185 | |||
186 | if (mount_crypt_stat->flags & ECRYPTFS_PLAINTEXT_PASSTHROUGH_ENABLED) { | ||
187 | crypt_stat->flags &= ~(ECRYPTFS_I_SIZE_INITIALIZED | ||
188 | | ECRYPTFS_ENCRYPTED); | ||
189 | rc = 0; | ||
190 | goto out; | ||
191 | } | ||
192 | |||
193 | if (!(mount_crypt_stat->flags & ECRYPTFS_XATTR_METADATA_ENABLED) && | ||
194 | !i_size_read(ecryptfs_inode_to_lower(inode))) { | ||
195 | rc = ecryptfs_initialize_file(dentry, inode); | ||
196 | if (!rc) | ||
197 | goto out; | ||
198 | } | ||
199 | |||
200 | rc = -EIO; | ||
201 | out: | ||
202 | mutex_unlock(&crypt_stat->cs_mutex); | ||
203 | return rc; | ||
204 | } | ||
205 | |||
164 | /** | 206 | /** |
165 | * ecryptfs_open | 207 | * ecryptfs_open |
166 | * @inode: inode speciying file to open | 208 | * @inode: inode speciying file to open |
@@ -236,32 +278,9 @@ static int ecryptfs_open(struct inode *inode, struct file *file) | |||
236 | rc = 0; | 278 | rc = 0; |
237 | goto out; | 279 | goto out; |
238 | } | 280 | } |
239 | mutex_lock(&crypt_stat->cs_mutex); | 281 | rc = read_or_initialize_metadata(ecryptfs_dentry); |
240 | if (!(crypt_stat->flags & ECRYPTFS_POLICY_APPLIED) | 282 | if (rc) |
241 | || !(crypt_stat->flags & ECRYPTFS_KEY_VALID)) { | 283 | goto out_put; |
242 | rc = ecryptfs_read_metadata(ecryptfs_dentry); | ||
243 | if (rc) { | ||
244 | ecryptfs_printk(KERN_DEBUG, | ||
245 | "Valid headers not found\n"); | ||
246 | if (!(mount_crypt_stat->flags | ||
247 | & ECRYPTFS_PLAINTEXT_PASSTHROUGH_ENABLED)) { | ||
248 | rc = -EIO; | ||
249 | printk(KERN_WARNING "Either the lower file " | ||
250 | "is not in a valid eCryptfs format, " | ||
251 | "or the key could not be retrieved. " | ||
252 | "Plaintext passthrough mode is not " | ||
253 | "enabled; returning -EIO\n"); | ||
254 | mutex_unlock(&crypt_stat->cs_mutex); | ||
255 | goto out_put; | ||
256 | } | ||
257 | rc = 0; | ||
258 | crypt_stat->flags &= ~(ECRYPTFS_I_SIZE_INITIALIZED | ||
259 | | ECRYPTFS_ENCRYPTED); | ||
260 | mutex_unlock(&crypt_stat->cs_mutex); | ||
261 | goto out; | ||
262 | } | ||
263 | } | ||
264 | mutex_unlock(&crypt_stat->cs_mutex); | ||
265 | ecryptfs_printk(KERN_DEBUG, "inode w/ addr = [0x%p], i_ino = " | 284 | ecryptfs_printk(KERN_DEBUG, "inode w/ addr = [0x%p], i_ino = " |
266 | "[0x%.16lx] size: [0x%.16llx]\n", inode, inode->i_ino, | 285 | "[0x%.16lx] size: [0x%.16llx]\n", inode, inode->i_ino, |
267 | (unsigned long long)i_size_read(inode)); | 286 | (unsigned long long)i_size_read(inode)); |
diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c index 65efe5fa687c..2d4143f8f5c9 100644 --- a/fs/ecryptfs/inode.c +++ b/fs/ecryptfs/inode.c | |||
@@ -227,8 +227,8 @@ out: | |||
227 | * | 227 | * |
228 | * Returns zero on success | 228 | * Returns zero on success |
229 | */ | 229 | */ |
230 | static int ecryptfs_initialize_file(struct dentry *ecryptfs_dentry, | 230 | int ecryptfs_initialize_file(struct dentry *ecryptfs_dentry, |
231 | struct inode *ecryptfs_inode) | 231 | struct inode *ecryptfs_inode) |
232 | { | 232 | { |
233 | struct ecryptfs_crypt_stat *crypt_stat = | 233 | struct ecryptfs_crypt_stat *crypt_stat = |
234 | &ecryptfs_inode_to_private(ecryptfs_inode)->crypt_stat; | 234 | &ecryptfs_inode_to_private(ecryptfs_inode)->crypt_stat; |