diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/block_dev.c | 56 | ||||
-rw-r--r-- | fs/cifs/CHANGES | 5 | ||||
-rw-r--r-- | fs/cifs/connect.c | 7 | ||||
-rw-r--r-- | fs/cifs/file.c | 23 | ||||
-rw-r--r-- | fs/cifs/inode.c | 14 | ||||
-rw-r--r-- | fs/cifs/readdir.c | 9 | ||||
-rw-r--r-- | fs/compat.c | 20 | ||||
-rw-r--r-- | fs/ecryptfs/crypto.c | 206 | ||||
-rw-r--r-- | fs/ecryptfs/dentry.c | 8 | ||||
-rw-r--r-- | fs/ecryptfs/ecryptfs_kernel.h | 22 | ||||
-rw-r--r-- | fs/ecryptfs/file.c | 44 | ||||
-rw-r--r-- | fs/ecryptfs/inode.c | 95 | ||||
-rw-r--r-- | fs/ecryptfs/keystore.c | 114 | ||||
-rw-r--r-- | fs/ecryptfs/main.c | 15 | ||||
-rw-r--r-- | fs/ecryptfs/super.c | 18 | ||||
-rw-r--r-- | fs/fuse/file.c | 9 | ||||
-rw-r--r-- | fs/gfs2/ops_address.c | 7 | ||||
-rw-r--r-- | fs/nfsd/nfs4recover.c | 2 | ||||
-rw-r--r-- | fs/reiserfs/super.c | 1 | ||||
-rw-r--r-- | fs/xattr.c | 13 |
20 files changed, 375 insertions, 313 deletions
diff --git a/fs/block_dev.c b/fs/block_dev.c index 702b88cbd91d..36c0e7af9d0f 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c | |||
@@ -642,34 +642,47 @@ static void free_bd_holder(struct bd_holder *bo) | |||
642 | } | 642 | } |
643 | 643 | ||
644 | /** | 644 | /** |
645 | * find_bd_holder - find matching struct bd_holder from the block device | ||
646 | * | ||
647 | * @bdev: struct block device to be searched | ||
648 | * @bo: target struct bd_holder | ||
649 | * | ||
650 | * Returns matching entry with @bo in @bdev->bd_holder_list. | ||
651 | * If found, increment the reference count and return the pointer. | ||
652 | * If not found, returns NULL. | ||
653 | */ | ||
654 | static struct bd_holder *find_bd_holder(struct block_device *bdev, | ||
655 | struct bd_holder *bo) | ||
656 | { | ||
657 | struct bd_holder *tmp; | ||
658 | |||
659 | list_for_each_entry(tmp, &bdev->bd_holder_list, list) | ||
660 | if (tmp->sdir == bo->sdir) { | ||
661 | tmp->count++; | ||
662 | return tmp; | ||
663 | } | ||
664 | |||
665 | return NULL; | ||
666 | } | ||
667 | |||
668 | /** | ||
645 | * add_bd_holder - create sysfs symlinks for bd_claim() relationship | 669 | * add_bd_holder - create sysfs symlinks for bd_claim() relationship |
646 | * | 670 | * |
647 | * @bdev: block device to be bd_claimed | 671 | * @bdev: block device to be bd_claimed |
648 | * @bo: preallocated and initialized by alloc_bd_holder() | 672 | * @bo: preallocated and initialized by alloc_bd_holder() |
649 | * | 673 | * |
650 | * If there is no matching entry with @bo in @bdev->bd_holder_list, | 674 | * Add @bo to @bdev->bd_holder_list, create symlinks. |
651 | * add @bo to the list, create symlinks. | ||
652 | * | 675 | * |
653 | * Returns 0 if symlinks are created or already there. | 676 | * Returns 0 if symlinks are created. |
654 | * Returns -ve if something fails and @bo can be freed. | 677 | * Returns -ve if something fails. |
655 | */ | 678 | */ |
656 | static int add_bd_holder(struct block_device *bdev, struct bd_holder *bo) | 679 | static int add_bd_holder(struct block_device *bdev, struct bd_holder *bo) |
657 | { | 680 | { |
658 | struct bd_holder *tmp; | ||
659 | int ret; | 681 | int ret; |
660 | 682 | ||
661 | if (!bo) | 683 | if (!bo) |
662 | return -EINVAL; | 684 | return -EINVAL; |
663 | 685 | ||
664 | list_for_each_entry(tmp, &bdev->bd_holder_list, list) { | ||
665 | if (tmp->sdir == bo->sdir) { | ||
666 | tmp->count++; | ||
667 | /* We've already done what we need to do here. */ | ||
668 | free_bd_holder(bo); | ||
669 | return 0; | ||
670 | } | ||
671 | } | ||
672 | |||
673 | if (!bd_holder_grab_dirs(bdev, bo)) | 686 | if (!bd_holder_grab_dirs(bdev, bo)) |
674 | return -EBUSY; | 687 | return -EBUSY; |
675 | 688 | ||
@@ -740,7 +753,7 @@ static int bd_claim_by_kobject(struct block_device *bdev, void *holder, | |||
740 | struct kobject *kobj) | 753 | struct kobject *kobj) |
741 | { | 754 | { |
742 | int res; | 755 | int res; |
743 | struct bd_holder *bo; | 756 | struct bd_holder *bo, *found; |
744 | 757 | ||
745 | if (!kobj) | 758 | if (!kobj) |
746 | return -EINVAL; | 759 | return -EINVAL; |
@@ -751,9 +764,16 @@ static int bd_claim_by_kobject(struct block_device *bdev, void *holder, | |||
751 | 764 | ||
752 | mutex_lock_nested(&bdev->bd_mutex, BD_MUTEX_PARTITION); | 765 | mutex_lock_nested(&bdev->bd_mutex, BD_MUTEX_PARTITION); |
753 | res = bd_claim(bdev, holder); | 766 | res = bd_claim(bdev, holder); |
754 | if (res == 0) | 767 | if (res == 0) { |
755 | res = add_bd_holder(bdev, bo); | 768 | found = find_bd_holder(bdev, bo); |
756 | if (res) | 769 | if (found == NULL) { |
770 | res = add_bd_holder(bdev, bo); | ||
771 | if (res) | ||
772 | bd_release(bdev); | ||
773 | } | ||
774 | } | ||
775 | |||
776 | if (res || found) | ||
757 | free_bd_holder(bo); | 777 | free_bd_holder(bo); |
758 | mutex_unlock(&bdev->bd_mutex); | 778 | mutex_unlock(&bdev->bd_mutex); |
759 | 779 | ||
diff --git a/fs/cifs/CHANGES b/fs/cifs/CHANGES index 1eb9a2ec0a3b..0b3c37ef52e0 100644 --- a/fs/cifs/CHANGES +++ b/fs/cifs/CHANGES | |||
@@ -1,6 +1,11 @@ | |||
1 | Version 1.46 | 1 | Version 1.46 |
2 | ------------ | 2 | ------------ |
3 | Support deep tree mounts. Better support OS/2, Win9x (DOS) time stamps. | 3 | Support deep tree mounts. Better support OS/2, Win9x (DOS) time stamps. |
4 | Allow null user to be specified on mount ("username="). Do not return | ||
5 | EINVAL on readdir when filldir fails due to overwritten blocksize | ||
6 | (fixes FC problem). Return error in rename 2nd attempt retry (ie report | ||
7 | if rename by handle also fails, after rename by path fails, we were | ||
8 | not reporting whether the retry worked or not). | ||
4 | 9 | ||
5 | Version 1.45 | 10 | Version 1.45 |
6 | ------------ | 11 | ------------ |
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 4093d5332930..71f77914ce93 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c | |||
@@ -822,10 +822,13 @@ cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol) | |||
822 | } else if (strnicmp(data, "nouser_xattr",12) == 0) { | 822 | } else if (strnicmp(data, "nouser_xattr",12) == 0) { |
823 | vol->no_xattr = 1; | 823 | vol->no_xattr = 1; |
824 | } else if (strnicmp(data, "user", 4) == 0) { | 824 | } else if (strnicmp(data, "user", 4) == 0) { |
825 | if (!value || !*value) { | 825 | if (!value) { |
826 | printk(KERN_WARNING | 826 | printk(KERN_WARNING |
827 | "CIFS: invalid or missing username\n"); | 827 | "CIFS: invalid or missing username\n"); |
828 | return 1; /* needs_arg; */ | 828 | return 1; /* needs_arg; */ |
829 | } else if(!*value) { | ||
830 | /* null user, ie anonymous, authentication */ | ||
831 | vol->nullauth = 1; | ||
829 | } | 832 | } |
830 | if (strnlen(value, 200) < 200) { | 833 | if (strnlen(value, 200) < 200) { |
831 | vol->username = value; | 834 | vol->username = value; |
@@ -1642,6 +1645,8 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, | |||
1642 | /* BB fixme parse for domain name here */ | 1645 | /* BB fixme parse for domain name here */ |
1643 | cFYI(1, ("Username: %s ", volume_info.username)); | 1646 | cFYI(1, ("Username: %s ", volume_info.username)); |
1644 | 1647 | ||
1648 | } else if (volume_info.nullauth) { | ||
1649 | cFYI(1,("null user")); | ||
1645 | } else { | 1650 | } else { |
1646 | cifserror("No username specified"); | 1651 | cifserror("No username specified"); |
1647 | /* In userspace mount helper we can get user name from alternate | 1652 | /* In userspace mount helper we can get user name from alternate |
diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 976a691c5a68..7e056b9b49e8 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c | |||
@@ -1806,13 +1806,6 @@ static int cifs_readpages(struct file *file, struct address_space *mapping, | |||
1806 | } | 1806 | } |
1807 | if ((rc < 0) || (smb_read_data == NULL)) { | 1807 | if ((rc < 0) || (smb_read_data == NULL)) { |
1808 | cFYI(1, ("Read error in readpages: %d", rc)); | 1808 | cFYI(1, ("Read error in readpages: %d", rc)); |
1809 | /* clean up remaing pages off list */ | ||
1810 | while (!list_empty(page_list) && (i < num_pages)) { | ||
1811 | page = list_entry(page_list->prev, struct page, | ||
1812 | lru); | ||
1813 | list_del(&page->lru); | ||
1814 | page_cache_release(page); | ||
1815 | } | ||
1816 | break; | 1809 | break; |
1817 | } else if (bytes_read > 0) { | 1810 | } else if (bytes_read > 0) { |
1818 | pSMBr = (struct smb_com_read_rsp *)smb_read_data; | 1811 | pSMBr = (struct smb_com_read_rsp *)smb_read_data; |
@@ -1831,13 +1824,7 @@ static int cifs_readpages(struct file *file, struct address_space *mapping, | |||
1831 | this case is ok - if we are at server EOF | 1824 | this case is ok - if we are at server EOF |
1832 | we will hit it on next read */ | 1825 | we will hit it on next read */ |
1833 | 1826 | ||
1834 | /* while (!list_empty(page_list) && (i < num_pages)) { | 1827 | /* break; */ |
1835 | page = list_entry(page_list->prev, | ||
1836 | struct page, list); | ||
1837 | list_del(&page->list); | ||
1838 | page_cache_release(page); | ||
1839 | } | ||
1840 | break; */ | ||
1841 | } | 1828 | } |
1842 | } else { | 1829 | } else { |
1843 | cFYI(1, ("No bytes read (%d) at offset %lld . " | 1830 | cFYI(1, ("No bytes read (%d) at offset %lld . " |
@@ -1845,14 +1832,6 @@ static int cifs_readpages(struct file *file, struct address_space *mapping, | |||
1845 | bytes_read, offset)); | 1832 | bytes_read, offset)); |
1846 | /* BB turn off caching and do new lookup on | 1833 | /* BB turn off caching and do new lookup on |
1847 | file size at server? */ | 1834 | file size at server? */ |
1848 | while (!list_empty(page_list) && (i < num_pages)) { | ||
1849 | page = list_entry(page_list->prev, struct page, | ||
1850 | lru); | ||
1851 | list_del(&page->lru); | ||
1852 | |||
1853 | /* BB removeme - replace with zero of page? */ | ||
1854 | page_cache_release(page); | ||
1855 | } | ||
1856 | break; | 1835 | break; |
1857 | } | 1836 | } |
1858 | if (smb_read_data) { | 1837 | if (smb_read_data) { |
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index 35d54bb0869a..dffe295825f4 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c | |||
@@ -885,10 +885,14 @@ int cifs_rename(struct inode *source_inode, struct dentry *source_direntry, | |||
885 | kmalloc(2 * sizeof(FILE_UNIX_BASIC_INFO), GFP_KERNEL); | 885 | kmalloc(2 * sizeof(FILE_UNIX_BASIC_INFO), GFP_KERNEL); |
886 | if (info_buf_source != NULL) { | 886 | if (info_buf_source != NULL) { |
887 | info_buf_target = info_buf_source + 1; | 887 | info_buf_target = info_buf_source + 1; |
888 | rc = CIFSSMBUnixQPathInfo(xid, pTcon, fromName, | 888 | if (pTcon->ses->capabilities & CAP_UNIX) |
889 | info_buf_source, cifs_sb_source->local_nls, | 889 | rc = CIFSSMBUnixQPathInfo(xid, pTcon, fromName, |
890 | cifs_sb_source->mnt_cifs_flags & | 890 | info_buf_source, |
891 | CIFS_MOUNT_MAP_SPECIAL_CHR); | 891 | cifs_sb_source->local_nls, |
892 | cifs_sb_source->mnt_cifs_flags & | ||
893 | CIFS_MOUNT_MAP_SPECIAL_CHR); | ||
894 | /* else rc is still EEXIST so will fall through to | ||
895 | unlink the target and retry rename */ | ||
892 | if (rc == 0) { | 896 | if (rc == 0) { |
893 | rc = CIFSSMBUnixQPathInfo(xid, pTcon, toName, | 897 | rc = CIFSSMBUnixQPathInfo(xid, pTcon, toName, |
894 | info_buf_target, | 898 | info_buf_target, |
@@ -937,7 +941,7 @@ int cifs_rename(struct inode *source_inode, struct dentry *source_direntry, | |||
937 | cifs_sb_source->mnt_cifs_flags & | 941 | cifs_sb_source->mnt_cifs_flags & |
938 | CIFS_MOUNT_MAP_SPECIAL_CHR); | 942 | CIFS_MOUNT_MAP_SPECIAL_CHR); |
939 | if (rc==0) { | 943 | if (rc==0) { |
940 | CIFSSMBRenameOpenFile(xid, pTcon, netfid, toName, | 944 | rc = CIFSSMBRenameOpenFile(xid, pTcon, netfid, toName, |
941 | cifs_sb_source->local_nls, | 945 | cifs_sb_source->local_nls, |
942 | cifs_sb_source->mnt_cifs_flags & | 946 | cifs_sb_source->mnt_cifs_flags & |
943 | CIFS_MOUNT_MAP_SPECIAL_CHR); | 947 | CIFS_MOUNT_MAP_SPECIAL_CHR); |
diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c index b5b0a2a41bef..ed18c3965f7b 100644 --- a/fs/cifs/readdir.c +++ b/fs/cifs/readdir.c | |||
@@ -896,6 +896,10 @@ static int cifs_filldir(char *pfindEntry, struct file *file, | |||
896 | tmp_inode->i_ino,obj_type); | 896 | tmp_inode->i_ino,obj_type); |
897 | if(rc) { | 897 | if(rc) { |
898 | cFYI(1,("filldir rc = %d",rc)); | 898 | cFYI(1,("filldir rc = %d",rc)); |
899 | /* we can not return filldir errors to the caller | ||
900 | since they are "normal" when the stat blocksize | ||
901 | is too small - we return remapped error instead */ | ||
902 | rc = -EOVERFLOW; | ||
899 | } | 903 | } |
900 | 904 | ||
901 | dput(tmp_dentry); | 905 | dput(tmp_dentry); |
@@ -1074,6 +1078,11 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir) | |||
1074 | we want to check for that here? */ | 1078 | we want to check for that here? */ |
1075 | rc = cifs_filldir(current_entry, file, | 1079 | rc = cifs_filldir(current_entry, file, |
1076 | filldir, direntry, tmp_buf, max_len); | 1080 | filldir, direntry, tmp_buf, max_len); |
1081 | if(rc == -EOVERFLOW) { | ||
1082 | rc = 0; | ||
1083 | break; | ||
1084 | } | ||
1085 | |||
1077 | file->f_pos++; | 1086 | file->f_pos++; |
1078 | if(file->f_pos == | 1087 | if(file->f_pos == |
1079 | cifsFile->srch_inf.index_of_last_entry) { | 1088 | cifsFile->srch_inf.index_of_last_entry) { |
diff --git a/fs/compat.c b/fs/compat.c index 50624d4a70c6..8d0a0018a7d2 100644 --- a/fs/compat.c +++ b/fs/compat.c | |||
@@ -1835,9 +1835,12 @@ asmlinkage long compat_sys_pselect7(int n, compat_ulong_t __user *inp, | |||
1835 | 1835 | ||
1836 | } while (!ret && !timeout && tsp && (ts.tv_sec || ts.tv_nsec)); | 1836 | } while (!ret && !timeout && tsp && (ts.tv_sec || ts.tv_nsec)); |
1837 | 1837 | ||
1838 | if (ret == 0 && tsp && !(current->personality & STICKY_TIMEOUTS)) { | 1838 | if (tsp) { |
1839 | struct compat_timespec rts; | 1839 | struct compat_timespec rts; |
1840 | 1840 | ||
1841 | if (current->personality & STICKY_TIMEOUTS) | ||
1842 | goto sticky; | ||
1843 | |||
1841 | rts.tv_sec = timeout / HZ; | 1844 | rts.tv_sec = timeout / HZ; |
1842 | rts.tv_nsec = (timeout % HZ) * (NSEC_PER_SEC/HZ); | 1845 | rts.tv_nsec = (timeout % HZ) * (NSEC_PER_SEC/HZ); |
1843 | if (rts.tv_nsec >= NSEC_PER_SEC) { | 1846 | if (rts.tv_nsec >= NSEC_PER_SEC) { |
@@ -1846,8 +1849,19 @@ asmlinkage long compat_sys_pselect7(int n, compat_ulong_t __user *inp, | |||
1846 | } | 1849 | } |
1847 | if (compat_timespec_compare(&rts, &ts) >= 0) | 1850 | if (compat_timespec_compare(&rts, &ts) >= 0) |
1848 | rts = ts; | 1851 | rts = ts; |
1849 | if (copy_to_user(tsp, &rts, sizeof(rts))) | 1852 | if (copy_to_user(tsp, &rts, sizeof(rts))) { |
1850 | ret = -EFAULT; | 1853 | sticky: |
1854 | /* | ||
1855 | * If an application puts its timeval in read-only | ||
1856 | * memory, we don't want the Linux-specific update to | ||
1857 | * the timeval to cause a fault after the select has | ||
1858 | * completed successfully. However, because we're not | ||
1859 | * updating the timeval, we can't restart the system | ||
1860 | * call. | ||
1861 | */ | ||
1862 | if (ret == -ERESTARTNOHAND) | ||
1863 | ret = -EINTR; | ||
1864 | } | ||
1851 | } | 1865 | } |
1852 | 1866 | ||
1853 | if (ret == -ERESTARTNOHAND) { | 1867 | if (ret == -ERESTARTNOHAND) { |
diff --git a/fs/ecryptfs/crypto.c b/fs/ecryptfs/crypto.c index ed35a9712fa1..136175a69332 100644 --- a/fs/ecryptfs/crypto.c +++ b/fs/ecryptfs/crypto.c | |||
@@ -94,25 +94,53 @@ static int ecryptfs_calculate_md5(char *dst, | |||
94 | struct ecryptfs_crypt_stat *crypt_stat, | 94 | struct ecryptfs_crypt_stat *crypt_stat, |
95 | char *src, int len) | 95 | char *src, int len) |
96 | { | 96 | { |
97 | int rc = 0; | ||
98 | struct scatterlist sg; | 97 | struct scatterlist sg; |
98 | struct hash_desc desc = { | ||
99 | .tfm = crypt_stat->hash_tfm, | ||
100 | .flags = CRYPTO_TFM_REQ_MAY_SLEEP | ||
101 | }; | ||
102 | int rc = 0; | ||
99 | 103 | ||
100 | mutex_lock(&crypt_stat->cs_md5_tfm_mutex); | 104 | mutex_lock(&crypt_stat->cs_hash_tfm_mutex); |
101 | sg_init_one(&sg, (u8 *)src, len); | 105 | sg_init_one(&sg, (u8 *)src, len); |
102 | if (!crypt_stat->md5_tfm) { | 106 | if (!desc.tfm) { |
103 | crypt_stat->md5_tfm = | 107 | desc.tfm = crypto_alloc_hash(ECRYPTFS_DEFAULT_HASH, 0, |
104 | crypto_alloc_tfm("md5", CRYPTO_TFM_REQ_MAY_SLEEP); | 108 | CRYPTO_ALG_ASYNC); |
105 | if (!crypt_stat->md5_tfm) { | 109 | if (IS_ERR(desc.tfm)) { |
106 | rc = -ENOMEM; | 110 | rc = PTR_ERR(desc.tfm); |
107 | ecryptfs_printk(KERN_ERR, "Error attempting to " | 111 | ecryptfs_printk(KERN_ERR, "Error attempting to " |
108 | "allocate crypto context\n"); | 112 | "allocate crypto context; rc = [%d]\n", |
113 | rc); | ||
109 | goto out; | 114 | goto out; |
110 | } | 115 | } |
116 | crypt_stat->hash_tfm = desc.tfm; | ||
111 | } | 117 | } |
112 | crypto_digest_init(crypt_stat->md5_tfm); | 118 | crypto_hash_init(&desc); |
113 | crypto_digest_update(crypt_stat->md5_tfm, &sg, 1); | 119 | crypto_hash_update(&desc, &sg, len); |
114 | crypto_digest_final(crypt_stat->md5_tfm, dst); | 120 | crypto_hash_final(&desc, dst); |
115 | mutex_unlock(&crypt_stat->cs_md5_tfm_mutex); | 121 | mutex_unlock(&crypt_stat->cs_hash_tfm_mutex); |
122 | out: | ||
123 | return rc; | ||
124 | } | ||
125 | |||
126 | int ecryptfs_crypto_api_algify_cipher_name(char **algified_name, | ||
127 | char *cipher_name, | ||
128 | char *chaining_modifier) | ||
129 | { | ||
130 | int cipher_name_len = strlen(cipher_name); | ||
131 | int chaining_modifier_len = strlen(chaining_modifier); | ||
132 | int algified_name_len; | ||
133 | int rc; | ||
134 | |||
135 | algified_name_len = (chaining_modifier_len + cipher_name_len + 3); | ||
136 | (*algified_name) = kmalloc(algified_name_len, GFP_KERNEL); | ||
137 | if (!(*algified_name)) { | ||
138 | rc = -ENOMEM; | ||
139 | goto out; | ||
140 | } | ||
141 | snprintf((*algified_name), algified_name_len, "%s(%s)", | ||
142 | chaining_modifier, cipher_name); | ||
143 | rc = 0; | ||
116 | out: | 144 | out: |
117 | return rc; | 145 | return rc; |
118 | } | 146 | } |
@@ -178,7 +206,7 @@ ecryptfs_init_crypt_stat(struct ecryptfs_crypt_stat *crypt_stat) | |||
178 | memset((void *)crypt_stat, 0, sizeof(struct ecryptfs_crypt_stat)); | 206 | memset((void *)crypt_stat, 0, sizeof(struct ecryptfs_crypt_stat)); |
179 | mutex_init(&crypt_stat->cs_mutex); | 207 | mutex_init(&crypt_stat->cs_mutex); |
180 | mutex_init(&crypt_stat->cs_tfm_mutex); | 208 | mutex_init(&crypt_stat->cs_tfm_mutex); |
181 | mutex_init(&crypt_stat->cs_md5_tfm_mutex); | 209 | mutex_init(&crypt_stat->cs_hash_tfm_mutex); |
182 | ECRYPTFS_SET_FLAG(crypt_stat->flags, ECRYPTFS_STRUCT_INITIALIZED); | 210 | ECRYPTFS_SET_FLAG(crypt_stat->flags, ECRYPTFS_STRUCT_INITIALIZED); |
183 | } | 211 | } |
184 | 212 | ||
@@ -191,9 +219,9 @@ ecryptfs_init_crypt_stat(struct ecryptfs_crypt_stat *crypt_stat) | |||
191 | void ecryptfs_destruct_crypt_stat(struct ecryptfs_crypt_stat *crypt_stat) | 219 | void ecryptfs_destruct_crypt_stat(struct ecryptfs_crypt_stat *crypt_stat) |
192 | { | 220 | { |
193 | if (crypt_stat->tfm) | 221 | if (crypt_stat->tfm) |
194 | crypto_free_tfm(crypt_stat->tfm); | 222 | crypto_free_blkcipher(crypt_stat->tfm); |
195 | if (crypt_stat->md5_tfm) | 223 | if (crypt_stat->hash_tfm) |
196 | crypto_free_tfm(crypt_stat->md5_tfm); | 224 | crypto_free_hash(crypt_stat->hash_tfm); |
197 | memset(crypt_stat, 0, sizeof(struct ecryptfs_crypt_stat)); | 225 | memset(crypt_stat, 0, sizeof(struct ecryptfs_crypt_stat)); |
198 | } | 226 | } |
199 | 227 | ||
@@ -203,7 +231,7 @@ void ecryptfs_destruct_mount_crypt_stat( | |||
203 | if (mount_crypt_stat->global_auth_tok_key) | 231 | if (mount_crypt_stat->global_auth_tok_key) |
204 | key_put(mount_crypt_stat->global_auth_tok_key); | 232 | key_put(mount_crypt_stat->global_auth_tok_key); |
205 | if (mount_crypt_stat->global_key_tfm) | 233 | if (mount_crypt_stat->global_key_tfm) |
206 | crypto_free_tfm(mount_crypt_stat->global_key_tfm); | 234 | crypto_free_blkcipher(mount_crypt_stat->global_key_tfm); |
207 | memset(mount_crypt_stat, 0, sizeof(struct ecryptfs_mount_crypt_stat)); | 235 | memset(mount_crypt_stat, 0, sizeof(struct ecryptfs_mount_crypt_stat)); |
208 | } | 236 | } |
209 | 237 | ||
@@ -269,6 +297,11 @@ static int encrypt_scatterlist(struct ecryptfs_crypt_stat *crypt_stat, | |||
269 | struct scatterlist *src_sg, int size, | 297 | struct scatterlist *src_sg, int size, |
270 | unsigned char *iv) | 298 | unsigned char *iv) |
271 | { | 299 | { |
300 | struct blkcipher_desc desc = { | ||
301 | .tfm = crypt_stat->tfm, | ||
302 | .info = iv, | ||
303 | .flags = CRYPTO_TFM_REQ_MAY_SLEEP | ||
304 | }; | ||
272 | int rc = 0; | 305 | int rc = 0; |
273 | 306 | ||
274 | BUG_ON(!crypt_stat || !crypt_stat->tfm | 307 | BUG_ON(!crypt_stat || !crypt_stat->tfm |
@@ -282,8 +315,8 @@ static int encrypt_scatterlist(struct ecryptfs_crypt_stat *crypt_stat, | |||
282 | } | 315 | } |
283 | /* Consider doing this once, when the file is opened */ | 316 | /* Consider doing this once, when the file is opened */ |
284 | mutex_lock(&crypt_stat->cs_tfm_mutex); | 317 | mutex_lock(&crypt_stat->cs_tfm_mutex); |
285 | rc = crypto_cipher_setkey(crypt_stat->tfm, crypt_stat->key, | 318 | rc = crypto_blkcipher_setkey(crypt_stat->tfm, crypt_stat->key, |
286 | crypt_stat->key_size); | 319 | crypt_stat->key_size); |
287 | if (rc) { | 320 | if (rc) { |
288 | ecryptfs_printk(KERN_ERR, "Error setting key; rc = [%d]\n", | 321 | ecryptfs_printk(KERN_ERR, "Error setting key; rc = [%d]\n", |
289 | rc); | 322 | rc); |
@@ -292,7 +325,7 @@ static int encrypt_scatterlist(struct ecryptfs_crypt_stat *crypt_stat, | |||
292 | goto out; | 325 | goto out; |
293 | } | 326 | } |
294 | ecryptfs_printk(KERN_DEBUG, "Encrypting [%d] bytes.\n", size); | 327 | ecryptfs_printk(KERN_DEBUG, "Encrypting [%d] bytes.\n", size); |
295 | crypto_cipher_encrypt_iv(crypt_stat->tfm, dest_sg, src_sg, size, iv); | 328 | crypto_blkcipher_encrypt_iv(&desc, dest_sg, src_sg, size); |
296 | mutex_unlock(&crypt_stat->cs_tfm_mutex); | 329 | mutex_unlock(&crypt_stat->cs_tfm_mutex); |
297 | out: | 330 | out: |
298 | return rc; | 331 | return rc; |
@@ -675,12 +708,17 @@ static int decrypt_scatterlist(struct ecryptfs_crypt_stat *crypt_stat, | |||
675 | struct scatterlist *src_sg, int size, | 708 | struct scatterlist *src_sg, int size, |
676 | unsigned char *iv) | 709 | unsigned char *iv) |
677 | { | 710 | { |
711 | struct blkcipher_desc desc = { | ||
712 | .tfm = crypt_stat->tfm, | ||
713 | .info = iv, | ||
714 | .flags = CRYPTO_TFM_REQ_MAY_SLEEP | ||
715 | }; | ||
678 | int rc = 0; | 716 | int rc = 0; |
679 | 717 | ||
680 | /* Consider doing this once, when the file is opened */ | 718 | /* Consider doing this once, when the file is opened */ |
681 | mutex_lock(&crypt_stat->cs_tfm_mutex); | 719 | mutex_lock(&crypt_stat->cs_tfm_mutex); |
682 | rc = crypto_cipher_setkey(crypt_stat->tfm, crypt_stat->key, | 720 | rc = crypto_blkcipher_setkey(crypt_stat->tfm, crypt_stat->key, |
683 | crypt_stat->key_size); | 721 | crypt_stat->key_size); |
684 | if (rc) { | 722 | if (rc) { |
685 | ecryptfs_printk(KERN_ERR, "Error setting key; rc = [%d]\n", | 723 | ecryptfs_printk(KERN_ERR, "Error setting key; rc = [%d]\n", |
686 | rc); | 724 | rc); |
@@ -689,8 +727,7 @@ static int decrypt_scatterlist(struct ecryptfs_crypt_stat *crypt_stat, | |||
689 | goto out; | 727 | goto out; |
690 | } | 728 | } |
691 | ecryptfs_printk(KERN_DEBUG, "Decrypting [%d] bytes.\n", size); | 729 | ecryptfs_printk(KERN_DEBUG, "Decrypting [%d] bytes.\n", size); |
692 | rc = crypto_cipher_decrypt_iv(crypt_stat->tfm, dest_sg, src_sg, size, | 730 | rc = crypto_blkcipher_decrypt_iv(&desc, dest_sg, src_sg, size); |
693 | iv); | ||
694 | mutex_unlock(&crypt_stat->cs_tfm_mutex); | 731 | mutex_unlock(&crypt_stat->cs_tfm_mutex); |
695 | if (rc) { | 732 | if (rc) { |
696 | ecryptfs_printk(KERN_ERR, "Error decrypting; rc = [%d]\n", | 733 | ecryptfs_printk(KERN_ERR, "Error decrypting; rc = [%d]\n", |
@@ -759,6 +796,7 @@ ecryptfs_decrypt_page_offset(struct ecryptfs_crypt_stat *crypt_stat, | |||
759 | */ | 796 | */ |
760 | int ecryptfs_init_crypt_ctx(struct ecryptfs_crypt_stat *crypt_stat) | 797 | int ecryptfs_init_crypt_ctx(struct ecryptfs_crypt_stat *crypt_stat) |
761 | { | 798 | { |
799 | char *full_alg_name; | ||
762 | int rc = -EINVAL; | 800 | int rc = -EINVAL; |
763 | 801 | ||
764 | if (!crypt_stat->cipher) { | 802 | if (!crypt_stat->cipher) { |
@@ -775,16 +813,24 @@ int ecryptfs_init_crypt_ctx(struct ecryptfs_crypt_stat *crypt_stat) | |||
775 | goto out; | 813 | goto out; |
776 | } | 814 | } |
777 | mutex_lock(&crypt_stat->cs_tfm_mutex); | 815 | mutex_lock(&crypt_stat->cs_tfm_mutex); |
778 | crypt_stat->tfm = crypto_alloc_tfm(crypt_stat->cipher, | 816 | rc = ecryptfs_crypto_api_algify_cipher_name(&full_alg_name, |
779 | ECRYPTFS_DEFAULT_CHAINING_MODE | 817 | crypt_stat->cipher, "cbc"); |
780 | | CRYPTO_TFM_REQ_WEAK_KEY); | 818 | if (rc) |
781 | mutex_unlock(&crypt_stat->cs_tfm_mutex); | 819 | goto out; |
820 | crypt_stat->tfm = crypto_alloc_blkcipher(full_alg_name, 0, | ||
821 | CRYPTO_ALG_ASYNC); | ||
822 | kfree(full_alg_name); | ||
782 | if (!crypt_stat->tfm) { | 823 | if (!crypt_stat->tfm) { |
783 | ecryptfs_printk(KERN_ERR, "cryptfs: init_crypt_ctx(): " | 824 | ecryptfs_printk(KERN_ERR, "cryptfs: init_crypt_ctx(): " |
784 | "Error initializing cipher [%s]\n", | 825 | "Error initializing cipher [%s]\n", |
785 | crypt_stat->cipher); | 826 | crypt_stat->cipher); |
827 | mutex_unlock(&crypt_stat->cs_tfm_mutex); | ||
786 | goto out; | 828 | goto out; |
787 | } | 829 | } |
830 | crypto_blkcipher_set_flags(crypt_stat->tfm, | ||
831 | (ECRYPTFS_DEFAULT_CHAINING_MODE | ||
832 | | CRYPTO_TFM_REQ_WEAK_KEY)); | ||
833 | mutex_unlock(&crypt_stat->cs_tfm_mutex); | ||
788 | rc = 0; | 834 | rc = 0; |
789 | out: | 835 | out: |
790 | return rc; | 836 | return rc; |
@@ -1145,28 +1191,28 @@ int ecryptfs_cipher_code_to_string(char *str, u16 cipher_code) | |||
1145 | int ecryptfs_read_header_region(char *data, struct dentry *dentry, | 1191 | int ecryptfs_read_header_region(char *data, struct dentry *dentry, |
1146 | struct vfsmount *mnt) | 1192 | struct vfsmount *mnt) |
1147 | { | 1193 | { |
1148 | struct file *file; | 1194 | struct file *lower_file; |
1149 | mm_segment_t oldfs; | 1195 | mm_segment_t oldfs; |
1150 | int rc; | 1196 | int rc; |
1151 | 1197 | ||
1152 | mnt = mntget(mnt); | 1198 | if ((rc = ecryptfs_open_lower_file(&lower_file, dentry, mnt, |
1153 | file = dentry_open(dentry, mnt, O_RDONLY); | 1199 | O_RDONLY))) { |
1154 | if (IS_ERR(file)) { | 1200 | printk(KERN_ERR |
1155 | ecryptfs_printk(KERN_DEBUG, "Error opening file to " | 1201 | "Error opening lower_file to read header region\n"); |
1156 | "read header region\n"); | ||
1157 | mntput(mnt); | ||
1158 | rc = PTR_ERR(file); | ||
1159 | goto out; | 1202 | goto out; |
1160 | } | 1203 | } |
1161 | file->f_pos = 0; | 1204 | lower_file->f_pos = 0; |
1162 | oldfs = get_fs(); | 1205 | oldfs = get_fs(); |
1163 | set_fs(get_ds()); | 1206 | set_fs(get_ds()); |
1164 | /* For releases 0.1 and 0.2, all of the header information | 1207 | /* For releases 0.1 and 0.2, all of the header information |
1165 | * fits in the first data extent-sized region. */ | 1208 | * fits in the first data extent-sized region. */ |
1166 | rc = file->f_op->read(file, (char __user *)data, | 1209 | rc = lower_file->f_op->read(lower_file, (char __user *)data, |
1167 | ECRYPTFS_DEFAULT_EXTENT_SIZE, &file->f_pos); | 1210 | ECRYPTFS_DEFAULT_EXTENT_SIZE, &lower_file->f_pos); |
1168 | set_fs(oldfs); | 1211 | set_fs(oldfs); |
1169 | fput(file); | 1212 | if ((rc = ecryptfs_close_lower_file(lower_file))) { |
1213 | printk(KERN_ERR "Error closing lower_file\n"); | ||
1214 | goto out; | ||
1215 | } | ||
1170 | rc = 0; | 1216 | rc = 0; |
1171 | out: | 1217 | out: |
1172 | return rc; | 1218 | return rc; |
@@ -1573,84 +1619,52 @@ out: | |||
1573 | 1619 | ||
1574 | /** | 1620 | /** |
1575 | * ecryptfs_process_cipher - Perform cipher initialization. | 1621 | * ecryptfs_process_cipher - Perform cipher initialization. |
1576 | * @tfm: Crypto context set by this function | ||
1577 | * @key_tfm: Crypto context for key material, set by this function | 1622 | * @key_tfm: Crypto context for key material, set by this function |
1578 | * @cipher_name: Name of the cipher. | 1623 | * @cipher_name: Name of the cipher |
1579 | * @key_size: Size of the key in bytes. | 1624 | * @key_size: Size of the key in bytes |
1580 | * | 1625 | * |
1581 | * Returns zero on success. Any crypto_tfm structs allocated here | 1626 | * Returns zero on success. Any crypto_tfm structs allocated here |
1582 | * should be released by other functions, such as on a superblock put | 1627 | * should be released by other functions, such as on a superblock put |
1583 | * event, regardless of whether this function succeeds for fails. | 1628 | * event, regardless of whether this function succeeds for fails. |
1584 | */ | 1629 | */ |
1585 | int | 1630 | int |
1586 | ecryptfs_process_cipher(struct crypto_tfm **tfm, struct crypto_tfm **key_tfm, | 1631 | ecryptfs_process_cipher(struct crypto_blkcipher **key_tfm, char *cipher_name, |
1587 | char *cipher_name, size_t key_size) | 1632 | size_t *key_size) |
1588 | { | 1633 | { |
1589 | char dummy_key[ECRYPTFS_MAX_KEY_BYTES]; | 1634 | char dummy_key[ECRYPTFS_MAX_KEY_BYTES]; |
1635 | char *full_alg_name; | ||
1590 | int rc; | 1636 | int rc; |
1591 | 1637 | ||
1592 | *tfm = *key_tfm = NULL; | 1638 | *key_tfm = NULL; |
1593 | if (key_size > ECRYPTFS_MAX_KEY_BYTES) { | 1639 | if (*key_size > ECRYPTFS_MAX_KEY_BYTES) { |
1594 | rc = -EINVAL; | 1640 | rc = -EINVAL; |
1595 | printk(KERN_ERR "Requested key size is [%Zd] bytes; maximum " | 1641 | printk(KERN_ERR "Requested key size is [%Zd] bytes; maximum " |
1596 | "allowable is [%d]\n", key_size, ECRYPTFS_MAX_KEY_BYTES); | 1642 | "allowable is [%d]\n", *key_size, ECRYPTFS_MAX_KEY_BYTES); |
1597 | goto out; | 1643 | goto out; |
1598 | } | 1644 | } |
1599 | *tfm = crypto_alloc_tfm(cipher_name, (ECRYPTFS_DEFAULT_CHAINING_MODE | 1645 | rc = ecryptfs_crypto_api_algify_cipher_name(&full_alg_name, cipher_name, |
1600 | | CRYPTO_TFM_REQ_WEAK_KEY)); | 1646 | "ecb"); |
1601 | if (!(*tfm)) { | 1647 | if (rc) |
1602 | rc = -EINVAL; | ||
1603 | printk(KERN_ERR "Unable to allocate crypto cipher with name " | ||
1604 | "[%s]\n", cipher_name); | ||
1605 | goto out; | 1648 | goto out; |
1606 | } | 1649 | *key_tfm = crypto_alloc_blkcipher(full_alg_name, 0, CRYPTO_ALG_ASYNC); |
1607 | *key_tfm = crypto_alloc_tfm(cipher_name, CRYPTO_TFM_REQ_WEAK_KEY); | 1650 | kfree(full_alg_name); |
1608 | if (!(*key_tfm)) { | 1651 | if (IS_ERR(*key_tfm)) { |
1609 | rc = -EINVAL; | 1652 | rc = PTR_ERR(*key_tfm); |
1610 | printk(KERN_ERR "Unable to allocate crypto cipher with name " | 1653 | printk(KERN_ERR "Unable to allocate crypto cipher with name " |
1611 | "[%s]\n", cipher_name); | 1654 | "[%s]; rc = [%d]\n", cipher_name, rc); |
1612 | goto out; | ||
1613 | } | ||
1614 | if (key_size < crypto_tfm_alg_min_keysize(*tfm)) { | ||
1615 | rc = -EINVAL; | ||
1616 | printk(KERN_ERR "Request key size is [%Zd]; minimum key size " | ||
1617 | "supported by cipher [%s] is [%d]\n", key_size, | ||
1618 | cipher_name, crypto_tfm_alg_min_keysize(*tfm)); | ||
1619 | goto out; | ||
1620 | } | ||
1621 | if (key_size < crypto_tfm_alg_min_keysize(*key_tfm)) { | ||
1622 | rc = -EINVAL; | ||
1623 | printk(KERN_ERR "Request key size is [%Zd]; minimum key size " | ||
1624 | "supported by cipher [%s] is [%d]\n", key_size, | ||
1625 | cipher_name, crypto_tfm_alg_min_keysize(*key_tfm)); | ||
1626 | goto out; | 1655 | goto out; |
1627 | } | 1656 | } |
1628 | if (key_size > crypto_tfm_alg_max_keysize(*tfm)) { | 1657 | crypto_blkcipher_set_flags(*key_tfm, CRYPTO_TFM_REQ_WEAK_KEY); |
1629 | rc = -EINVAL; | 1658 | if (*key_size == 0) { |
1630 | printk(KERN_ERR "Request key size is [%Zd]; maximum key size " | 1659 | struct blkcipher_alg *alg = crypto_blkcipher_alg(*key_tfm); |
1631 | "supported by cipher [%s] is [%d]\n", key_size, | 1660 | |
1632 | cipher_name, crypto_tfm_alg_min_keysize(*tfm)); | 1661 | *key_size = alg->max_keysize; |
1633 | goto out; | ||
1634 | } | ||
1635 | if (key_size > crypto_tfm_alg_max_keysize(*key_tfm)) { | ||
1636 | rc = -EINVAL; | ||
1637 | printk(KERN_ERR "Request key size is [%Zd]; maximum key size " | ||
1638 | "supported by cipher [%s] is [%d]\n", key_size, | ||
1639 | cipher_name, crypto_tfm_alg_min_keysize(*key_tfm)); | ||
1640 | goto out; | ||
1641 | } | ||
1642 | get_random_bytes(dummy_key, key_size); | ||
1643 | rc = crypto_cipher_setkey(*tfm, dummy_key, key_size); | ||
1644 | if (rc) { | ||
1645 | printk(KERN_ERR "Error attempting to set key of size [%Zd] for " | ||
1646 | "cipher [%s]; rc = [%d]\n", key_size, cipher_name, rc); | ||
1647 | rc = -EINVAL; | ||
1648 | goto out; | ||
1649 | } | 1662 | } |
1650 | rc = crypto_cipher_setkey(*key_tfm, dummy_key, key_size); | 1663 | get_random_bytes(dummy_key, *key_size); |
1664 | rc = crypto_blkcipher_setkey(*key_tfm, dummy_key, *key_size); | ||
1651 | if (rc) { | 1665 | if (rc) { |
1652 | printk(KERN_ERR "Error attempting to set key of size [%Zd] for " | 1666 | printk(KERN_ERR "Error attempting to set key of size [%Zd] for " |
1653 | "cipher [%s]; rc = [%d]\n", key_size, cipher_name, rc); | 1667 | "cipher [%s]; rc = [%d]\n", *key_size, cipher_name, rc); |
1654 | rc = -EINVAL; | 1668 | rc = -EINVAL; |
1655 | goto out; | 1669 | goto out; |
1656 | } | 1670 | } |
diff --git a/fs/ecryptfs/dentry.c b/fs/ecryptfs/dentry.c index f0d2a433242b..0b9992ab990f 100644 --- a/fs/ecryptfs/dentry.c +++ b/fs/ecryptfs/dentry.c | |||
@@ -24,6 +24,7 @@ | |||
24 | 24 | ||
25 | #include <linux/dcache.h> | 25 | #include <linux/dcache.h> |
26 | #include <linux/namei.h> | 26 | #include <linux/namei.h> |
27 | #include <linux/mount.h> | ||
27 | #include "ecryptfs_kernel.h" | 28 | #include "ecryptfs_kernel.h" |
28 | 29 | ||
29 | /** | 30 | /** |
@@ -76,8 +77,13 @@ static void ecryptfs_d_release(struct dentry *dentry) | |||
76 | if (ecryptfs_dentry_to_private(dentry)) | 77 | if (ecryptfs_dentry_to_private(dentry)) |
77 | kmem_cache_free(ecryptfs_dentry_info_cache, | 78 | kmem_cache_free(ecryptfs_dentry_info_cache, |
78 | ecryptfs_dentry_to_private(dentry)); | 79 | ecryptfs_dentry_to_private(dentry)); |
79 | if (lower_dentry) | 80 | if (lower_dentry) { |
81 | struct vfsmount *lower_mnt = | ||
82 | ecryptfs_dentry_to_lower_mnt(dentry); | ||
83 | |||
84 | mntput(lower_mnt); | ||
80 | dput(lower_dentry); | 85 | dput(lower_dentry); |
86 | } | ||
81 | return; | 87 | return; |
82 | } | 88 | } |
83 | 89 | ||
diff --git a/fs/ecryptfs/ecryptfs_kernel.h b/fs/ecryptfs/ecryptfs_kernel.h index 872c9958531a..f992533d1692 100644 --- a/fs/ecryptfs/ecryptfs_kernel.h +++ b/fs/ecryptfs/ecryptfs_kernel.h | |||
@@ -175,6 +175,7 @@ ecryptfs_get_key_payload_data(struct key *key) | |||
175 | #define ECRYPTFS_DEFAULT_CIPHER "aes" | 175 | #define ECRYPTFS_DEFAULT_CIPHER "aes" |
176 | #define ECRYPTFS_DEFAULT_KEY_BYTES 16 | 176 | #define ECRYPTFS_DEFAULT_KEY_BYTES 16 |
177 | #define ECRYPTFS_DEFAULT_CHAINING_MODE CRYPTO_TFM_MODE_CBC | 177 | #define ECRYPTFS_DEFAULT_CHAINING_MODE CRYPTO_TFM_MODE_CBC |
178 | #define ECRYPTFS_DEFAULT_HASH "md5" | ||
178 | #define ECRYPTFS_TAG_3_PACKET_TYPE 0x8C | 179 | #define ECRYPTFS_TAG_3_PACKET_TYPE 0x8C |
179 | #define ECRYPTFS_TAG_11_PACKET_TYPE 0xED | 180 | #define ECRYPTFS_TAG_11_PACKET_TYPE 0xED |
180 | #define MD5_DIGEST_SIZE 16 | 181 | #define MD5_DIGEST_SIZE 16 |
@@ -204,15 +205,15 @@ struct ecryptfs_crypt_stat { | |||
204 | size_t extent_shift; | 205 | size_t extent_shift; |
205 | unsigned int extent_mask; | 206 | unsigned int extent_mask; |
206 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat; | 207 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat; |
207 | struct crypto_tfm *tfm; | 208 | struct crypto_blkcipher *tfm; |
208 | struct crypto_tfm *md5_tfm; /* Crypto context for generating | 209 | struct crypto_hash *hash_tfm; /* Crypto context for generating |
209 | * the initialization vectors */ | 210 | * the initialization vectors */ |
210 | unsigned char cipher[ECRYPTFS_MAX_CIPHER_NAME_SIZE]; | 211 | unsigned char cipher[ECRYPTFS_MAX_CIPHER_NAME_SIZE]; |
211 | unsigned char key[ECRYPTFS_MAX_KEY_BYTES]; | 212 | unsigned char key[ECRYPTFS_MAX_KEY_BYTES]; |
212 | unsigned char root_iv[ECRYPTFS_MAX_IV_BYTES]; | 213 | unsigned char root_iv[ECRYPTFS_MAX_IV_BYTES]; |
213 | unsigned char keysigs[ECRYPTFS_MAX_NUM_KEYSIGS][ECRYPTFS_SIG_SIZE_HEX]; | 214 | unsigned char keysigs[ECRYPTFS_MAX_NUM_KEYSIGS][ECRYPTFS_SIG_SIZE_HEX]; |
214 | struct mutex cs_tfm_mutex; | 215 | struct mutex cs_tfm_mutex; |
215 | struct mutex cs_md5_tfm_mutex; | 216 | struct mutex cs_hash_tfm_mutex; |
216 | struct mutex cs_mutex; | 217 | struct mutex cs_mutex; |
217 | }; | 218 | }; |
218 | 219 | ||
@@ -244,7 +245,7 @@ struct ecryptfs_mount_crypt_stat { | |||
244 | struct ecryptfs_auth_tok *global_auth_tok; | 245 | struct ecryptfs_auth_tok *global_auth_tok; |
245 | struct key *global_auth_tok_key; | 246 | struct key *global_auth_tok_key; |
246 | size_t global_default_cipher_key_size; | 247 | size_t global_default_cipher_key_size; |
247 | struct crypto_tfm *global_key_tfm; | 248 | struct crypto_blkcipher *global_key_tfm; |
248 | struct mutex global_key_tfm_mutex; | 249 | struct mutex global_key_tfm_mutex; |
249 | unsigned char global_default_cipher_name[ECRYPTFS_MAX_CIPHER_NAME_SIZE | 250 | unsigned char global_default_cipher_name[ECRYPTFS_MAX_CIPHER_NAME_SIZE |
250 | + 1]; | 251 | + 1]; |
@@ -425,6 +426,9 @@ void ecryptfs_destruct_crypt_stat(struct ecryptfs_crypt_stat *crypt_stat); | |||
425 | void ecryptfs_destruct_mount_crypt_stat( | 426 | void ecryptfs_destruct_mount_crypt_stat( |
426 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat); | 427 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat); |
427 | int ecryptfs_init_crypt_ctx(struct ecryptfs_crypt_stat *crypt_stat); | 428 | int ecryptfs_init_crypt_ctx(struct ecryptfs_crypt_stat *crypt_stat); |
429 | int ecryptfs_crypto_api_algify_cipher_name(char **algified_name, | ||
430 | char *cipher_name, | ||
431 | char *chaining_modifier); | ||
428 | int ecryptfs_write_inode_size_to_header(struct file *lower_file, | 432 | int ecryptfs_write_inode_size_to_header(struct file *lower_file, |
429 | struct inode *lower_inode, | 433 | struct inode *lower_inode, |
430 | struct inode *inode); | 434 | struct inode *inode); |
@@ -473,10 +477,14 @@ ecryptfs_parse_packet_set(struct ecryptfs_crypt_stat *crypt_stat, | |||
473 | unsigned char *src, struct dentry *ecryptfs_dentry); | 477 | unsigned char *src, struct dentry *ecryptfs_dentry); |
474 | int ecryptfs_truncate(struct dentry *dentry, loff_t new_length); | 478 | int ecryptfs_truncate(struct dentry *dentry, loff_t new_length); |
475 | int | 479 | int |
476 | ecryptfs_process_cipher(struct crypto_tfm **tfm, struct crypto_tfm **key_tfm, | 480 | ecryptfs_process_cipher(struct crypto_blkcipher **key_tfm, char *cipher_name, |
477 | char *cipher_name, size_t key_size); | 481 | size_t *key_size); |
478 | int ecryptfs_inode_test(struct inode *inode, void *candidate_lower_inode); | 482 | int ecryptfs_inode_test(struct inode *inode, void *candidate_lower_inode); |
479 | int ecryptfs_inode_set(struct inode *inode, void *lower_inode); | 483 | int ecryptfs_inode_set(struct inode *inode, void *lower_inode); |
480 | void ecryptfs_init_inode(struct inode *inode, struct inode *lower_inode); | 484 | void ecryptfs_init_inode(struct inode *inode, struct inode *lower_inode); |
485 | int ecryptfs_open_lower_file(struct file **lower_file, | ||
486 | struct dentry *lower_dentry, | ||
487 | struct vfsmount *lower_mnt, int flags); | ||
488 | int ecryptfs_close_lower_file(struct file *lower_file); | ||
481 | 489 | ||
482 | #endif /* #ifndef ECRYPTFS_KERNEL_H */ | 490 | #endif /* #ifndef ECRYPTFS_KERNEL_H */ |
diff --git a/fs/ecryptfs/file.c b/fs/ecryptfs/file.c index c8550c9f9cd2..a92ef05eff8f 100644 --- a/fs/ecryptfs/file.c +++ b/fs/ecryptfs/file.c | |||
@@ -198,6 +198,33 @@ retry: | |||
198 | 198 | ||
199 | struct kmem_cache *ecryptfs_file_info_cache; | 199 | struct kmem_cache *ecryptfs_file_info_cache; |
200 | 200 | ||
201 | int ecryptfs_open_lower_file(struct file **lower_file, | ||
202 | struct dentry *lower_dentry, | ||
203 | struct vfsmount *lower_mnt, int flags) | ||
204 | { | ||
205 | int rc = 0; | ||
206 | |||
207 | dget(lower_dentry); | ||
208 | mntget(lower_mnt); | ||
209 | *lower_file = dentry_open(lower_dentry, lower_mnt, flags); | ||
210 | if (IS_ERR(*lower_file)) { | ||
211 | printk(KERN_ERR "Error opening lower file for lower_dentry " | ||
212 | "[0x%p], lower_mnt [0x%p], and flags [0x%x]\n", | ||
213 | lower_dentry, lower_mnt, flags); | ||
214 | rc = PTR_ERR(*lower_file); | ||
215 | *lower_file = NULL; | ||
216 | goto out; | ||
217 | } | ||
218 | out: | ||
219 | return rc; | ||
220 | } | ||
221 | |||
222 | int ecryptfs_close_lower_file(struct file *lower_file) | ||
223 | { | ||
224 | fput(lower_file); | ||
225 | return 0; | ||
226 | } | ||
227 | |||
201 | /** | 228 | /** |
202 | * ecryptfs_open | 229 | * ecryptfs_open |
203 | * @inode: inode speciying file to open | 230 | * @inode: inode speciying file to open |
@@ -244,19 +271,15 @@ static int ecryptfs_open(struct inode *inode, struct file *file) | |||
244 | ECRYPTFS_SET_FLAG(crypt_stat->flags, ECRYPTFS_ENCRYPTED); | 271 | ECRYPTFS_SET_FLAG(crypt_stat->flags, ECRYPTFS_ENCRYPTED); |
245 | } | 272 | } |
246 | mutex_unlock(&crypt_stat->cs_mutex); | 273 | mutex_unlock(&crypt_stat->cs_mutex); |
247 | /* This mntget & dget is undone via fput when the file is released */ | ||
248 | dget(lower_dentry); | ||
249 | lower_flags = file->f_flags; | 274 | lower_flags = file->f_flags; |
250 | if ((lower_flags & O_ACCMODE) == O_WRONLY) | 275 | if ((lower_flags & O_ACCMODE) == O_WRONLY) |
251 | lower_flags = (lower_flags & O_ACCMODE) | O_RDWR; | 276 | lower_flags = (lower_flags & O_ACCMODE) | O_RDWR; |
252 | if (file->f_flags & O_APPEND) | 277 | if (file->f_flags & O_APPEND) |
253 | lower_flags &= ~O_APPEND; | 278 | lower_flags &= ~O_APPEND; |
254 | lower_mnt = ecryptfs_dentry_to_lower_mnt(ecryptfs_dentry); | 279 | lower_mnt = ecryptfs_dentry_to_lower_mnt(ecryptfs_dentry); |
255 | mntget(lower_mnt); | ||
256 | /* Corresponding fput() in ecryptfs_release() */ | 280 | /* Corresponding fput() in ecryptfs_release() */ |
257 | lower_file = dentry_open(lower_dentry, lower_mnt, lower_flags); | 281 | if ((rc = ecryptfs_open_lower_file(&lower_file, lower_dentry, lower_mnt, |
258 | if (IS_ERR(lower_file)) { | 282 | lower_flags))) { |
259 | rc = PTR_ERR(lower_file); | ||
260 | ecryptfs_printk(KERN_ERR, "Error opening lower file\n"); | 283 | ecryptfs_printk(KERN_ERR, "Error opening lower file\n"); |
261 | goto out_puts; | 284 | goto out_puts; |
262 | } | 285 | } |
@@ -341,11 +364,16 @@ static int ecryptfs_release(struct inode *inode, struct file *file) | |||
341 | struct file *lower_file = ecryptfs_file_to_lower(file); | 364 | struct file *lower_file = ecryptfs_file_to_lower(file); |
342 | struct ecryptfs_file_info *file_info = ecryptfs_file_to_private(file); | 365 | struct ecryptfs_file_info *file_info = ecryptfs_file_to_private(file); |
343 | struct inode *lower_inode = ecryptfs_inode_to_lower(inode); | 366 | struct inode *lower_inode = ecryptfs_inode_to_lower(inode); |
367 | int rc; | ||
344 | 368 | ||
345 | fput(lower_file); | 369 | if ((rc = ecryptfs_close_lower_file(lower_file))) { |
370 | printk(KERN_ERR "Error closing lower_file\n"); | ||
371 | goto out; | ||
372 | } | ||
346 | inode->i_blocks = lower_inode->i_blocks; | 373 | inode->i_blocks = lower_inode->i_blocks; |
347 | kmem_cache_free(ecryptfs_file_info_cache, file_info); | 374 | kmem_cache_free(ecryptfs_file_info_cache, file_info); |
348 | return 0; | 375 | out: |
376 | return rc; | ||
349 | } | 377 | } |
350 | 378 | ||
351 | static int | 379 | static int |
diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c index efdd2b7b62d7..ff4865d24f0f 100644 --- a/fs/ecryptfs/inode.c +++ b/fs/ecryptfs/inode.c | |||
@@ -231,7 +231,6 @@ static int ecryptfs_initialize_file(struct dentry *ecryptfs_dentry) | |||
231 | int lower_flags; | 231 | int lower_flags; |
232 | struct ecryptfs_crypt_stat *crypt_stat; | 232 | struct ecryptfs_crypt_stat *crypt_stat; |
233 | struct dentry *lower_dentry; | 233 | struct dentry *lower_dentry; |
234 | struct dentry *tlower_dentry = NULL; | ||
235 | struct file *lower_file; | 234 | struct file *lower_file; |
236 | struct inode *inode, *lower_inode; | 235 | struct inode *inode, *lower_inode; |
237 | struct vfsmount *lower_mnt; | 236 | struct vfsmount *lower_mnt; |
@@ -241,30 +240,19 @@ static int ecryptfs_initialize_file(struct dentry *ecryptfs_dentry) | |||
241 | lower_dentry->d_name.name); | 240 | lower_dentry->d_name.name); |
242 | inode = ecryptfs_dentry->d_inode; | 241 | inode = ecryptfs_dentry->d_inode; |
243 | crypt_stat = &ecryptfs_inode_to_private(inode)->crypt_stat; | 242 | crypt_stat = &ecryptfs_inode_to_private(inode)->crypt_stat; |
244 | tlower_dentry = dget(lower_dentry); | ||
245 | if (!tlower_dentry) { | ||
246 | rc = -ENOMEM; | ||
247 | ecryptfs_printk(KERN_ERR, "Error dget'ing lower_dentry\n"); | ||
248 | goto out; | ||
249 | } | ||
250 | lower_flags = ((O_CREAT | O_WRONLY | O_TRUNC) & O_ACCMODE) | O_RDWR; | 243 | lower_flags = ((O_CREAT | O_WRONLY | O_TRUNC) & O_ACCMODE) | O_RDWR; |
251 | #if BITS_PER_LONG != 32 | 244 | #if BITS_PER_LONG != 32 |
252 | lower_flags |= O_LARGEFILE; | 245 | lower_flags |= O_LARGEFILE; |
253 | #endif | 246 | #endif |
254 | lower_mnt = ecryptfs_dentry_to_lower_mnt(ecryptfs_dentry); | 247 | lower_mnt = ecryptfs_dentry_to_lower_mnt(ecryptfs_dentry); |
255 | mntget(lower_mnt); | ||
256 | /* Corresponding fput() at end of this function */ | 248 | /* Corresponding fput() at end of this function */ |
257 | lower_file = dentry_open(tlower_dentry, lower_mnt, lower_flags); | 249 | if ((rc = ecryptfs_open_lower_file(&lower_file, lower_dentry, lower_mnt, |
258 | if (IS_ERR(lower_file)) { | 250 | lower_flags))) { |
259 | rc = PTR_ERR(lower_file); | ||
260 | ecryptfs_printk(KERN_ERR, | 251 | ecryptfs_printk(KERN_ERR, |
261 | "Error opening dentry; rc = [%i]\n", rc); | 252 | "Error opening dentry; rc = [%i]\n", rc); |
262 | goto out; | 253 | goto out; |
263 | } | 254 | } |
264 | /* fput(lower_file) should handle the puts if we do this */ | 255 | lower_inode = lower_dentry->d_inode; |
265 | lower_file->f_dentry = tlower_dentry; | ||
266 | lower_file->f_vfsmnt = lower_mnt; | ||
267 | lower_inode = tlower_dentry->d_inode; | ||
268 | if (S_ISDIR(ecryptfs_dentry->d_inode->i_mode)) { | 256 | if (S_ISDIR(ecryptfs_dentry->d_inode->i_mode)) { |
269 | ecryptfs_printk(KERN_DEBUG, "This is a directory\n"); | 257 | ecryptfs_printk(KERN_DEBUG, "This is a directory\n"); |
270 | ECRYPTFS_CLEAR_FLAG(crypt_stat->flags, ECRYPTFS_ENCRYPTED); | 258 | ECRYPTFS_CLEAR_FLAG(crypt_stat->flags, ECRYPTFS_ENCRYPTED); |
@@ -285,7 +273,8 @@ static int ecryptfs_initialize_file(struct dentry *ecryptfs_dentry) | |||
285 | } | 273 | } |
286 | rc = grow_file(ecryptfs_dentry, lower_file, inode, lower_inode); | 274 | rc = grow_file(ecryptfs_dentry, lower_file, inode, lower_inode); |
287 | out_fput: | 275 | out_fput: |
288 | fput(lower_file); | 276 | if ((rc = ecryptfs_close_lower_file(lower_file))) |
277 | printk(KERN_ERR "Error closing lower_file\n"); | ||
289 | out: | 278 | out: |
290 | return rc; | 279 | return rc; |
291 | } | 280 | } |
@@ -336,7 +325,6 @@ static struct dentry *ecryptfs_lookup(struct inode *dir, struct dentry *dentry, | |||
336 | struct dentry *lower_dir_dentry; | 325 | struct dentry *lower_dir_dentry; |
337 | struct dentry *lower_dentry; | 326 | struct dentry *lower_dentry; |
338 | struct vfsmount *lower_mnt; | 327 | struct vfsmount *lower_mnt; |
339 | struct dentry *tlower_dentry = NULL; | ||
340 | char *encoded_name; | 328 | char *encoded_name; |
341 | unsigned int encoded_namelen; | 329 | unsigned int encoded_namelen; |
342 | struct ecryptfs_crypt_stat *crypt_stat = NULL; | 330 | struct ecryptfs_crypt_stat *crypt_stat = NULL; |
@@ -347,27 +335,32 @@ static struct dentry *ecryptfs_lookup(struct inode *dir, struct dentry *dentry, | |||
347 | lower_dir_dentry = ecryptfs_dentry_to_lower(dentry->d_parent); | 335 | lower_dir_dentry = ecryptfs_dentry_to_lower(dentry->d_parent); |
348 | dentry->d_op = &ecryptfs_dops; | 336 | dentry->d_op = &ecryptfs_dops; |
349 | if ((dentry->d_name.len == 1 && !strcmp(dentry->d_name.name, ".")) | 337 | if ((dentry->d_name.len == 1 && !strcmp(dentry->d_name.name, ".")) |
350 | || (dentry->d_name.len == 2 && !strcmp(dentry->d_name.name, ".."))) | 338 | || (dentry->d_name.len == 2 |
351 | goto out_drop; | 339 | && !strcmp(dentry->d_name.name, ".."))) { |
340 | d_drop(dentry); | ||
341 | goto out; | ||
342 | } | ||
352 | encoded_namelen = ecryptfs_encode_filename(crypt_stat, | 343 | encoded_namelen = ecryptfs_encode_filename(crypt_stat, |
353 | dentry->d_name.name, | 344 | dentry->d_name.name, |
354 | dentry->d_name.len, | 345 | dentry->d_name.len, |
355 | &encoded_name); | 346 | &encoded_name); |
356 | if (encoded_namelen < 0) { | 347 | if (encoded_namelen < 0) { |
357 | rc = encoded_namelen; | 348 | rc = encoded_namelen; |
358 | goto out_drop; | 349 | d_drop(dentry); |
350 | goto out; | ||
359 | } | 351 | } |
360 | ecryptfs_printk(KERN_DEBUG, "encoded_name = [%s]; encoded_namelen " | 352 | ecryptfs_printk(KERN_DEBUG, "encoded_name = [%s]; encoded_namelen " |
361 | "= [%d]\n", encoded_name, encoded_namelen); | 353 | "= [%d]\n", encoded_name, encoded_namelen); |
362 | lower_dentry = lookup_one_len(encoded_name, lower_dir_dentry, | 354 | lower_dentry = lookup_one_len(encoded_name, lower_dir_dentry, |
363 | encoded_namelen - 1); | 355 | encoded_namelen - 1); |
364 | kfree(encoded_name); | 356 | kfree(encoded_name); |
365 | lower_mnt = mntget(ecryptfs_dentry_to_lower_mnt(dentry->d_parent)); | ||
366 | if (IS_ERR(lower_dentry)) { | 357 | if (IS_ERR(lower_dentry)) { |
367 | ecryptfs_printk(KERN_ERR, "ERR from lower_dentry\n"); | 358 | ecryptfs_printk(KERN_ERR, "ERR from lower_dentry\n"); |
368 | rc = PTR_ERR(lower_dentry); | 359 | rc = PTR_ERR(lower_dentry); |
369 | goto out_drop; | 360 | d_drop(dentry); |
361 | goto out; | ||
370 | } | 362 | } |
363 | lower_mnt = mntget(ecryptfs_dentry_to_lower_mnt(dentry->d_parent)); | ||
371 | ecryptfs_printk(KERN_DEBUG, "lower_dentry = [%p]; lower_dentry->" | 364 | ecryptfs_printk(KERN_DEBUG, "lower_dentry = [%p]; lower_dentry->" |
372 | "d_name.name = [%s]\n", lower_dentry, | 365 | "d_name.name = [%s]\n", lower_dentry, |
373 | lower_dentry->d_name.name); | 366 | lower_dentry->d_name.name); |
@@ -408,12 +401,6 @@ static struct dentry *ecryptfs_lookup(struct inode *dir, struct dentry *dentry, | |||
408 | "as we *think* we are about to unlink\n"); | 401 | "as we *think* we are about to unlink\n"); |
409 | goto out; | 402 | goto out; |
410 | } | 403 | } |
411 | tlower_dentry = dget(lower_dentry); | ||
412 | if (!tlower_dentry || IS_ERR(tlower_dentry)) { | ||
413 | rc = -ENOMEM; | ||
414 | ecryptfs_printk(KERN_ERR, "Cannot dget lower_dentry\n"); | ||
415 | goto out_dput; | ||
416 | } | ||
417 | /* Released in this function */ | 404 | /* Released in this function */ |
418 | page_virt = | 405 | page_virt = |
419 | (char *)kmem_cache_alloc(ecryptfs_header_cache_2, | 406 | (char *)kmem_cache_alloc(ecryptfs_header_cache_2, |
@@ -425,7 +412,7 @@ static struct dentry *ecryptfs_lookup(struct inode *dir, struct dentry *dentry, | |||
425 | goto out_dput; | 412 | goto out_dput; |
426 | } | 413 | } |
427 | memset(page_virt, 0, PAGE_CACHE_SIZE); | 414 | memset(page_virt, 0, PAGE_CACHE_SIZE); |
428 | rc = ecryptfs_read_header_region(page_virt, tlower_dentry, nd->mnt); | 415 | rc = ecryptfs_read_header_region(page_virt, lower_dentry, nd->mnt); |
429 | crypt_stat = &ecryptfs_inode_to_private(dentry->d_inode)->crypt_stat; | 416 | crypt_stat = &ecryptfs_inode_to_private(dentry->d_inode)->crypt_stat; |
430 | if (!ECRYPTFS_CHECK_FLAG(crypt_stat->flags, ECRYPTFS_POLICY_APPLIED)) | 417 | if (!ECRYPTFS_CHECK_FLAG(crypt_stat->flags, ECRYPTFS_POLICY_APPLIED)) |
431 | ecryptfs_set_default_sizes(crypt_stat); | 418 | ecryptfs_set_default_sizes(crypt_stat); |
@@ -448,9 +435,6 @@ static struct dentry *ecryptfs_lookup(struct inode *dir, struct dentry *dentry, | |||
448 | 435 | ||
449 | out_dput: | 436 | out_dput: |
450 | dput(lower_dentry); | 437 | dput(lower_dentry); |
451 | if (tlower_dentry) | ||
452 | dput(tlower_dentry); | ||
453 | out_drop: | ||
454 | d_drop(dentry); | 438 | d_drop(dentry); |
455 | out: | 439 | out: |
456 | return ERR_PTR(rc); | 440 | return ERR_PTR(rc); |
@@ -486,8 +470,8 @@ out_lock: | |||
486 | unlock_dir(lower_dir_dentry); | 470 | unlock_dir(lower_dir_dentry); |
487 | dput(lower_new_dentry); | 471 | dput(lower_new_dentry); |
488 | dput(lower_old_dentry); | 472 | dput(lower_old_dentry); |
489 | if (!new_dentry->d_inode) | 473 | d_drop(new_dentry); |
490 | d_drop(new_dentry); | 474 | d_drop(old_dentry); |
491 | return rc; | 475 | return rc; |
492 | } | 476 | } |
493 | 477 | ||
@@ -576,41 +560,24 @@ out: | |||
576 | 560 | ||
577 | static int ecryptfs_rmdir(struct inode *dir, struct dentry *dentry) | 561 | static int ecryptfs_rmdir(struct inode *dir, struct dentry *dentry) |
578 | { | 562 | { |
579 | int rc = 0; | ||
580 | struct dentry *tdentry = NULL; | ||
581 | struct dentry *lower_dentry; | 563 | struct dentry *lower_dentry; |
582 | struct dentry *tlower_dentry = NULL; | ||
583 | struct dentry *lower_dir_dentry; | 564 | struct dentry *lower_dir_dentry; |
565 | int rc; | ||
584 | 566 | ||
585 | lower_dentry = ecryptfs_dentry_to_lower(dentry); | 567 | lower_dentry = ecryptfs_dentry_to_lower(dentry); |
586 | if (!(tdentry = dget(dentry))) { | 568 | dget(dentry); |
587 | rc = -EINVAL; | ||
588 | ecryptfs_printk(KERN_ERR, "Error dget'ing dentry [%p]\n", | ||
589 | dentry); | ||
590 | goto out; | ||
591 | } | ||
592 | lower_dir_dentry = lock_parent(lower_dentry); | 569 | lower_dir_dentry = lock_parent(lower_dentry); |
593 | if (!(tlower_dentry = dget(lower_dentry))) { | 570 | dget(lower_dentry); |
594 | rc = -EINVAL; | ||
595 | ecryptfs_printk(KERN_ERR, "Error dget'ing lower_dentry " | ||
596 | "[%p]\n", lower_dentry); | ||
597 | goto out; | ||
598 | } | ||
599 | rc = vfs_rmdir(lower_dir_dentry->d_inode, lower_dentry); | 571 | rc = vfs_rmdir(lower_dir_dentry->d_inode, lower_dentry); |
600 | if (!rc) { | 572 | dput(lower_dentry); |
601 | d_delete(tlower_dentry); | 573 | if (!rc) |
602 | tlower_dentry = NULL; | 574 | d_delete(lower_dentry); |
603 | } | ||
604 | ecryptfs_copy_attr_times(dir, lower_dir_dentry->d_inode); | 575 | ecryptfs_copy_attr_times(dir, lower_dir_dentry->d_inode); |
605 | dir->i_nlink = lower_dir_dentry->d_inode->i_nlink; | 576 | dir->i_nlink = lower_dir_dentry->d_inode->i_nlink; |
606 | unlock_dir(lower_dir_dentry); | 577 | unlock_dir(lower_dir_dentry); |
607 | if (!rc) | 578 | if (!rc) |
608 | d_drop(dentry); | 579 | d_drop(dentry); |
609 | out: | 580 | dput(dentry); |
610 | if (tdentry) | ||
611 | dput(tdentry); | ||
612 | if (tlower_dentry) | ||
613 | dput(tlower_dentry); | ||
614 | return rc; | 581 | return rc; |
615 | } | 582 | } |
616 | 583 | ||
@@ -832,12 +799,11 @@ int ecryptfs_truncate(struct dentry *dentry, loff_t new_length) | |||
832 | } | 799 | } |
833 | lower_dentry = ecryptfs_dentry_to_lower(dentry); | 800 | lower_dentry = ecryptfs_dentry_to_lower(dentry); |
834 | /* This dget & mntget is released through fput at out_fput: */ | 801 | /* This dget & mntget is released through fput at out_fput: */ |
835 | dget(lower_dentry); | ||
836 | lower_mnt = ecryptfs_dentry_to_lower_mnt(dentry); | 802 | lower_mnt = ecryptfs_dentry_to_lower_mnt(dentry); |
837 | mntget(lower_mnt); | 803 | if ((rc = ecryptfs_open_lower_file(&lower_file, lower_dentry, lower_mnt, |
838 | lower_file = dentry_open(lower_dentry, lower_mnt, O_RDWR); | 804 | O_RDWR))) { |
839 | if (unlikely(IS_ERR(lower_file))) { | 805 | ecryptfs_printk(KERN_ERR, |
840 | rc = PTR_ERR(lower_file); | 806 | "Error opening dentry; rc = [%i]\n", rc); |
841 | goto out_free; | 807 | goto out_free; |
842 | } | 808 | } |
843 | ecryptfs_set_file_lower(&fake_ecryptfs_file, lower_file); | 809 | ecryptfs_set_file_lower(&fake_ecryptfs_file, lower_file); |
@@ -879,7 +845,8 @@ int ecryptfs_truncate(struct dentry *dentry, loff_t new_length) | |||
879 | = CURRENT_TIME; | 845 | = CURRENT_TIME; |
880 | mark_inode_dirty_sync(inode); | 846 | mark_inode_dirty_sync(inode); |
881 | out_fput: | 847 | out_fput: |
882 | fput(lower_file); | 848 | if ((rc = ecryptfs_close_lower_file(lower_file))) |
849 | printk(KERN_ERR "Error closing lower_file\n"); | ||
883 | out_free: | 850 | out_free: |
884 | if (ecryptfs_file_to_private(&fake_ecryptfs_file)) | 851 | if (ecryptfs_file_to_private(&fake_ecryptfs_file)) |
885 | kmem_cache_free(ecryptfs_file_info_cache, | 852 | kmem_cache_free(ecryptfs_file_info_cache, |
diff --git a/fs/ecryptfs/keystore.c b/fs/ecryptfs/keystore.c index ba454785a0c5..c3746f56d162 100644 --- a/fs/ecryptfs/keystore.c +++ b/fs/ecryptfs/keystore.c | |||
@@ -458,14 +458,16 @@ out: | |||
458 | static int decrypt_session_key(struct ecryptfs_auth_tok *auth_tok, | 458 | static int decrypt_session_key(struct ecryptfs_auth_tok *auth_tok, |
459 | struct ecryptfs_crypt_stat *crypt_stat) | 459 | struct ecryptfs_crypt_stat *crypt_stat) |
460 | { | 460 | { |
461 | int rc = 0; | ||
462 | struct ecryptfs_password *password_s_ptr; | 461 | struct ecryptfs_password *password_s_ptr; |
463 | struct crypto_tfm *tfm = NULL; | ||
464 | struct scatterlist src_sg[2], dst_sg[2]; | 462 | struct scatterlist src_sg[2], dst_sg[2]; |
465 | struct mutex *tfm_mutex = NULL; | 463 | struct mutex *tfm_mutex = NULL; |
466 | /* TODO: Use virt_to_scatterlist for these */ | 464 | /* TODO: Use virt_to_scatterlist for these */ |
467 | char *encrypted_session_key; | 465 | char *encrypted_session_key; |
468 | char *session_key; | 466 | char *session_key; |
467 | struct blkcipher_desc desc = { | ||
468 | .flags = CRYPTO_TFM_REQ_MAY_SLEEP | ||
469 | }; | ||
470 | int rc = 0; | ||
469 | 471 | ||
470 | password_s_ptr = &auth_tok->token.password; | 472 | password_s_ptr = &auth_tok->token.password; |
471 | if (ECRYPTFS_CHECK_FLAG(password_s_ptr->flags, | 473 | if (ECRYPTFS_CHECK_FLAG(password_s_ptr->flags, |
@@ -482,30 +484,37 @@ static int decrypt_session_key(struct ecryptfs_auth_tok *auth_tok, | |||
482 | if (!strcmp(crypt_stat->cipher, | 484 | if (!strcmp(crypt_stat->cipher, |
483 | crypt_stat->mount_crypt_stat->global_default_cipher_name) | 485 | crypt_stat->mount_crypt_stat->global_default_cipher_name) |
484 | && crypt_stat->mount_crypt_stat->global_key_tfm) { | 486 | && crypt_stat->mount_crypt_stat->global_key_tfm) { |
485 | tfm = crypt_stat->mount_crypt_stat->global_key_tfm; | 487 | desc.tfm = crypt_stat->mount_crypt_stat->global_key_tfm; |
486 | tfm_mutex = &crypt_stat->mount_crypt_stat->global_key_tfm_mutex; | 488 | tfm_mutex = &crypt_stat->mount_crypt_stat->global_key_tfm_mutex; |
487 | } else { | 489 | } else { |
488 | tfm = crypto_alloc_tfm(crypt_stat->cipher, | 490 | char *full_alg_name; |
489 | CRYPTO_TFM_REQ_WEAK_KEY); | 491 | |
490 | if (!tfm) { | 492 | rc = ecryptfs_crypto_api_algify_cipher_name(&full_alg_name, |
491 | printk(KERN_ERR "Error allocating crypto context\n"); | 493 | crypt_stat->cipher, |
492 | rc = -ENOMEM; | 494 | "ecb"); |
495 | if (rc) | ||
496 | goto out; | ||
497 | desc.tfm = crypto_alloc_blkcipher(full_alg_name, 0, | ||
498 | CRYPTO_ALG_ASYNC); | ||
499 | kfree(full_alg_name); | ||
500 | if (IS_ERR(desc.tfm)) { | ||
501 | rc = PTR_ERR(desc.tfm); | ||
502 | printk(KERN_ERR "Error allocating crypto context; " | ||
503 | "rc = [%d]\n", rc); | ||
493 | goto out; | 504 | goto out; |
494 | } | 505 | } |
495 | } | 506 | crypto_blkcipher_set_flags(desc.tfm, CRYPTO_TFM_REQ_WEAK_KEY); |
496 | if (password_s_ptr->session_key_encryption_key_bytes | ||
497 | < crypto_tfm_alg_min_keysize(tfm)) { | ||
498 | printk(KERN_WARNING "Session key encryption key is [%d] bytes; " | ||
499 | "minimum keysize for selected cipher is [%d] bytes.\n", | ||
500 | password_s_ptr->session_key_encryption_key_bytes, | ||
501 | crypto_tfm_alg_min_keysize(tfm)); | ||
502 | rc = -EINVAL; | ||
503 | goto out; | ||
504 | } | 507 | } |
505 | if (tfm_mutex) | 508 | if (tfm_mutex) |
506 | mutex_lock(tfm_mutex); | 509 | mutex_lock(tfm_mutex); |
507 | crypto_cipher_setkey(tfm, password_s_ptr->session_key_encryption_key, | 510 | rc = crypto_blkcipher_setkey(desc.tfm, |
508 | crypt_stat->key_size); | 511 | password_s_ptr->session_key_encryption_key, |
512 | crypt_stat->key_size); | ||
513 | if (rc < 0) { | ||
514 | printk(KERN_ERR "Error setting key for crypto context\n"); | ||
515 | rc = -EINVAL; | ||
516 | goto out_free_tfm; | ||
517 | } | ||
509 | /* TODO: virt_to_scatterlist */ | 518 | /* TODO: virt_to_scatterlist */ |
510 | encrypted_session_key = (char *)__get_free_page(GFP_KERNEL); | 519 | encrypted_session_key = (char *)__get_free_page(GFP_KERNEL); |
511 | if (!encrypted_session_key) { | 520 | if (!encrypted_session_key) { |
@@ -531,9 +540,12 @@ static int decrypt_session_key(struct ecryptfs_auth_tok *auth_tok, | |||
531 | auth_tok->session_key.decrypted_key_size = | 540 | auth_tok->session_key.decrypted_key_size = |
532 | auth_tok->session_key.encrypted_key_size; | 541 | auth_tok->session_key.encrypted_key_size; |
533 | dst_sg[0].length = auth_tok->session_key.encrypted_key_size; | 542 | dst_sg[0].length = auth_tok->session_key.encrypted_key_size; |
534 | /* TODO: Handle error condition */ | 543 | rc = crypto_blkcipher_decrypt(&desc, dst_sg, src_sg, |
535 | crypto_cipher_decrypt(tfm, dst_sg, src_sg, | 544 | auth_tok->session_key.encrypted_key_size); |
536 | auth_tok->session_key.encrypted_key_size); | 545 | if (rc) { |
546 | printk(KERN_ERR "Error decrypting; rc = [%d]\n", rc); | ||
547 | goto out_free_memory; | ||
548 | } | ||
537 | auth_tok->session_key.decrypted_key_size = | 549 | auth_tok->session_key.decrypted_key_size = |
538 | auth_tok->session_key.encrypted_key_size; | 550 | auth_tok->session_key.encrypted_key_size; |
539 | memcpy(auth_tok->session_key.decrypted_key, session_key, | 551 | memcpy(auth_tok->session_key.decrypted_key, session_key, |
@@ -546,6 +558,7 @@ static int decrypt_session_key(struct ecryptfs_auth_tok *auth_tok, | |||
546 | if (ecryptfs_verbosity > 0) | 558 | if (ecryptfs_verbosity > 0) |
547 | ecryptfs_dump_hex(crypt_stat->key, | 559 | ecryptfs_dump_hex(crypt_stat->key, |
548 | crypt_stat->key_size); | 560 | crypt_stat->key_size); |
561 | out_free_memory: | ||
549 | memset(encrypted_session_key, 0, PAGE_CACHE_SIZE); | 562 | memset(encrypted_session_key, 0, PAGE_CACHE_SIZE); |
550 | free_page((unsigned long)encrypted_session_key); | 563 | free_page((unsigned long)encrypted_session_key); |
551 | memset(session_key, 0, PAGE_CACHE_SIZE); | 564 | memset(session_key, 0, PAGE_CACHE_SIZE); |
@@ -554,7 +567,7 @@ out_free_tfm: | |||
554 | if (tfm_mutex) | 567 | if (tfm_mutex) |
555 | mutex_unlock(tfm_mutex); | 568 | mutex_unlock(tfm_mutex); |
556 | else | 569 | else |
557 | crypto_free_tfm(tfm); | 570 | crypto_free_blkcipher(desc.tfm); |
558 | out: | 571 | out: |
559 | return rc; | 572 | return rc; |
560 | } | 573 | } |
@@ -803,19 +816,21 @@ write_tag_3_packet(char *dest, size_t max, struct ecryptfs_auth_tok *auth_tok, | |||
803 | struct ecryptfs_crypt_stat *crypt_stat, | 816 | struct ecryptfs_crypt_stat *crypt_stat, |
804 | struct ecryptfs_key_record *key_rec, size_t *packet_size) | 817 | struct ecryptfs_key_record *key_rec, size_t *packet_size) |
805 | { | 818 | { |
806 | int rc = 0; | ||
807 | |||
808 | size_t i; | 819 | size_t i; |
809 | size_t signature_is_valid = 0; | 820 | size_t signature_is_valid = 0; |
810 | size_t encrypted_session_key_valid = 0; | 821 | size_t encrypted_session_key_valid = 0; |
811 | char session_key_encryption_key[ECRYPTFS_MAX_KEY_BYTES]; | 822 | char session_key_encryption_key[ECRYPTFS_MAX_KEY_BYTES]; |
812 | struct scatterlist dest_sg[2]; | 823 | struct scatterlist dest_sg[2]; |
813 | struct scatterlist src_sg[2]; | 824 | struct scatterlist src_sg[2]; |
814 | struct crypto_tfm *tfm = NULL; | ||
815 | struct mutex *tfm_mutex = NULL; | 825 | struct mutex *tfm_mutex = NULL; |
816 | size_t key_rec_size; | 826 | size_t key_rec_size; |
817 | size_t packet_size_length; | 827 | size_t packet_size_length; |
818 | size_t cipher_code; | 828 | size_t cipher_code; |
829 | struct blkcipher_desc desc = { | ||
830 | .tfm = NULL, | ||
831 | .flags = CRYPTO_TFM_REQ_MAY_SLEEP | ||
832 | }; | ||
833 | int rc = 0; | ||
819 | 834 | ||
820 | (*packet_size) = 0; | 835 | (*packet_size) = 0; |
821 | /* Check for a valid signature on the auth_tok */ | 836 | /* Check for a valid signature on the auth_tok */ |
@@ -882,33 +897,48 @@ write_tag_3_packet(char *dest, size_t max, struct ecryptfs_auth_tok *auth_tok, | |||
882 | if (!strcmp(crypt_stat->cipher, | 897 | if (!strcmp(crypt_stat->cipher, |
883 | crypt_stat->mount_crypt_stat->global_default_cipher_name) | 898 | crypt_stat->mount_crypt_stat->global_default_cipher_name) |
884 | && crypt_stat->mount_crypt_stat->global_key_tfm) { | 899 | && crypt_stat->mount_crypt_stat->global_key_tfm) { |
885 | tfm = crypt_stat->mount_crypt_stat->global_key_tfm; | 900 | desc.tfm = crypt_stat->mount_crypt_stat->global_key_tfm; |
886 | tfm_mutex = &crypt_stat->mount_crypt_stat->global_key_tfm_mutex; | 901 | tfm_mutex = &crypt_stat->mount_crypt_stat->global_key_tfm_mutex; |
887 | } else | 902 | } else { |
888 | tfm = crypto_alloc_tfm(crypt_stat->cipher, 0); | 903 | char *full_alg_name; |
889 | if (!tfm) { | 904 | |
890 | ecryptfs_printk(KERN_ERR, "Could not initialize crypto " | 905 | rc = ecryptfs_crypto_api_algify_cipher_name(&full_alg_name, |
891 | "context for cipher [%s]\n", | 906 | crypt_stat->cipher, |
892 | crypt_stat->cipher); | 907 | "ecb"); |
893 | rc = -EINVAL; | 908 | if (rc) |
894 | goto out; | 909 | goto out; |
910 | desc.tfm = crypto_alloc_blkcipher(full_alg_name, 0, | ||
911 | CRYPTO_ALG_ASYNC); | ||
912 | kfree(full_alg_name); | ||
913 | if (IS_ERR(desc.tfm)) { | ||
914 | rc = PTR_ERR(desc.tfm); | ||
915 | ecryptfs_printk(KERN_ERR, "Could not initialize crypto " | ||
916 | "context for cipher [%s]; rc = [%d]\n", | ||
917 | crypt_stat->cipher, rc); | ||
918 | goto out; | ||
919 | } | ||
920 | crypto_blkcipher_set_flags(desc.tfm, CRYPTO_TFM_REQ_WEAK_KEY); | ||
895 | } | 921 | } |
896 | if (tfm_mutex) | 922 | if (tfm_mutex) |
897 | mutex_lock(tfm_mutex); | 923 | mutex_lock(tfm_mutex); |
898 | rc = crypto_cipher_setkey(tfm, session_key_encryption_key, | 924 | rc = crypto_blkcipher_setkey(desc.tfm, session_key_encryption_key, |
899 | crypt_stat->key_size); | 925 | crypt_stat->key_size); |
900 | if (rc < 0) { | 926 | if (rc < 0) { |
901 | if (tfm_mutex) | 927 | if (tfm_mutex) |
902 | mutex_unlock(tfm_mutex); | 928 | mutex_unlock(tfm_mutex); |
903 | ecryptfs_printk(KERN_ERR, "Error setting key for crypto " | 929 | ecryptfs_printk(KERN_ERR, "Error setting key for crypto " |
904 | "context\n"); | 930 | "context; rc = [%d]\n", rc); |
905 | goto out; | 931 | goto out; |
906 | } | 932 | } |
907 | rc = 0; | 933 | rc = 0; |
908 | ecryptfs_printk(KERN_DEBUG, "Encrypting [%d] bytes of the key\n", | 934 | ecryptfs_printk(KERN_DEBUG, "Encrypting [%d] bytes of the key\n", |
909 | crypt_stat->key_size); | 935 | crypt_stat->key_size); |
910 | crypto_cipher_encrypt(tfm, dest_sg, src_sg, | 936 | rc = crypto_blkcipher_encrypt(&desc, dest_sg, src_sg, |
911 | (*key_rec).enc_key_size); | 937 | (*key_rec).enc_key_size); |
938 | if (rc) { | ||
939 | printk(KERN_ERR "Error encrypting; rc = [%d]\n", rc); | ||
940 | goto out; | ||
941 | } | ||
912 | if (tfm_mutex) | 942 | if (tfm_mutex) |
913 | mutex_unlock(tfm_mutex); | 943 | mutex_unlock(tfm_mutex); |
914 | ecryptfs_printk(KERN_DEBUG, "This should be the encrypted key:\n"); | 944 | ecryptfs_printk(KERN_DEBUG, "This should be the encrypted key:\n"); |
@@ -971,8 +1001,8 @@ encrypted_session_key_set: | |||
971 | (*key_rec).enc_key_size); | 1001 | (*key_rec).enc_key_size); |
972 | (*packet_size) += (*key_rec).enc_key_size; | 1002 | (*packet_size) += (*key_rec).enc_key_size; |
973 | out: | 1003 | out: |
974 | if (tfm && !tfm_mutex) | 1004 | if (desc.tfm && !tfm_mutex) |
975 | crypto_free_tfm(tfm); | 1005 | crypto_free_blkcipher(desc.tfm); |
976 | if (rc) | 1006 | if (rc) |
977 | (*packet_size) = 0; | 1007 | (*packet_size) = 0; |
978 | return rc; | 1008 | return rc; |
diff --git a/fs/ecryptfs/main.c b/fs/ecryptfs/main.c index 5938a232d11b..a78d87d14baf 100644 --- a/fs/ecryptfs/main.c +++ b/fs/ecryptfs/main.c | |||
@@ -208,7 +208,6 @@ static int ecryptfs_parse_options(struct super_block *sb, char *options) | |||
208 | char *cipher_name_dst; | 208 | char *cipher_name_dst; |
209 | char *cipher_name_src; | 209 | char *cipher_name_src; |
210 | char *cipher_key_bytes_src; | 210 | char *cipher_key_bytes_src; |
211 | struct crypto_tfm *tmp_tfm; | ||
212 | int cipher_name_len; | 211 | int cipher_name_len; |
213 | 212 | ||
214 | if (!options) { | 213 | if (!options) { |
@@ -305,25 +304,19 @@ static int ecryptfs_parse_options(struct super_block *sb, char *options) | |||
305 | = '\0'; | 304 | = '\0'; |
306 | } | 305 | } |
307 | if (!cipher_key_bytes_set) { | 306 | if (!cipher_key_bytes_set) { |
308 | mount_crypt_stat->global_default_cipher_key_size = | 307 | mount_crypt_stat->global_default_cipher_key_size = 0; |
309 | ECRYPTFS_DEFAULT_KEY_BYTES; | ||
310 | ecryptfs_printk(KERN_DEBUG, "Cipher key size was not " | ||
311 | "specified. Defaulting to [%d]\n", | ||
312 | mount_crypt_stat-> | ||
313 | global_default_cipher_key_size); | ||
314 | } | 308 | } |
315 | rc = ecryptfs_process_cipher( | 309 | rc = ecryptfs_process_cipher( |
316 | &tmp_tfm, | ||
317 | &mount_crypt_stat->global_key_tfm, | 310 | &mount_crypt_stat->global_key_tfm, |
318 | mount_crypt_stat->global_default_cipher_name, | 311 | mount_crypt_stat->global_default_cipher_name, |
319 | mount_crypt_stat->global_default_cipher_key_size); | 312 | &mount_crypt_stat->global_default_cipher_key_size); |
320 | if (tmp_tfm) | ||
321 | crypto_free_tfm(tmp_tfm); | ||
322 | if (rc) { | 313 | if (rc) { |
323 | printk(KERN_ERR "Error attempting to initialize cipher [%s] " | 314 | printk(KERN_ERR "Error attempting to initialize cipher [%s] " |
324 | "with key size [%Zd] bytes; rc = [%d]\n", | 315 | "with key size [%Zd] bytes; rc = [%d]\n", |
325 | mount_crypt_stat->global_default_cipher_name, | 316 | mount_crypt_stat->global_default_cipher_name, |
326 | mount_crypt_stat->global_default_cipher_key_size, rc); | 317 | mount_crypt_stat->global_default_cipher_key_size, rc); |
318 | mount_crypt_stat->global_key_tfm = NULL; | ||
319 | mount_crypt_stat->global_auth_tok_key = NULL; | ||
327 | rc = -EINVAL; | 320 | rc = -EINVAL; |
328 | goto out; | 321 | goto out; |
329 | } | 322 | } |
diff --git a/fs/ecryptfs/super.c b/fs/ecryptfs/super.c index c337c0410fb1..825757ae4867 100644 --- a/fs/ecryptfs/super.c +++ b/fs/ecryptfs/super.c | |||
@@ -138,23 +138,6 @@ static void ecryptfs_clear_inode(struct inode *inode) | |||
138 | } | 138 | } |
139 | 139 | ||
140 | /** | 140 | /** |
141 | * ecryptfs_umount_begin | ||
142 | * | ||
143 | * Called in do_umount(). | ||
144 | */ | ||
145 | static void ecryptfs_umount_begin(struct vfsmount *vfsmnt, int flags) | ||
146 | { | ||
147 | struct vfsmount *lower_mnt = | ||
148 | ecryptfs_dentry_to_lower_mnt(vfsmnt->mnt_sb->s_root); | ||
149 | struct super_block *lower_sb; | ||
150 | |||
151 | mntput(lower_mnt); | ||
152 | lower_sb = lower_mnt->mnt_sb; | ||
153 | if (lower_sb->s_op->umount_begin) | ||
154 | lower_sb->s_op->umount_begin(lower_mnt, flags); | ||
155 | } | ||
156 | |||
157 | /** | ||
158 | * ecryptfs_show_options | 141 | * ecryptfs_show_options |
159 | * | 142 | * |
160 | * Prints the directory we are currently mounted over. | 143 | * Prints the directory we are currently mounted over. |
@@ -193,6 +176,5 @@ struct super_operations ecryptfs_sops = { | |||
193 | .statfs = ecryptfs_statfs, | 176 | .statfs = ecryptfs_statfs, |
194 | .remount_fs = NULL, | 177 | .remount_fs = NULL, |
195 | .clear_inode = ecryptfs_clear_inode, | 178 | .clear_inode = ecryptfs_clear_inode, |
196 | .umount_begin = ecryptfs_umount_begin, | ||
197 | .show_options = ecryptfs_show_options | 179 | .show_options = ecryptfs_show_options |
198 | }; | 180 | }; |
diff --git a/fs/fuse/file.c b/fs/fuse/file.c index 2bb5ace3882d..763a50daf1c0 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c | |||
@@ -397,14 +397,14 @@ static int fuse_readpages(struct file *file, struct address_space *mapping, | |||
397 | 397 | ||
398 | err = -EIO; | 398 | err = -EIO; |
399 | if (is_bad_inode(inode)) | 399 | if (is_bad_inode(inode)) |
400 | goto clean_pages_up; | 400 | goto out; |
401 | 401 | ||
402 | data.file = file; | 402 | data.file = file; |
403 | data.inode = inode; | 403 | data.inode = inode; |
404 | data.req = fuse_get_req(fc); | 404 | data.req = fuse_get_req(fc); |
405 | err = PTR_ERR(data.req); | 405 | err = PTR_ERR(data.req); |
406 | if (IS_ERR(data.req)) | 406 | if (IS_ERR(data.req)) |
407 | goto clean_pages_up; | 407 | goto out; |
408 | 408 | ||
409 | err = read_cache_pages(mapping, pages, fuse_readpages_fill, &data); | 409 | err = read_cache_pages(mapping, pages, fuse_readpages_fill, &data); |
410 | if (!err) { | 410 | if (!err) { |
@@ -413,10 +413,7 @@ static int fuse_readpages(struct file *file, struct address_space *mapping, | |||
413 | else | 413 | else |
414 | fuse_put_request(fc, data.req); | 414 | fuse_put_request(fc, data.req); |
415 | } | 415 | } |
416 | return err; | 416 | out: |
417 | |||
418 | clean_pages_up: | ||
419 | put_pages_list(pages); | ||
420 | return err; | 417 | return err; |
421 | } | 418 | } |
422 | 419 | ||
diff --git a/fs/gfs2/ops_address.c b/fs/gfs2/ops_address.c index 8d5963c7e123..015640b3f123 100644 --- a/fs/gfs2/ops_address.c +++ b/fs/gfs2/ops_address.c | |||
@@ -337,13 +337,6 @@ out: | |||
337 | out_noerror: | 337 | out_noerror: |
338 | ret = 0; | 338 | ret = 0; |
339 | out_unlock: | 339 | out_unlock: |
340 | /* unlock all pages, we can't do any I/O right now */ | ||
341 | for (page_idx = 0; page_idx < nr_pages; page_idx++) { | ||
342 | struct page *page = list_entry(pages->prev, struct page, lru); | ||
343 | list_del(&page->lru); | ||
344 | unlock_page(page); | ||
345 | page_cache_release(page); | ||
346 | } | ||
347 | if (do_unlock) | 340 | if (do_unlock) |
348 | gfs2_holder_uninit(&gh); | 341 | gfs2_holder_uninit(&gh); |
349 | goto out; | 342 | goto out; |
diff --git a/fs/nfsd/nfs4recover.c b/fs/nfsd/nfs4recover.c index e9d07704680e..81b8565d3837 100644 --- a/fs/nfsd/nfs4recover.c +++ b/fs/nfsd/nfs4recover.c | |||
@@ -274,7 +274,7 @@ nfsd4_clear_clid_dir(struct dentry *dir, struct dentry *dentry) | |||
274 | * any regular files anyway, just in case the directory was created by | 274 | * any regular files anyway, just in case the directory was created by |
275 | * a kernel from the future.... */ | 275 | * a kernel from the future.... */ |
276 | nfsd4_list_rec_dir(dentry, nfsd4_remove_clid_file); | 276 | nfsd4_list_rec_dir(dentry, nfsd4_remove_clid_file); |
277 | mutex_lock(&dir->d_inode->i_mutex); | 277 | mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_PARENT); |
278 | status = vfs_rmdir(dir->d_inode, dentry); | 278 | status = vfs_rmdir(dir->d_inode, dentry); |
279 | mutex_unlock(&dir->d_inode->i_mutex); | 279 | mutex_unlock(&dir->d_inode->i_mutex); |
280 | return status; | 280 | return status; |
diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c index 9041802df832..17249994110f 100644 --- a/fs/reiserfs/super.c +++ b/fs/reiserfs/super.c | |||
@@ -1619,6 +1619,7 @@ static int reiserfs_fill_super(struct super_block *s, void *data, int silent) | |||
1619 | "jmacd-8: reiserfs_fill_super: unable to read bitmap"); | 1619 | "jmacd-8: reiserfs_fill_super: unable to read bitmap"); |
1620 | goto error; | 1620 | goto error; |
1621 | } | 1621 | } |
1622 | errval = -EINVAL; | ||
1622 | #ifdef CONFIG_REISERFS_CHECK | 1623 | #ifdef CONFIG_REISERFS_CHECK |
1623 | SWARN(silent, s, "CONFIG_REISERFS_CHECK is set ON"); | 1624 | SWARN(silent, s, "CONFIG_REISERFS_CHECK is set ON"); |
1624 | SWARN(silent, s, "- it is slow mode for debugging."); | 1625 | SWARN(silent, s, "- it is slow mode for debugging."); |
diff --git a/fs/xattr.c b/fs/xattr.c index 395635100f77..0901bdc2ce24 100644 --- a/fs/xattr.c +++ b/fs/xattr.c | |||
@@ -48,14 +48,21 @@ xattr_permission(struct inode *inode, const char *name, int mask) | |||
48 | return 0; | 48 | return 0; |
49 | 49 | ||
50 | /* | 50 | /* |
51 | * The trusted.* namespace can only accessed by a privilegued user. | 51 | * The trusted.* namespace can only be accessed by a privileged user. |
52 | */ | 52 | */ |
53 | if (!strncmp(name, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN)) | 53 | if (!strncmp(name, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN)) |
54 | return (capable(CAP_SYS_ADMIN) ? 0 : -EPERM); | 54 | return (capable(CAP_SYS_ADMIN) ? 0 : -EPERM); |
55 | 55 | ||
56 | /* In user.* namespace, only regular files and directories can have | ||
57 | * extended attributes. For sticky directories, only the owner and | ||
58 | * privileged user can write attributes. | ||
59 | */ | ||
56 | if (!strncmp(name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN)) { | 60 | if (!strncmp(name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN)) { |
57 | if (!S_ISREG(inode->i_mode) && | 61 | if (!S_ISREG(inode->i_mode) && !S_ISDIR(inode->i_mode)) |
58 | (!S_ISDIR(inode->i_mode) || inode->i_mode & S_ISVTX)) | 62 | return -EPERM; |
63 | if (S_ISDIR(inode->i_mode) && (inode->i_mode & S_ISVTX) && | ||
64 | (mask & MAY_WRITE) && (current->fsuid != inode->i_uid) && | ||
65 | !capable(CAP_FOWNER)) | ||
59 | return -EPERM; | 66 | return -EPERM; |
60 | } | 67 | } |
61 | 68 | ||