aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ecryptfs/file.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ecryptfs/file.c')
-rw-r--r--fs/ecryptfs/file.c52
1 files changed, 21 insertions, 31 deletions
diff --git a/fs/ecryptfs/file.c b/fs/ecryptfs/file.c
index c5a2e5298f15..bd969adf70d7 100644
--- a/fs/ecryptfs/file.c
+++ b/fs/ecryptfs/file.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * Copyright (C) 1997-2004 Erez Zadok 4 * Copyright (C) 1997-2004 Erez Zadok
5 * Copyright (C) 2001-2004 Stony Brook University 5 * Copyright (C) 2001-2004 Stony Brook University
6 * Copyright (C) 2004-2006 International Business Machines Corp. 6 * Copyright (C) 2004-2007 International Business Machines Corp.
7 * Author(s): Michael A. Halcrow <mhalcrow@us.ibm.com> 7 * Author(s): Michael A. Halcrow <mhalcrow@us.ibm.com>
8 * Michael C. Thompson <mcthomps@us.ibm.com> 8 * Michael C. Thompson <mcthomps@us.ibm.com>
9 * 9 *
@@ -250,8 +250,19 @@ static int ecryptfs_open(struct inode *inode, struct file *file)
250 struct ecryptfs_file_info *file_info; 250 struct ecryptfs_file_info *file_info;
251 int lower_flags; 251 int lower_flags;
252 252
253 mount_crypt_stat = &ecryptfs_superblock_to_private(
254 ecryptfs_dentry->d_sb)->mount_crypt_stat;
255 if ((mount_crypt_stat->flags & ECRYPTFS_ENCRYPTED_VIEW_ENABLED)
256 && ((file->f_flags & O_WRONLY) || (file->f_flags & O_RDWR)
257 || (file->f_flags & O_CREAT) || (file->f_flags & O_TRUNC)
258 || (file->f_flags & O_APPEND))) {
259 printk(KERN_WARNING "Mount has encrypted view enabled; "
260 "files may only be read\n");
261 rc = -EPERM;
262 goto out;
263 }
253 /* Released in ecryptfs_release or end of function if failure */ 264 /* Released in ecryptfs_release or end of function if failure */
254 file_info = kmem_cache_alloc(ecryptfs_file_info_cache, GFP_KERNEL); 265 file_info = kmem_cache_zalloc(ecryptfs_file_info_cache, GFP_KERNEL);
255 ecryptfs_set_file_private(file, file_info); 266 ecryptfs_set_file_private(file, file_info);
256 if (!file_info) { 267 if (!file_info) {
257 ecryptfs_printk(KERN_ERR, 268 ecryptfs_printk(KERN_ERR,
@@ -259,17 +270,14 @@ static int ecryptfs_open(struct inode *inode, struct file *file)
259 rc = -ENOMEM; 270 rc = -ENOMEM;
260 goto out; 271 goto out;
261 } 272 }
262 memset(file_info, 0, sizeof(*file_info));
263 lower_dentry = ecryptfs_dentry_to_lower(ecryptfs_dentry); 273 lower_dentry = ecryptfs_dentry_to_lower(ecryptfs_dentry);
264 crypt_stat = &ecryptfs_inode_to_private(inode)->crypt_stat; 274 crypt_stat = &ecryptfs_inode_to_private(inode)->crypt_stat;
265 mount_crypt_stat = &ecryptfs_superblock_to_private(
266 ecryptfs_dentry->d_sb)->mount_crypt_stat;
267 mutex_lock(&crypt_stat->cs_mutex); 275 mutex_lock(&crypt_stat->cs_mutex);
268 if (!ECRYPTFS_CHECK_FLAG(crypt_stat->flags, ECRYPTFS_POLICY_APPLIED)) { 276 if (!(crypt_stat->flags & ECRYPTFS_POLICY_APPLIED)) {
269 ecryptfs_printk(KERN_DEBUG, "Setting flags for stat...\n"); 277 ecryptfs_printk(KERN_DEBUG, "Setting flags for stat...\n");
270 /* Policy code enabled in future release */ 278 /* Policy code enabled in future release */
271 ECRYPTFS_SET_FLAG(crypt_stat->flags, ECRYPTFS_POLICY_APPLIED); 279 crypt_stat->flags |= ECRYPTFS_POLICY_APPLIED;
272 ECRYPTFS_SET_FLAG(crypt_stat->flags, ECRYPTFS_ENCRYPTED); 280 crypt_stat->flags |= ECRYPTFS_ENCRYPTED;
273 } 281 }
274 mutex_unlock(&crypt_stat->cs_mutex); 282 mutex_unlock(&crypt_stat->cs_mutex);
275 lower_flags = file->f_flags; 283 lower_flags = file->f_flags;
@@ -289,31 +297,14 @@ static int ecryptfs_open(struct inode *inode, struct file *file)
289 lower_inode = lower_dentry->d_inode; 297 lower_inode = lower_dentry->d_inode;
290 if (S_ISDIR(ecryptfs_dentry->d_inode->i_mode)) { 298 if (S_ISDIR(ecryptfs_dentry->d_inode->i_mode)) {
291 ecryptfs_printk(KERN_DEBUG, "This is a directory\n"); 299 ecryptfs_printk(KERN_DEBUG, "This is a directory\n");
292 ECRYPTFS_CLEAR_FLAG(crypt_stat->flags, ECRYPTFS_ENCRYPTED); 300 crypt_stat->flags &= ~(ECRYPTFS_ENCRYPTED);
293 rc = 0; 301 rc = 0;
294 goto out; 302 goto out;
295 } 303 }
296 mutex_lock(&crypt_stat->cs_mutex); 304 mutex_lock(&crypt_stat->cs_mutex);
297 if (i_size_read(lower_inode) < ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE) { 305 if (!(crypt_stat->flags & ECRYPTFS_POLICY_APPLIED)
298 if (!(mount_crypt_stat->flags 306 || !(crypt_stat->flags & ECRYPTFS_KEY_VALID)) {
299 & ECRYPTFS_PLAINTEXT_PASSTHROUGH_ENABLED)) { 307 rc = ecryptfs_read_metadata(ecryptfs_dentry, lower_file);
300 rc = -EIO;
301 printk(KERN_WARNING "Attempt to read file that is "
302 "not in a valid eCryptfs format, and plaintext "
303 "passthrough mode is not enabled; returning "
304 "-EIO\n");
305 mutex_unlock(&crypt_stat->cs_mutex);
306 goto out_puts;
307 }
308 crypt_stat->flags &= ~(ECRYPTFS_ENCRYPTED);
309 rc = 0;
310 mutex_unlock(&crypt_stat->cs_mutex);
311 goto out;
312 } else if (!ECRYPTFS_CHECK_FLAG(crypt_stat->flags,
313 ECRYPTFS_POLICY_APPLIED)
314 || !ECRYPTFS_CHECK_FLAG(crypt_stat->flags,
315 ECRYPTFS_KEY_VALID)) {
316 rc = ecryptfs_read_headers(ecryptfs_dentry, lower_file);
317 if (rc) { 308 if (rc) {
318 ecryptfs_printk(KERN_DEBUG, 309 ecryptfs_printk(KERN_DEBUG,
319 "Valid headers not found\n"); 310 "Valid headers not found\n");
@@ -327,9 +318,8 @@ static int ecryptfs_open(struct inode *inode, struct file *file)
327 mutex_unlock(&crypt_stat->cs_mutex); 318 mutex_unlock(&crypt_stat->cs_mutex);
328 goto out_puts; 319 goto out_puts;
329 } 320 }
330 ECRYPTFS_CLEAR_FLAG(crypt_stat->flags,
331 ECRYPTFS_ENCRYPTED);
332 rc = 0; 321 rc = 0;
322 crypt_stat->flags &= ~(ECRYPTFS_ENCRYPTED);
333 mutex_unlock(&crypt_stat->cs_mutex); 323 mutex_unlock(&crypt_stat->cs_mutex);
334 goto out; 324 goto out;
335 } 325 }