diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-04-19 17:20:32 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-04-19 17:20:32 -0400 |
commit | 9b030e2006546366c832911ca5eb9e785408795b (patch) | |
tree | fe2b5913249c047fc8d7f851f7a6a0049825e2d3 /fs/ecryptfs | |
parent | 76e506a754c9519ba0a948b475a62f31fac8b599 (diff) | |
parent | 9f37622f897a90ad3c3da5c14d94d8f3ffc62b70 (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ecryptfs/ecryptfs-2.6
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ecryptfs/ecryptfs-2.6:
eCryptfs: Turn lower lookup error messages into debug messages
eCryptfs: Copy lower directory inode times and size on link
ecryptfs: fix use with tmpfs by removing d_drop from ecryptfs_destroy_inode
ecryptfs: fix error code for missing xattrs in lower fs
eCryptfs: Decrypt symlink target for stat size
eCryptfs: Strip metadata in xattr flag in encrypted view
eCryptfs: Clear buffer before reading in metadata xattr
eCryptfs: Rename ecryptfs_crypt_stat.num_header_bytes_at_front
eCryptfs: Fix metadata in xattr feature regression
Diffstat (limited to 'fs/ecryptfs')
-rw-r--r-- | fs/ecryptfs/crypto.c | 37 | ||||
-rw-r--r-- | fs/ecryptfs/ecryptfs_kernel.h | 13 | ||||
-rw-r--r-- | fs/ecryptfs/inode.c | 129 | ||||
-rw-r--r-- | fs/ecryptfs/mmap.c | 38 | ||||
-rw-r--r-- | fs/ecryptfs/super.c | 1 |
5 files changed, 118 insertions, 100 deletions
diff --git a/fs/ecryptfs/crypto.c b/fs/ecryptfs/crypto.c index efb2b940039..1cc087635a5 100644 --- a/fs/ecryptfs/crypto.c +++ b/fs/ecryptfs/crypto.c | |||
@@ -382,8 +382,8 @@ out: | |||
382 | static void ecryptfs_lower_offset_for_extent(loff_t *offset, loff_t extent_num, | 382 | static void ecryptfs_lower_offset_for_extent(loff_t *offset, loff_t extent_num, |
383 | struct ecryptfs_crypt_stat *crypt_stat) | 383 | struct ecryptfs_crypt_stat *crypt_stat) |
384 | { | 384 | { |
385 | (*offset) = (crypt_stat->num_header_bytes_at_front | 385 | (*offset) = ecryptfs_lower_header_size(crypt_stat) |
386 | + (crypt_stat->extent_size * extent_num)); | 386 | + (crypt_stat->extent_size * extent_num); |
387 | } | 387 | } |
388 | 388 | ||
389 | /** | 389 | /** |
@@ -835,13 +835,13 @@ void ecryptfs_set_default_sizes(struct ecryptfs_crypt_stat *crypt_stat) | |||
835 | set_extent_mask_and_shift(crypt_stat); | 835 | set_extent_mask_and_shift(crypt_stat); |
836 | crypt_stat->iv_bytes = ECRYPTFS_DEFAULT_IV_BYTES; | 836 | crypt_stat->iv_bytes = ECRYPTFS_DEFAULT_IV_BYTES; |
837 | if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR) | 837 | if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR) |
838 | crypt_stat->num_header_bytes_at_front = 0; | 838 | crypt_stat->metadata_size = ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE; |
839 | else { | 839 | else { |
840 | if (PAGE_CACHE_SIZE <= ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE) | 840 | if (PAGE_CACHE_SIZE <= ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE) |
841 | crypt_stat->num_header_bytes_at_front = | 841 | crypt_stat->metadata_size = |
842 | ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE; | 842 | ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE; |
843 | else | 843 | else |
844 | crypt_stat->num_header_bytes_at_front = PAGE_CACHE_SIZE; | 844 | crypt_stat->metadata_size = PAGE_CACHE_SIZE; |
845 | } | 845 | } |
846 | } | 846 | } |
847 | 847 | ||
@@ -1108,9 +1108,9 @@ static void write_ecryptfs_marker(char *page_virt, size_t *written) | |||
1108 | (*written) = MAGIC_ECRYPTFS_MARKER_SIZE_BYTES; | 1108 | (*written) = MAGIC_ECRYPTFS_MARKER_SIZE_BYTES; |
1109 | } | 1109 | } |
1110 | 1110 | ||
1111 | static void | 1111 | void ecryptfs_write_crypt_stat_flags(char *page_virt, |
1112 | write_ecryptfs_flags(char *page_virt, struct ecryptfs_crypt_stat *crypt_stat, | 1112 | struct ecryptfs_crypt_stat *crypt_stat, |
1113 | size_t *written) | 1113 | size_t *written) |
1114 | { | 1114 | { |
1115 | u32 flags = 0; | 1115 | u32 flags = 0; |
1116 | int i; | 1116 | int i; |
@@ -1238,8 +1238,7 @@ ecryptfs_write_header_metadata(char *virt, | |||
1238 | 1238 | ||
1239 | header_extent_size = (u32)crypt_stat->extent_size; | 1239 | header_extent_size = (u32)crypt_stat->extent_size; |
1240 | num_header_extents_at_front = | 1240 | num_header_extents_at_front = |
1241 | (u16)(crypt_stat->num_header_bytes_at_front | 1241 | (u16)(crypt_stat->metadata_size / crypt_stat->extent_size); |
1242 | / crypt_stat->extent_size); | ||
1243 | put_unaligned_be32(header_extent_size, virt); | 1242 | put_unaligned_be32(header_extent_size, virt); |
1244 | virt += 4; | 1243 | virt += 4; |
1245 | put_unaligned_be16(num_header_extents_at_front, virt); | 1244 | put_unaligned_be16(num_header_extents_at_front, virt); |
@@ -1292,7 +1291,8 @@ static int ecryptfs_write_headers_virt(char *page_virt, size_t max, | |||
1292 | offset = ECRYPTFS_FILE_SIZE_BYTES; | 1291 | offset = ECRYPTFS_FILE_SIZE_BYTES; |
1293 | write_ecryptfs_marker((page_virt + offset), &written); | 1292 | write_ecryptfs_marker((page_virt + offset), &written); |
1294 | offset += written; | 1293 | offset += written; |
1295 | write_ecryptfs_flags((page_virt + offset), crypt_stat, &written); | 1294 | ecryptfs_write_crypt_stat_flags((page_virt + offset), crypt_stat, |
1295 | &written); | ||
1296 | offset += written; | 1296 | offset += written; |
1297 | ecryptfs_write_header_metadata((page_virt + offset), crypt_stat, | 1297 | ecryptfs_write_header_metadata((page_virt + offset), crypt_stat, |
1298 | &written); | 1298 | &written); |
@@ -1382,7 +1382,7 @@ int ecryptfs_write_metadata(struct dentry *ecryptfs_dentry) | |||
1382 | rc = -EINVAL; | 1382 | rc = -EINVAL; |
1383 | goto out; | 1383 | goto out; |
1384 | } | 1384 | } |
1385 | virt_len = crypt_stat->num_header_bytes_at_front; | 1385 | virt_len = crypt_stat->metadata_size; |
1386 | order = get_order(virt_len); | 1386 | order = get_order(virt_len); |
1387 | /* Released in this function */ | 1387 | /* Released in this function */ |
1388 | virt = (char *)ecryptfs_get_zeroed_pages(GFP_KERNEL, order); | 1388 | virt = (char *)ecryptfs_get_zeroed_pages(GFP_KERNEL, order); |
@@ -1428,16 +1428,15 @@ static int parse_header_metadata(struct ecryptfs_crypt_stat *crypt_stat, | |||
1428 | header_extent_size = get_unaligned_be32(virt); | 1428 | header_extent_size = get_unaligned_be32(virt); |
1429 | virt += sizeof(__be32); | 1429 | virt += sizeof(__be32); |
1430 | num_header_extents_at_front = get_unaligned_be16(virt); | 1430 | num_header_extents_at_front = get_unaligned_be16(virt); |
1431 | crypt_stat->num_header_bytes_at_front = | 1431 | crypt_stat->metadata_size = (((size_t)num_header_extents_at_front |
1432 | (((size_t)num_header_extents_at_front | 1432 | * (size_t)header_extent_size)); |
1433 | * (size_t)header_extent_size)); | ||
1434 | (*bytes_read) = (sizeof(__be32) + sizeof(__be16)); | 1433 | (*bytes_read) = (sizeof(__be32) + sizeof(__be16)); |
1435 | if ((validate_header_size == ECRYPTFS_VALIDATE_HEADER_SIZE) | 1434 | if ((validate_header_size == ECRYPTFS_VALIDATE_HEADER_SIZE) |
1436 | && (crypt_stat->num_header_bytes_at_front | 1435 | && (crypt_stat->metadata_size |
1437 | < ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE)) { | 1436 | < ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE)) { |
1438 | rc = -EINVAL; | 1437 | rc = -EINVAL; |
1439 | printk(KERN_WARNING "Invalid header size: [%zd]\n", | 1438 | printk(KERN_WARNING "Invalid header size: [%zd]\n", |
1440 | crypt_stat->num_header_bytes_at_front); | 1439 | crypt_stat->metadata_size); |
1441 | } | 1440 | } |
1442 | return rc; | 1441 | return rc; |
1443 | } | 1442 | } |
@@ -1452,8 +1451,7 @@ static int parse_header_metadata(struct ecryptfs_crypt_stat *crypt_stat, | |||
1452 | */ | 1451 | */ |
1453 | static void set_default_header_data(struct ecryptfs_crypt_stat *crypt_stat) | 1452 | static void set_default_header_data(struct ecryptfs_crypt_stat *crypt_stat) |
1454 | { | 1453 | { |
1455 | crypt_stat->num_header_bytes_at_front = | 1454 | crypt_stat->metadata_size = ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE; |
1456 | ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE; | ||
1457 | } | 1455 | } |
1458 | 1456 | ||
1459 | /** | 1457 | /** |
@@ -1607,6 +1605,7 @@ int ecryptfs_read_metadata(struct dentry *ecryptfs_dentry) | |||
1607 | ecryptfs_dentry, | 1605 | ecryptfs_dentry, |
1608 | ECRYPTFS_VALIDATE_HEADER_SIZE); | 1606 | ECRYPTFS_VALIDATE_HEADER_SIZE); |
1609 | if (rc) { | 1607 | if (rc) { |
1608 | memset(page_virt, 0, PAGE_CACHE_SIZE); | ||
1610 | rc = ecryptfs_read_xattr_region(page_virt, ecryptfs_inode); | 1609 | rc = ecryptfs_read_xattr_region(page_virt, ecryptfs_inode); |
1611 | if (rc) { | 1610 | if (rc) { |
1612 | printk(KERN_DEBUG "Valid eCryptfs headers not found in " | 1611 | printk(KERN_DEBUG "Valid eCryptfs headers not found in " |
diff --git a/fs/ecryptfs/ecryptfs_kernel.h b/fs/ecryptfs/ecryptfs_kernel.h index 542f625312f..bc7115403f3 100644 --- a/fs/ecryptfs/ecryptfs_kernel.h +++ b/fs/ecryptfs/ecryptfs_kernel.h | |||
@@ -273,7 +273,7 @@ struct ecryptfs_crypt_stat { | |||
273 | u32 flags; | 273 | u32 flags; |
274 | unsigned int file_version; | 274 | unsigned int file_version; |
275 | size_t iv_bytes; | 275 | size_t iv_bytes; |
276 | size_t num_header_bytes_at_front; | 276 | size_t metadata_size; |
277 | size_t extent_size; /* Data extent size; default is 4096 */ | 277 | size_t extent_size; /* Data extent size; default is 4096 */ |
278 | size_t key_size; | 278 | size_t key_size; |
279 | size_t extent_shift; | 279 | size_t extent_shift; |
@@ -464,6 +464,14 @@ struct ecryptfs_daemon { | |||
464 | 464 | ||
465 | extern struct mutex ecryptfs_daemon_hash_mux; | 465 | extern struct mutex ecryptfs_daemon_hash_mux; |
466 | 466 | ||
467 | static inline size_t | ||
468 | ecryptfs_lower_header_size(struct ecryptfs_crypt_stat *crypt_stat) | ||
469 | { | ||
470 | if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR) | ||
471 | return 0; | ||
472 | return crypt_stat->metadata_size; | ||
473 | } | ||
474 | |||
467 | static inline struct ecryptfs_file_info * | 475 | static inline struct ecryptfs_file_info * |
468 | ecryptfs_file_to_private(struct file *file) | 476 | ecryptfs_file_to_private(struct file *file) |
469 | { | 477 | { |
@@ -651,6 +659,9 @@ int ecryptfs_decrypt_page(struct page *page); | |||
651 | int ecryptfs_write_metadata(struct dentry *ecryptfs_dentry); | 659 | int ecryptfs_write_metadata(struct dentry *ecryptfs_dentry); |
652 | int ecryptfs_read_metadata(struct dentry *ecryptfs_dentry); | 660 | int ecryptfs_read_metadata(struct dentry *ecryptfs_dentry); |
653 | int ecryptfs_new_file_context(struct dentry *ecryptfs_dentry); | 661 | int ecryptfs_new_file_context(struct dentry *ecryptfs_dentry); |
662 | void ecryptfs_write_crypt_stat_flags(char *page_virt, | ||
663 | struct ecryptfs_crypt_stat *crypt_stat, | ||
664 | size_t *written); | ||
654 | int ecryptfs_read_and_validate_header_region(char *data, | 665 | int ecryptfs_read_and_validate_header_region(char *data, |
655 | struct inode *ecryptfs_inode); | 666 | struct inode *ecryptfs_inode); |
656 | int ecryptfs_read_and_validate_xattr_region(char *page_virt, | 667 | int ecryptfs_read_and_validate_xattr_region(char *page_virt, |
diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c index d3362faf385..e2d4418affa 100644 --- a/fs/ecryptfs/inode.c +++ b/fs/ecryptfs/inode.c | |||
@@ -324,6 +324,7 @@ int ecryptfs_lookup_and_interpose_lower(struct dentry *ecryptfs_dentry, | |||
324 | rc = ecryptfs_read_and_validate_header_region(page_virt, | 324 | rc = ecryptfs_read_and_validate_header_region(page_virt, |
325 | ecryptfs_dentry->d_inode); | 325 | ecryptfs_dentry->d_inode); |
326 | if (rc) { | 326 | if (rc) { |
327 | memset(page_virt, 0, PAGE_CACHE_SIZE); | ||
327 | rc = ecryptfs_read_and_validate_xattr_region(page_virt, | 328 | rc = ecryptfs_read_and_validate_xattr_region(page_virt, |
328 | ecryptfs_dentry); | 329 | ecryptfs_dentry); |
329 | if (rc) { | 330 | if (rc) { |
@@ -336,7 +337,7 @@ int ecryptfs_lookup_and_interpose_lower(struct dentry *ecryptfs_dentry, | |||
336 | ecryptfs_dentry->d_sb)->mount_crypt_stat; | 337 | ecryptfs_dentry->d_sb)->mount_crypt_stat; |
337 | if (mount_crypt_stat->flags & ECRYPTFS_ENCRYPTED_VIEW_ENABLED) { | 338 | if (mount_crypt_stat->flags & ECRYPTFS_ENCRYPTED_VIEW_ENABLED) { |
338 | if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR) | 339 | if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR) |
339 | file_size = (crypt_stat->num_header_bytes_at_front | 340 | file_size = (crypt_stat->metadata_size |
340 | + i_size_read(lower_dentry->d_inode)); | 341 | + i_size_read(lower_dentry->d_inode)); |
341 | else | 342 | else |
342 | file_size = i_size_read(lower_dentry->d_inode); | 343 | file_size = i_size_read(lower_dentry->d_inode); |
@@ -388,9 +389,9 @@ static struct dentry *ecryptfs_lookup(struct inode *ecryptfs_dir_inode, | |||
388 | mutex_unlock(&lower_dir_dentry->d_inode->i_mutex); | 389 | mutex_unlock(&lower_dir_dentry->d_inode->i_mutex); |
389 | if (IS_ERR(lower_dentry)) { | 390 | if (IS_ERR(lower_dentry)) { |
390 | rc = PTR_ERR(lower_dentry); | 391 | rc = PTR_ERR(lower_dentry); |
391 | printk(KERN_ERR "%s: lookup_one_len() returned [%d] on " | 392 | ecryptfs_printk(KERN_DEBUG, "%s: lookup_one_len() returned " |
392 | "lower_dentry = [%s]\n", __func__, rc, | 393 | "[%d] on lower_dentry = [%s]\n", __func__, rc, |
393 | ecryptfs_dentry->d_name.name); | 394 | encrypted_and_encoded_name); |
394 | goto out_d_drop; | 395 | goto out_d_drop; |
395 | } | 396 | } |
396 | if (lower_dentry->d_inode) | 397 | if (lower_dentry->d_inode) |
@@ -417,9 +418,9 @@ static struct dentry *ecryptfs_lookup(struct inode *ecryptfs_dir_inode, | |||
417 | mutex_unlock(&lower_dir_dentry->d_inode->i_mutex); | 418 | mutex_unlock(&lower_dir_dentry->d_inode->i_mutex); |
418 | if (IS_ERR(lower_dentry)) { | 419 | if (IS_ERR(lower_dentry)) { |
419 | rc = PTR_ERR(lower_dentry); | 420 | rc = PTR_ERR(lower_dentry); |
420 | printk(KERN_ERR "%s: lookup_one_len() returned [%d] on " | 421 | ecryptfs_printk(KERN_DEBUG, "%s: lookup_one_len() returned " |
421 | "lower_dentry = [%s]\n", __func__, rc, | 422 | "[%d] on lower_dentry = [%s]\n", __func__, rc, |
422 | encrypted_and_encoded_name); | 423 | encrypted_and_encoded_name); |
423 | goto out_d_drop; | 424 | goto out_d_drop; |
424 | } | 425 | } |
425 | lookup_and_interpose: | 426 | lookup_and_interpose: |
@@ -456,8 +457,8 @@ static int ecryptfs_link(struct dentry *old_dentry, struct inode *dir, | |||
456 | rc = ecryptfs_interpose(lower_new_dentry, new_dentry, dir->i_sb, 0); | 457 | rc = ecryptfs_interpose(lower_new_dentry, new_dentry, dir->i_sb, 0); |
457 | if (rc) | 458 | if (rc) |
458 | goto out_lock; | 459 | goto out_lock; |
459 | fsstack_copy_attr_times(dir, lower_new_dentry->d_inode); | 460 | fsstack_copy_attr_times(dir, lower_dir_dentry->d_inode); |
460 | fsstack_copy_inode_size(dir, lower_new_dentry->d_inode); | 461 | fsstack_copy_inode_size(dir, lower_dir_dentry->d_inode); |
461 | old_dentry->d_inode->i_nlink = | 462 | old_dentry->d_inode->i_nlink = |
462 | ecryptfs_inode_to_lower(old_dentry->d_inode)->i_nlink; | 463 | ecryptfs_inode_to_lower(old_dentry->d_inode)->i_nlink; |
463 | i_size_write(new_dentry->d_inode, file_size_save); | 464 | i_size_write(new_dentry->d_inode, file_size_save); |
@@ -648,38 +649,17 @@ out_lock: | |||
648 | return rc; | 649 | return rc; |
649 | } | 650 | } |
650 | 651 | ||
651 | static int | 652 | static int ecryptfs_readlink_lower(struct dentry *dentry, char **buf, |
652 | ecryptfs_readlink(struct dentry *dentry, char __user *buf, int bufsiz) | 653 | size_t *bufsiz) |
653 | { | 654 | { |
655 | struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry); | ||
654 | char *lower_buf; | 656 | char *lower_buf; |
655 | size_t lower_bufsiz; | 657 | size_t lower_bufsiz = PATH_MAX; |
656 | struct dentry *lower_dentry; | ||
657 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat; | ||
658 | char *plaintext_name; | ||
659 | size_t plaintext_name_size; | ||
660 | mm_segment_t old_fs; | 658 | mm_segment_t old_fs; |
661 | int rc; | 659 | int rc; |
662 | 660 | ||
663 | lower_dentry = ecryptfs_dentry_to_lower(dentry); | ||
664 | if (!lower_dentry->d_inode->i_op->readlink) { | ||
665 | rc = -EINVAL; | ||
666 | goto out; | ||
667 | } | ||
668 | mount_crypt_stat = &ecryptfs_superblock_to_private( | ||
669 | dentry->d_sb)->mount_crypt_stat; | ||
670 | /* | ||
671 | * If the lower filename is encrypted, it will result in a significantly | ||
672 | * longer name. If needed, truncate the name after decode and decrypt. | ||
673 | */ | ||
674 | if (mount_crypt_stat->flags & ECRYPTFS_GLOBAL_ENCRYPT_FILENAMES) | ||
675 | lower_bufsiz = PATH_MAX; | ||
676 | else | ||
677 | lower_bufsiz = bufsiz; | ||
678 | /* Released in this function */ | ||
679 | lower_buf = kmalloc(lower_bufsiz, GFP_KERNEL); | 661 | lower_buf = kmalloc(lower_bufsiz, GFP_KERNEL); |
680 | if (lower_buf == NULL) { | 662 | if (!lower_buf) { |
681 | printk(KERN_ERR "%s: Out of memory whilst attempting to " | ||
682 | "kmalloc [%zd] bytes\n", __func__, lower_bufsiz); | ||
683 | rc = -ENOMEM; | 663 | rc = -ENOMEM; |
684 | goto out; | 664 | goto out; |
685 | } | 665 | } |
@@ -689,29 +669,31 @@ ecryptfs_readlink(struct dentry *dentry, char __user *buf, int bufsiz) | |||
689 | (char __user *)lower_buf, | 669 | (char __user *)lower_buf, |
690 | lower_bufsiz); | 670 | lower_bufsiz); |
691 | set_fs(old_fs); | 671 | set_fs(old_fs); |
692 | if (rc >= 0) { | 672 | if (rc < 0) |
693 | rc = ecryptfs_decode_and_decrypt_filename(&plaintext_name, | 673 | goto out; |
694 | &plaintext_name_size, | 674 | lower_bufsiz = rc; |
695 | dentry, lower_buf, | 675 | rc = ecryptfs_decode_and_decrypt_filename(buf, bufsiz, dentry, |
696 | rc); | 676 | lower_buf, lower_bufsiz); |
697 | if (rc) { | 677 | out: |
698 | printk(KERN_ERR "%s: Error attempting to decode and " | ||
699 | "decrypt filename; rc = [%d]\n", __func__, | ||
700 | rc); | ||
701 | goto out_free_lower_buf; | ||
702 | } | ||
703 | /* Check for bufsiz <= 0 done in sys_readlinkat() */ | ||
704 | rc = copy_to_user(buf, plaintext_name, | ||
705 | min((size_t) bufsiz, plaintext_name_size)); | ||
706 | if (rc) | ||
707 | rc = -EFAULT; | ||
708 | else | ||
709 | rc = plaintext_name_size; | ||
710 | kfree(plaintext_name); | ||
711 | fsstack_copy_attr_atime(dentry->d_inode, lower_dentry->d_inode); | ||
712 | } | ||
713 | out_free_lower_buf: | ||
714 | kfree(lower_buf); | 678 | kfree(lower_buf); |
679 | return rc; | ||
680 | } | ||
681 | |||
682 | static int | ||
683 | ecryptfs_readlink(struct dentry *dentry, char __user *buf, int bufsiz) | ||
684 | { | ||
685 | char *kbuf; | ||
686 | size_t kbufsiz, copied; | ||
687 | int rc; | ||
688 | |||
689 | rc = ecryptfs_readlink_lower(dentry, &kbuf, &kbufsiz); | ||
690 | if (rc) | ||
691 | goto out; | ||
692 | copied = min_t(size_t, bufsiz, kbufsiz); | ||
693 | rc = copy_to_user(buf, kbuf, copied) ? -EFAULT : copied; | ||
694 | kfree(kbuf); | ||
695 | fsstack_copy_attr_atime(dentry->d_inode, | ||
696 | ecryptfs_dentry_to_lower(dentry)->d_inode); | ||
715 | out: | 697 | out: |
716 | return rc; | 698 | return rc; |
717 | } | 699 | } |
@@ -769,7 +751,7 @@ upper_size_to_lower_size(struct ecryptfs_crypt_stat *crypt_stat, | |||
769 | { | 751 | { |
770 | loff_t lower_size; | 752 | loff_t lower_size; |
771 | 753 | ||
772 | lower_size = crypt_stat->num_header_bytes_at_front; | 754 | lower_size = ecryptfs_lower_header_size(crypt_stat); |
773 | if (upper_size != 0) { | 755 | if (upper_size != 0) { |
774 | loff_t num_extents; | 756 | loff_t num_extents; |
775 | 757 | ||
@@ -1016,6 +998,28 @@ out: | |||
1016 | return rc; | 998 | return rc; |
1017 | } | 999 | } |
1018 | 1000 | ||
1001 | int ecryptfs_getattr_link(struct vfsmount *mnt, struct dentry *dentry, | ||
1002 | struct kstat *stat) | ||
1003 | { | ||
1004 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat; | ||
1005 | int rc = 0; | ||
1006 | |||
1007 | mount_crypt_stat = &ecryptfs_superblock_to_private( | ||
1008 | dentry->d_sb)->mount_crypt_stat; | ||
1009 | generic_fillattr(dentry->d_inode, stat); | ||
1010 | if (mount_crypt_stat->flags & ECRYPTFS_GLOBAL_ENCRYPT_FILENAMES) { | ||
1011 | char *target; | ||
1012 | size_t targetsiz; | ||
1013 | |||
1014 | rc = ecryptfs_readlink_lower(dentry, &target, &targetsiz); | ||
1015 | if (!rc) { | ||
1016 | kfree(target); | ||
1017 | stat->size = targetsiz; | ||
1018 | } | ||
1019 | } | ||
1020 | return rc; | ||
1021 | } | ||
1022 | |||
1019 | int ecryptfs_getattr(struct vfsmount *mnt, struct dentry *dentry, | 1023 | int ecryptfs_getattr(struct vfsmount *mnt, struct dentry *dentry, |
1020 | struct kstat *stat) | 1024 | struct kstat *stat) |
1021 | { | 1025 | { |
@@ -1040,7 +1044,7 @@ ecryptfs_setxattr(struct dentry *dentry, const char *name, const void *value, | |||
1040 | 1044 | ||
1041 | lower_dentry = ecryptfs_dentry_to_lower(dentry); | 1045 | lower_dentry = ecryptfs_dentry_to_lower(dentry); |
1042 | if (!lower_dentry->d_inode->i_op->setxattr) { | 1046 | if (!lower_dentry->d_inode->i_op->setxattr) { |
1043 | rc = -ENOSYS; | 1047 | rc = -EOPNOTSUPP; |
1044 | goto out; | 1048 | goto out; |
1045 | } | 1049 | } |
1046 | mutex_lock(&lower_dentry->d_inode->i_mutex); | 1050 | mutex_lock(&lower_dentry->d_inode->i_mutex); |
@@ -1058,7 +1062,7 @@ ecryptfs_getxattr_lower(struct dentry *lower_dentry, const char *name, | |||
1058 | int rc = 0; | 1062 | int rc = 0; |
1059 | 1063 | ||
1060 | if (!lower_dentry->d_inode->i_op->getxattr) { | 1064 | if (!lower_dentry->d_inode->i_op->getxattr) { |
1061 | rc = -ENOSYS; | 1065 | rc = -EOPNOTSUPP; |
1062 | goto out; | 1066 | goto out; |
1063 | } | 1067 | } |
1064 | mutex_lock(&lower_dentry->d_inode->i_mutex); | 1068 | mutex_lock(&lower_dentry->d_inode->i_mutex); |
@@ -1085,7 +1089,7 @@ ecryptfs_listxattr(struct dentry *dentry, char *list, size_t size) | |||
1085 | 1089 | ||
1086 | lower_dentry = ecryptfs_dentry_to_lower(dentry); | 1090 | lower_dentry = ecryptfs_dentry_to_lower(dentry); |
1087 | if (!lower_dentry->d_inode->i_op->listxattr) { | 1091 | if (!lower_dentry->d_inode->i_op->listxattr) { |
1088 | rc = -ENOSYS; | 1092 | rc = -EOPNOTSUPP; |
1089 | goto out; | 1093 | goto out; |
1090 | } | 1094 | } |
1091 | mutex_lock(&lower_dentry->d_inode->i_mutex); | 1095 | mutex_lock(&lower_dentry->d_inode->i_mutex); |
@@ -1102,7 +1106,7 @@ static int ecryptfs_removexattr(struct dentry *dentry, const char *name) | |||
1102 | 1106 | ||
1103 | lower_dentry = ecryptfs_dentry_to_lower(dentry); | 1107 | lower_dentry = ecryptfs_dentry_to_lower(dentry); |
1104 | if (!lower_dentry->d_inode->i_op->removexattr) { | 1108 | if (!lower_dentry->d_inode->i_op->removexattr) { |
1105 | rc = -ENOSYS; | 1109 | rc = -EOPNOTSUPP; |
1106 | goto out; | 1110 | goto out; |
1107 | } | 1111 | } |
1108 | mutex_lock(&lower_dentry->d_inode->i_mutex); | 1112 | mutex_lock(&lower_dentry->d_inode->i_mutex); |
@@ -1133,6 +1137,7 @@ const struct inode_operations ecryptfs_symlink_iops = { | |||
1133 | .put_link = ecryptfs_put_link, | 1137 | .put_link = ecryptfs_put_link, |
1134 | .permission = ecryptfs_permission, | 1138 | .permission = ecryptfs_permission, |
1135 | .setattr = ecryptfs_setattr, | 1139 | .setattr = ecryptfs_setattr, |
1140 | .getattr = ecryptfs_getattr_link, | ||
1136 | .setxattr = ecryptfs_setxattr, | 1141 | .setxattr = ecryptfs_setxattr, |
1137 | .getxattr = ecryptfs_getxattr, | 1142 | .getxattr = ecryptfs_getxattr, |
1138 | .listxattr = ecryptfs_listxattr, | 1143 | .listxattr = ecryptfs_listxattr, |
diff --git a/fs/ecryptfs/mmap.c b/fs/ecryptfs/mmap.c index d491237c98e..2ee9a3a7b68 100644 --- a/fs/ecryptfs/mmap.c +++ b/fs/ecryptfs/mmap.c | |||
@@ -83,6 +83,19 @@ out: | |||
83 | return rc; | 83 | return rc; |
84 | } | 84 | } |
85 | 85 | ||
86 | static void strip_xattr_flag(char *page_virt, | ||
87 | struct ecryptfs_crypt_stat *crypt_stat) | ||
88 | { | ||
89 | if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR) { | ||
90 | size_t written; | ||
91 | |||
92 | crypt_stat->flags &= ~ECRYPTFS_METADATA_IN_XATTR; | ||
93 | ecryptfs_write_crypt_stat_flags(page_virt, crypt_stat, | ||
94 | &written); | ||
95 | crypt_stat->flags |= ECRYPTFS_METADATA_IN_XATTR; | ||
96 | } | ||
97 | } | ||
98 | |||
86 | /** | 99 | /** |
87 | * Header Extent: | 100 | * Header Extent: |
88 | * Octets 0-7: Unencrypted file size (big-endian) | 101 | * Octets 0-7: Unencrypted file size (big-endian) |
@@ -98,19 +111,6 @@ out: | |||
98 | * (big-endian) | 111 | * (big-endian) |
99 | * Octet 26: Begin RFC 2440 authentication token packet set | 112 | * Octet 26: Begin RFC 2440 authentication token packet set |
100 | */ | 113 | */ |
101 | static void set_header_info(char *page_virt, | ||
102 | struct ecryptfs_crypt_stat *crypt_stat) | ||
103 | { | ||
104 | size_t written; | ||
105 | size_t save_num_header_bytes_at_front = | ||
106 | crypt_stat->num_header_bytes_at_front; | ||
107 | |||
108 | crypt_stat->num_header_bytes_at_front = | ||
109 | ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE; | ||
110 | ecryptfs_write_header_metadata(page_virt + 20, crypt_stat, &written); | ||
111 | crypt_stat->num_header_bytes_at_front = | ||
112 | save_num_header_bytes_at_front; | ||
113 | } | ||
114 | 114 | ||
115 | /** | 115 | /** |
116 | * ecryptfs_copy_up_encrypted_with_header | 116 | * ecryptfs_copy_up_encrypted_with_header |
@@ -136,8 +136,7 @@ ecryptfs_copy_up_encrypted_with_header(struct page *page, | |||
136 | * num_extents_per_page) | 136 | * num_extents_per_page) |
137 | + extent_num_in_page); | 137 | + extent_num_in_page); |
138 | size_t num_header_extents_at_front = | 138 | size_t num_header_extents_at_front = |
139 | (crypt_stat->num_header_bytes_at_front | 139 | (crypt_stat->metadata_size / crypt_stat->extent_size); |
140 | / crypt_stat->extent_size); | ||
141 | 140 | ||
142 | if (view_extent_num < num_header_extents_at_front) { | 141 | if (view_extent_num < num_header_extents_at_front) { |
143 | /* This is a header extent */ | 142 | /* This is a header extent */ |
@@ -147,9 +146,14 @@ ecryptfs_copy_up_encrypted_with_header(struct page *page, | |||
147 | memset(page_virt, 0, PAGE_CACHE_SIZE); | 146 | memset(page_virt, 0, PAGE_CACHE_SIZE); |
148 | /* TODO: Support more than one header extent */ | 147 | /* TODO: Support more than one header extent */ |
149 | if (view_extent_num == 0) { | 148 | if (view_extent_num == 0) { |
149 | size_t written; | ||
150 | |||
150 | rc = ecryptfs_read_xattr_region( | 151 | rc = ecryptfs_read_xattr_region( |
151 | page_virt, page->mapping->host); | 152 | page_virt, page->mapping->host); |
152 | set_header_info(page_virt, crypt_stat); | 153 | strip_xattr_flag(page_virt + 16, crypt_stat); |
154 | ecryptfs_write_header_metadata(page_virt + 20, | ||
155 | crypt_stat, | ||
156 | &written); | ||
153 | } | 157 | } |
154 | kunmap_atomic(page_virt, KM_USER0); | 158 | kunmap_atomic(page_virt, KM_USER0); |
155 | flush_dcache_page(page); | 159 | flush_dcache_page(page); |
@@ -162,7 +166,7 @@ ecryptfs_copy_up_encrypted_with_header(struct page *page, | |||
162 | /* This is an encrypted data extent */ | 166 | /* This is an encrypted data extent */ |
163 | loff_t lower_offset = | 167 | loff_t lower_offset = |
164 | ((view_extent_num * crypt_stat->extent_size) | 168 | ((view_extent_num * crypt_stat->extent_size) |
165 | - crypt_stat->num_header_bytes_at_front); | 169 | - crypt_stat->metadata_size); |
166 | 170 | ||
167 | rc = ecryptfs_read_lower_page_segment( | 171 | rc = ecryptfs_read_lower_page_segment( |
168 | page, (lower_offset >> PAGE_CACHE_SHIFT), | 172 | page, (lower_offset >> PAGE_CACHE_SHIFT), |
diff --git a/fs/ecryptfs/super.c b/fs/ecryptfs/super.c index fcef41c1d2c..278743c7716 100644 --- a/fs/ecryptfs/super.c +++ b/fs/ecryptfs/super.c | |||
@@ -86,7 +86,6 @@ static void ecryptfs_destroy_inode(struct inode *inode) | |||
86 | if (lower_dentry->d_inode) { | 86 | if (lower_dentry->d_inode) { |
87 | fput(inode_info->lower_file); | 87 | fput(inode_info->lower_file); |
88 | inode_info->lower_file = NULL; | 88 | inode_info->lower_file = NULL; |
89 | d_drop(lower_dentry); | ||
90 | } | 89 | } |
91 | } | 90 | } |
92 | ecryptfs_destroy_crypt_stat(&inode_info->crypt_stat); | 91 | ecryptfs_destroy_crypt_stat(&inode_info->crypt_stat); |