diff options
Diffstat (limited to 'fs/ecryptfs/inode.c')
-rw-r--r-- | fs/ecryptfs/inode.c | 130 |
1 files changed, 68 insertions, 62 deletions
diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c index 4a430ab4115c..e2d4418affac 100644 --- a/fs/ecryptfs/inode.c +++ b/fs/ecryptfs/inode.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include <linux/mount.h> | 31 | #include <linux/mount.h> |
32 | #include <linux/crypto.h> | 32 | #include <linux/crypto.h> |
33 | #include <linux/fs_stack.h> | 33 | #include <linux/fs_stack.h> |
34 | #include <linux/slab.h> | ||
34 | #include <asm/unaligned.h> | 35 | #include <asm/unaligned.h> |
35 | #include "ecryptfs_kernel.h" | 36 | #include "ecryptfs_kernel.h" |
36 | 37 | ||
@@ -323,6 +324,7 @@ int ecryptfs_lookup_and_interpose_lower(struct dentry *ecryptfs_dentry, | |||
323 | rc = ecryptfs_read_and_validate_header_region(page_virt, | 324 | rc = ecryptfs_read_and_validate_header_region(page_virt, |
324 | ecryptfs_dentry->d_inode); | 325 | ecryptfs_dentry->d_inode); |
325 | if (rc) { | 326 | if (rc) { |
327 | memset(page_virt, 0, PAGE_CACHE_SIZE); | ||
326 | rc = ecryptfs_read_and_validate_xattr_region(page_virt, | 328 | rc = ecryptfs_read_and_validate_xattr_region(page_virt, |
327 | ecryptfs_dentry); | 329 | ecryptfs_dentry); |
328 | if (rc) { | 330 | if (rc) { |
@@ -335,7 +337,7 @@ int ecryptfs_lookup_and_interpose_lower(struct dentry *ecryptfs_dentry, | |||
335 | ecryptfs_dentry->d_sb)->mount_crypt_stat; | 337 | ecryptfs_dentry->d_sb)->mount_crypt_stat; |
336 | if (mount_crypt_stat->flags & ECRYPTFS_ENCRYPTED_VIEW_ENABLED) { | 338 | if (mount_crypt_stat->flags & ECRYPTFS_ENCRYPTED_VIEW_ENABLED) { |
337 | if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR) | 339 | if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR) |
338 | file_size = (crypt_stat->num_header_bytes_at_front | 340 | file_size = (crypt_stat->metadata_size |
339 | + i_size_read(lower_dentry->d_inode)); | 341 | + i_size_read(lower_dentry->d_inode)); |
340 | else | 342 | else |
341 | file_size = i_size_read(lower_dentry->d_inode); | 343 | file_size = i_size_read(lower_dentry->d_inode); |
@@ -387,9 +389,9 @@ static struct dentry *ecryptfs_lookup(struct inode *ecryptfs_dir_inode, | |||
387 | mutex_unlock(&lower_dir_dentry->d_inode->i_mutex); | 389 | mutex_unlock(&lower_dir_dentry->d_inode->i_mutex); |
388 | if (IS_ERR(lower_dentry)) { | 390 | if (IS_ERR(lower_dentry)) { |
389 | rc = PTR_ERR(lower_dentry); | 391 | rc = PTR_ERR(lower_dentry); |
390 | printk(KERN_ERR "%s: lookup_one_len() returned [%d] on " | 392 | ecryptfs_printk(KERN_DEBUG, "%s: lookup_one_len() returned " |
391 | "lower_dentry = [%s]\n", __func__, rc, | 393 | "[%d] on lower_dentry = [%s]\n", __func__, rc, |
392 | ecryptfs_dentry->d_name.name); | 394 | encrypted_and_encoded_name); |
393 | goto out_d_drop; | 395 | goto out_d_drop; |
394 | } | 396 | } |
395 | if (lower_dentry->d_inode) | 397 | if (lower_dentry->d_inode) |
@@ -416,9 +418,9 @@ static struct dentry *ecryptfs_lookup(struct inode *ecryptfs_dir_inode, | |||
416 | mutex_unlock(&lower_dir_dentry->d_inode->i_mutex); | 418 | mutex_unlock(&lower_dir_dentry->d_inode->i_mutex); |
417 | if (IS_ERR(lower_dentry)) { | 419 | if (IS_ERR(lower_dentry)) { |
418 | rc = PTR_ERR(lower_dentry); | 420 | rc = PTR_ERR(lower_dentry); |
419 | printk(KERN_ERR "%s: lookup_one_len() returned [%d] on " | 421 | ecryptfs_printk(KERN_DEBUG, "%s: lookup_one_len() returned " |
420 | "lower_dentry = [%s]\n", __func__, rc, | 422 | "[%d] on lower_dentry = [%s]\n", __func__, rc, |
421 | encrypted_and_encoded_name); | 423 | encrypted_and_encoded_name); |
422 | goto out_d_drop; | 424 | goto out_d_drop; |
423 | } | 425 | } |
424 | lookup_and_interpose: | 426 | lookup_and_interpose: |
@@ -455,8 +457,8 @@ static int ecryptfs_link(struct dentry *old_dentry, struct inode *dir, | |||
455 | 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); |
456 | if (rc) | 458 | if (rc) |
457 | goto out_lock; | 459 | goto out_lock; |
458 | fsstack_copy_attr_times(dir, lower_new_dentry->d_inode); | 460 | fsstack_copy_attr_times(dir, lower_dir_dentry->d_inode); |
459 | fsstack_copy_inode_size(dir, lower_new_dentry->d_inode); | 461 | fsstack_copy_inode_size(dir, lower_dir_dentry->d_inode); |
460 | old_dentry->d_inode->i_nlink = | 462 | old_dentry->d_inode->i_nlink = |
461 | ecryptfs_inode_to_lower(old_dentry->d_inode)->i_nlink; | 463 | ecryptfs_inode_to_lower(old_dentry->d_inode)->i_nlink; |
462 | i_size_write(new_dentry->d_inode, file_size_save); | 464 | i_size_write(new_dentry->d_inode, file_size_save); |
@@ -647,38 +649,17 @@ out_lock: | |||
647 | return rc; | 649 | return rc; |
648 | } | 650 | } |
649 | 651 | ||
650 | static int | 652 | static int ecryptfs_readlink_lower(struct dentry *dentry, char **buf, |
651 | ecryptfs_readlink(struct dentry *dentry, char __user *buf, int bufsiz) | 653 | size_t *bufsiz) |
652 | { | 654 | { |
655 | struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry); | ||
653 | char *lower_buf; | 656 | char *lower_buf; |
654 | size_t lower_bufsiz; | 657 | size_t lower_bufsiz = PATH_MAX; |
655 | struct dentry *lower_dentry; | ||
656 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat; | ||
657 | char *plaintext_name; | ||
658 | size_t plaintext_name_size; | ||
659 | mm_segment_t old_fs; | 658 | mm_segment_t old_fs; |
660 | int rc; | 659 | int rc; |
661 | 660 | ||
662 | lower_dentry = ecryptfs_dentry_to_lower(dentry); | ||
663 | if (!lower_dentry->d_inode->i_op->readlink) { | ||
664 | rc = -EINVAL; | ||
665 | goto out; | ||
666 | } | ||
667 | mount_crypt_stat = &ecryptfs_superblock_to_private( | ||
668 | dentry->d_sb)->mount_crypt_stat; | ||
669 | /* | ||
670 | * If the lower filename is encrypted, it will result in a significantly | ||
671 | * longer name. If needed, truncate the name after decode and decrypt. | ||
672 | */ | ||
673 | if (mount_crypt_stat->flags & ECRYPTFS_GLOBAL_ENCRYPT_FILENAMES) | ||
674 | lower_bufsiz = PATH_MAX; | ||
675 | else | ||
676 | lower_bufsiz = bufsiz; | ||
677 | /* Released in this function */ | ||
678 | lower_buf = kmalloc(lower_bufsiz, GFP_KERNEL); | 661 | lower_buf = kmalloc(lower_bufsiz, GFP_KERNEL); |
679 | if (lower_buf == NULL) { | 662 | if (!lower_buf) { |
680 | printk(KERN_ERR "%s: Out of memory whilst attempting to " | ||
681 | "kmalloc [%zd] bytes\n", __func__, lower_bufsiz); | ||
682 | rc = -ENOMEM; | 663 | rc = -ENOMEM; |
683 | goto out; | 664 | goto out; |
684 | } | 665 | } |
@@ -688,29 +669,31 @@ ecryptfs_readlink(struct dentry *dentry, char __user *buf, int bufsiz) | |||
688 | (char __user *)lower_buf, | 669 | (char __user *)lower_buf, |
689 | lower_bufsiz); | 670 | lower_bufsiz); |
690 | set_fs(old_fs); | 671 | set_fs(old_fs); |
691 | if (rc >= 0) { | 672 | if (rc < 0) |
692 | rc = ecryptfs_decode_and_decrypt_filename(&plaintext_name, | 673 | goto out; |
693 | &plaintext_name_size, | 674 | lower_bufsiz = rc; |
694 | dentry, lower_buf, | 675 | rc = ecryptfs_decode_and_decrypt_filename(buf, bufsiz, dentry, |
695 | rc); | 676 | lower_buf, lower_bufsiz); |
696 | if (rc) { | 677 | out: |
697 | printk(KERN_ERR "%s: Error attempting to decode and " | ||
698 | "decrypt filename; rc = [%d]\n", __func__, | ||
699 | rc); | ||
700 | goto out_free_lower_buf; | ||
701 | } | ||
702 | /* Check for bufsiz <= 0 done in sys_readlinkat() */ | ||
703 | rc = copy_to_user(buf, plaintext_name, | ||
704 | min((size_t) bufsiz, plaintext_name_size)); | ||
705 | if (rc) | ||
706 | rc = -EFAULT; | ||
707 | else | ||
708 | rc = plaintext_name_size; | ||
709 | kfree(plaintext_name); | ||
710 | fsstack_copy_attr_atime(dentry->d_inode, lower_dentry->d_inode); | ||
711 | } | ||
712 | out_free_lower_buf: | ||
713 | 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); | ||
714 | out: | 697 | out: |
715 | return rc; | 698 | return rc; |
716 | } | 699 | } |
@@ -768,7 +751,7 @@ upper_size_to_lower_size(struct ecryptfs_crypt_stat *crypt_stat, | |||
768 | { | 751 | { |
769 | loff_t lower_size; | 752 | loff_t lower_size; |
770 | 753 | ||
771 | lower_size = crypt_stat->num_header_bytes_at_front; | 754 | lower_size = ecryptfs_lower_header_size(crypt_stat); |
772 | if (upper_size != 0) { | 755 | if (upper_size != 0) { |
773 | loff_t num_extents; | 756 | loff_t num_extents; |
774 | 757 | ||
@@ -1015,6 +998,28 @@ out: | |||
1015 | return rc; | 998 | return rc; |
1016 | } | 999 | } |
1017 | 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 | |||
1018 | int ecryptfs_getattr(struct vfsmount *mnt, struct dentry *dentry, | 1023 | int ecryptfs_getattr(struct vfsmount *mnt, struct dentry *dentry, |
1019 | struct kstat *stat) | 1024 | struct kstat *stat) |
1020 | { | 1025 | { |
@@ -1039,7 +1044,7 @@ ecryptfs_setxattr(struct dentry *dentry, const char *name, const void *value, | |||
1039 | 1044 | ||
1040 | lower_dentry = ecryptfs_dentry_to_lower(dentry); | 1045 | lower_dentry = ecryptfs_dentry_to_lower(dentry); |
1041 | if (!lower_dentry->d_inode->i_op->setxattr) { | 1046 | if (!lower_dentry->d_inode->i_op->setxattr) { |
1042 | rc = -ENOSYS; | 1047 | rc = -EOPNOTSUPP; |
1043 | goto out; | 1048 | goto out; |
1044 | } | 1049 | } |
1045 | mutex_lock(&lower_dentry->d_inode->i_mutex); | 1050 | mutex_lock(&lower_dentry->d_inode->i_mutex); |
@@ -1057,7 +1062,7 @@ ecryptfs_getxattr_lower(struct dentry *lower_dentry, const char *name, | |||
1057 | int rc = 0; | 1062 | int rc = 0; |
1058 | 1063 | ||
1059 | if (!lower_dentry->d_inode->i_op->getxattr) { | 1064 | if (!lower_dentry->d_inode->i_op->getxattr) { |
1060 | rc = -ENOSYS; | 1065 | rc = -EOPNOTSUPP; |
1061 | goto out; | 1066 | goto out; |
1062 | } | 1067 | } |
1063 | mutex_lock(&lower_dentry->d_inode->i_mutex); | 1068 | mutex_lock(&lower_dentry->d_inode->i_mutex); |
@@ -1084,7 +1089,7 @@ ecryptfs_listxattr(struct dentry *dentry, char *list, size_t size) | |||
1084 | 1089 | ||
1085 | lower_dentry = ecryptfs_dentry_to_lower(dentry); | 1090 | lower_dentry = ecryptfs_dentry_to_lower(dentry); |
1086 | if (!lower_dentry->d_inode->i_op->listxattr) { | 1091 | if (!lower_dentry->d_inode->i_op->listxattr) { |
1087 | rc = -ENOSYS; | 1092 | rc = -EOPNOTSUPP; |
1088 | goto out; | 1093 | goto out; |
1089 | } | 1094 | } |
1090 | mutex_lock(&lower_dentry->d_inode->i_mutex); | 1095 | mutex_lock(&lower_dentry->d_inode->i_mutex); |
@@ -1101,7 +1106,7 @@ static int ecryptfs_removexattr(struct dentry *dentry, const char *name) | |||
1101 | 1106 | ||
1102 | lower_dentry = ecryptfs_dentry_to_lower(dentry); | 1107 | lower_dentry = ecryptfs_dentry_to_lower(dentry); |
1103 | if (!lower_dentry->d_inode->i_op->removexattr) { | 1108 | if (!lower_dentry->d_inode->i_op->removexattr) { |
1104 | rc = -ENOSYS; | 1109 | rc = -EOPNOTSUPP; |
1105 | goto out; | 1110 | goto out; |
1106 | } | 1111 | } |
1107 | mutex_lock(&lower_dentry->d_inode->i_mutex); | 1112 | mutex_lock(&lower_dentry->d_inode->i_mutex); |
@@ -1132,6 +1137,7 @@ const struct inode_operations ecryptfs_symlink_iops = { | |||
1132 | .put_link = ecryptfs_put_link, | 1137 | .put_link = ecryptfs_put_link, |
1133 | .permission = ecryptfs_permission, | 1138 | .permission = ecryptfs_permission, |
1134 | .setattr = ecryptfs_setattr, | 1139 | .setattr = ecryptfs_setattr, |
1140 | .getattr = ecryptfs_getattr_link, | ||
1135 | .setxattr = ecryptfs_setxattr, | 1141 | .setxattr = ecryptfs_setxattr, |
1136 | .getxattr = ecryptfs_getxattr, | 1142 | .getxattr = ecryptfs_getxattr, |
1137 | .listxattr = ecryptfs_listxattr, | 1143 | .listxattr = ecryptfs_listxattr, |