aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ecryptfs/inode.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ecryptfs/inode.c')
-rw-r--r--fs/ecryptfs/inode.c24
1 files changed, 18 insertions, 6 deletions
diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c
index d8325263ba6e..93bc0f8174a7 100644
--- a/fs/ecryptfs/inode.c
+++ b/fs/ecryptfs/inode.c
@@ -640,8 +640,9 @@ static int
640ecryptfs_readlink(struct dentry *dentry, char __user *buf, int bufsiz) 640ecryptfs_readlink(struct dentry *dentry, char __user *buf, int bufsiz)
641{ 641{
642 char *lower_buf; 642 char *lower_buf;
643 size_t lower_bufsiz;
643 struct dentry *lower_dentry; 644 struct dentry *lower_dentry;
644 struct ecryptfs_crypt_stat *crypt_stat; 645 struct ecryptfs_mount_crypt_stat *mount_crypt_stat;
645 char *plaintext_name; 646 char *plaintext_name;
646 size_t plaintext_name_size; 647 size_t plaintext_name_size;
647 mm_segment_t old_fs; 648 mm_segment_t old_fs;
@@ -652,12 +653,21 @@ ecryptfs_readlink(struct dentry *dentry, char __user *buf, int bufsiz)
652 rc = -EINVAL; 653 rc = -EINVAL;
653 goto out; 654 goto out;
654 } 655 }
655 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;
656 /* Released in this function */ 666 /* Released in this function */
657 lower_buf = kmalloc(bufsiz, GFP_KERNEL); 667 lower_buf = kmalloc(lower_bufsiz, GFP_KERNEL);
658 if (lower_buf == NULL) { 668 if (lower_buf == NULL) {
659 printk(KERN_ERR "%s: Out of memory whilst attempting to " 669 printk(KERN_ERR "%s: Out of memory whilst attempting to "
660 "kmalloc [%d] bytes\n", __func__, bufsiz); 670 "kmalloc [%d] bytes\n", __func__, lower_bufsiz);
661 rc = -ENOMEM; 671 rc = -ENOMEM;
662 goto out; 672 goto out;
663 } 673 }
@@ -665,7 +675,7 @@ ecryptfs_readlink(struct dentry *dentry, char __user *buf, int bufsiz)
665 set_fs(get_ds()); 675 set_fs(get_ds());
666 rc = lower_dentry->d_inode->i_op->readlink(lower_dentry, 676 rc = lower_dentry->d_inode->i_op->readlink(lower_dentry,
667 (char __user *)lower_buf, 677 (char __user *)lower_buf,
668 bufsiz); 678 lower_bufsiz);
669 set_fs(old_fs); 679 set_fs(old_fs);
670 if (rc >= 0) { 680 if (rc >= 0) {
671 rc = ecryptfs_decode_and_decrypt_filename(&plaintext_name, 681 rc = ecryptfs_decode_and_decrypt_filename(&plaintext_name,
@@ -678,7 +688,9 @@ ecryptfs_readlink(struct dentry *dentry, char __user *buf, int bufsiz)
678 rc); 688 rc);
679 goto out_free_lower_buf; 689 goto out_free_lower_buf;
680 } 690 }
681 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((unsigned) bufsiz, plaintext_name_size));
682 if (rc) 694 if (rc)
683 rc = -EFAULT; 695 rc = -EFAULT;
684 else 696 else