diff options
Diffstat (limited to 'fs/ecryptfs/file.c')
-rw-r--r-- | fs/ecryptfs/file.c | 52 |
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 | } |