diff options
Diffstat (limited to 'fs/ecryptfs/inode.c')
-rw-r--r-- | fs/ecryptfs/inode.c | 37 |
1 files changed, 29 insertions, 8 deletions
diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c index 55b3145b8072..2f0945d63297 100644 --- a/fs/ecryptfs/inode.c +++ b/fs/ecryptfs/inode.c | |||
@@ -379,9 +379,11 @@ static struct dentry *ecryptfs_lookup(struct inode *ecryptfs_dir_inode, | |||
379 | goto out_d_drop; | 379 | goto out_d_drop; |
380 | } | 380 | } |
381 | lower_dir_dentry = ecryptfs_dentry_to_lower(ecryptfs_dentry->d_parent); | 381 | lower_dir_dentry = ecryptfs_dentry_to_lower(ecryptfs_dentry->d_parent); |
382 | mutex_lock(&lower_dir_dentry->d_inode->i_mutex); | ||
382 | lower_dentry = lookup_one_len(ecryptfs_dentry->d_name.name, | 383 | lower_dentry = lookup_one_len(ecryptfs_dentry->d_name.name, |
383 | lower_dir_dentry, | 384 | lower_dir_dentry, |
384 | ecryptfs_dentry->d_name.len); | 385 | ecryptfs_dentry->d_name.len); |
386 | mutex_unlock(&lower_dir_dentry->d_inode->i_mutex); | ||
385 | if (IS_ERR(lower_dentry)) { | 387 | if (IS_ERR(lower_dentry)) { |
386 | rc = PTR_ERR(lower_dentry); | 388 | rc = PTR_ERR(lower_dentry); |
387 | printk(KERN_ERR "%s: lookup_one_len() returned [%d] on " | 389 | printk(KERN_ERR "%s: lookup_one_len() returned [%d] on " |
@@ -406,9 +408,11 @@ static struct dentry *ecryptfs_lookup(struct inode *ecryptfs_dir_inode, | |||
406 | "filename; rc = [%d]\n", __func__, rc); | 408 | "filename; rc = [%d]\n", __func__, rc); |
407 | goto out_d_drop; | 409 | goto out_d_drop; |
408 | } | 410 | } |
411 | mutex_lock(&lower_dir_dentry->d_inode->i_mutex); | ||
409 | lower_dentry = lookup_one_len(encrypted_and_encoded_name, | 412 | lower_dentry = lookup_one_len(encrypted_and_encoded_name, |
410 | lower_dir_dentry, | 413 | lower_dir_dentry, |
411 | encrypted_and_encoded_name_size - 1); | 414 | encrypted_and_encoded_name_size - 1); |
415 | mutex_unlock(&lower_dir_dentry->d_inode->i_mutex); | ||
412 | if (IS_ERR(lower_dentry)) { | 416 | if (IS_ERR(lower_dentry)) { |
413 | rc = PTR_ERR(lower_dentry); | 417 | rc = PTR_ERR(lower_dentry); |
414 | printk(KERN_ERR "%s: lookup_one_len() returned [%d] on " | 418 | printk(KERN_ERR "%s: lookup_one_len() returned [%d] on " |
@@ -636,8 +640,9 @@ static int | |||
636 | ecryptfs_readlink(struct dentry *dentry, char __user *buf, int bufsiz) | 640 | ecryptfs_readlink(struct dentry *dentry, char __user *buf, int bufsiz) |
637 | { | 641 | { |
638 | char *lower_buf; | 642 | char *lower_buf; |
643 | size_t lower_bufsiz; | ||
639 | struct dentry *lower_dentry; | 644 | struct dentry *lower_dentry; |
640 | struct ecryptfs_crypt_stat *crypt_stat; | 645 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat; |
641 | char *plaintext_name; | 646 | char *plaintext_name; |
642 | size_t plaintext_name_size; | 647 | size_t plaintext_name_size; |
643 | mm_segment_t old_fs; | 648 | mm_segment_t old_fs; |
@@ -648,12 +653,21 @@ ecryptfs_readlink(struct dentry *dentry, char __user *buf, int bufsiz) | |||
648 | rc = -EINVAL; | 653 | rc = -EINVAL; |
649 | goto out; | 654 | goto out; |
650 | } | 655 | } |
651 | crypt_stat = &ecryptfs_inode_to_private(dentry->d_inode)->crypt_stat; | 656 | mount_crypt_stat = &ecryptfs_superblock_to_private( |
657 | dentry->d_sb)->mount_crypt_stat; | ||
658 | /* | ||
659 | * If the lower filename is encrypted, it will result in a significantly | ||
660 | * longer name. If needed, truncate the name after decode and decrypt. | ||
661 | */ | ||
662 | if (mount_crypt_stat->flags & ECRYPTFS_GLOBAL_ENCRYPT_FILENAMES) | ||
663 | lower_bufsiz = PATH_MAX; | ||
664 | else | ||
665 | lower_bufsiz = bufsiz; | ||
652 | /* Released in this function */ | 666 | /* Released in this function */ |
653 | lower_buf = kmalloc(bufsiz, GFP_KERNEL); | 667 | lower_buf = kmalloc(lower_bufsiz, GFP_KERNEL); |
654 | if (lower_buf == NULL) { | 668 | if (lower_buf == NULL) { |
655 | printk(KERN_ERR "%s: Out of memory whilst attempting to " | 669 | printk(KERN_ERR "%s: Out of memory whilst attempting to " |
656 | "kmalloc [%d] bytes\n", __func__, bufsiz); | 670 | "kmalloc [%zd] bytes\n", __func__, lower_bufsiz); |
657 | rc = -ENOMEM; | 671 | rc = -ENOMEM; |
658 | goto out; | 672 | goto out; |
659 | } | 673 | } |
@@ -661,7 +675,7 @@ ecryptfs_readlink(struct dentry *dentry, char __user *buf, int bufsiz) | |||
661 | set_fs(get_ds()); | 675 | set_fs(get_ds()); |
662 | rc = lower_dentry->d_inode->i_op->readlink(lower_dentry, | 676 | rc = lower_dentry->d_inode->i_op->readlink(lower_dentry, |
663 | (char __user *)lower_buf, | 677 | (char __user *)lower_buf, |
664 | bufsiz); | 678 | lower_bufsiz); |
665 | set_fs(old_fs); | 679 | set_fs(old_fs); |
666 | if (rc >= 0) { | 680 | if (rc >= 0) { |
667 | rc = ecryptfs_decode_and_decrypt_filename(&plaintext_name, | 681 | rc = ecryptfs_decode_and_decrypt_filename(&plaintext_name, |
@@ -674,7 +688,9 @@ ecryptfs_readlink(struct dentry *dentry, char __user *buf, int bufsiz) | |||
674 | rc); | 688 | rc); |
675 | goto out_free_lower_buf; | 689 | goto out_free_lower_buf; |
676 | } | 690 | } |
677 | rc = copy_to_user(buf, plaintext_name, plaintext_name_size); | 691 | /* Check for bufsiz <= 0 done in sys_readlinkat() */ |
692 | rc = copy_to_user(buf, plaintext_name, | ||
693 | min((size_t) bufsiz, plaintext_name_size)); | ||
678 | if (rc) | 694 | if (rc) |
679 | rc = -EFAULT; | 695 | rc = -EFAULT; |
680 | else | 696 | else |
@@ -814,6 +830,13 @@ int ecryptfs_truncate(struct dentry *dentry, loff_t new_length) | |||
814 | size_t num_zeros = (PAGE_CACHE_SIZE | 830 | size_t num_zeros = (PAGE_CACHE_SIZE |
815 | - (new_length & ~PAGE_CACHE_MASK)); | 831 | - (new_length & ~PAGE_CACHE_MASK)); |
816 | 832 | ||
833 | if (!(crypt_stat->flags & ECRYPTFS_ENCRYPTED)) { | ||
834 | rc = vmtruncate(inode, new_length); | ||
835 | if (rc) | ||
836 | goto out_free; | ||
837 | rc = vmtruncate(lower_dentry->d_inode, new_length); | ||
838 | goto out_free; | ||
839 | } | ||
817 | if (num_zeros) { | 840 | if (num_zeros) { |
818 | char *zeros_virt; | 841 | char *zeros_virt; |
819 | 842 | ||
@@ -915,8 +938,6 @@ static int ecryptfs_setattr(struct dentry *dentry, struct iattr *ia) | |||
915 | } | 938 | } |
916 | rc = 0; | 939 | rc = 0; |
917 | crypt_stat->flags &= ~(ECRYPTFS_ENCRYPTED); | 940 | crypt_stat->flags &= ~(ECRYPTFS_ENCRYPTED); |
918 | mutex_unlock(&crypt_stat->cs_mutex); | ||
919 | goto out; | ||
920 | } | 941 | } |
921 | } | 942 | } |
922 | mutex_unlock(&crypt_stat->cs_mutex); | 943 | mutex_unlock(&crypt_stat->cs_mutex); |