diff options
Diffstat (limited to 'fs/ecryptfs/main.c')
| -rw-r--r-- | fs/ecryptfs/main.c | 83 |
1 files changed, 35 insertions, 48 deletions
diff --git a/fs/ecryptfs/main.c b/fs/ecryptfs/main.c index d603631601eb..448dfd597b5f 100644 --- a/fs/ecryptfs/main.c +++ b/fs/ecryptfs/main.c | |||
| @@ -117,7 +117,7 @@ void __ecryptfs_printk(const char *fmt, ...) | |||
| 117 | * | 117 | * |
| 118 | * Returns zero on success; non-zero otherwise | 118 | * Returns zero on success; non-zero otherwise |
| 119 | */ | 119 | */ |
| 120 | static int ecryptfs_init_persistent_file(struct dentry *ecryptfs_dentry) | 120 | int ecryptfs_init_persistent_file(struct dentry *ecryptfs_dentry) |
| 121 | { | 121 | { |
| 122 | struct ecryptfs_inode_info *inode_info = | 122 | struct ecryptfs_inode_info *inode_info = |
| 123 | ecryptfs_inode_to_private(ecryptfs_dentry->d_inode); | 123 | ecryptfs_inode_to_private(ecryptfs_dentry->d_inode); |
| @@ -130,26 +130,12 @@ static int ecryptfs_init_persistent_file(struct dentry *ecryptfs_dentry) | |||
| 130 | ecryptfs_dentry_to_lower_mnt(ecryptfs_dentry); | 130 | ecryptfs_dentry_to_lower_mnt(ecryptfs_dentry); |
| 131 | 131 | ||
| 132 | lower_dentry = ecryptfs_dentry_to_lower(ecryptfs_dentry); | 132 | lower_dentry = ecryptfs_dentry_to_lower(ecryptfs_dentry); |
| 133 | /* Corresponding dput() and mntput() are done when the | 133 | rc = ecryptfs_privileged_open(&inode_info->lower_file, |
| 134 | * persistent file is fput() when the eCryptfs inode | 134 | lower_dentry, lower_mnt); |
| 135 | * is destroyed. */ | 135 | if (rc || IS_ERR(inode_info->lower_file)) { |
| 136 | dget(lower_dentry); | ||
| 137 | mntget(lower_mnt); | ||
| 138 | inode_info->lower_file = dentry_open(lower_dentry, | ||
| 139 | lower_mnt, | ||
| 140 | (O_RDWR | O_LARGEFILE)); | ||
| 141 | if (IS_ERR(inode_info->lower_file)) { | ||
| 142 | dget(lower_dentry); | ||
| 143 | mntget(lower_mnt); | ||
| 144 | inode_info->lower_file = dentry_open(lower_dentry, | ||
| 145 | lower_mnt, | ||
| 146 | (O_RDONLY | ||
| 147 | | O_LARGEFILE)); | ||
| 148 | } | ||
| 149 | if (IS_ERR(inode_info->lower_file)) { | ||
| 150 | printk(KERN_ERR "Error opening lower persistent file " | 136 | printk(KERN_ERR "Error opening lower persistent file " |
| 151 | "for lower_dentry [0x%p] and lower_mnt [0x%p]\n", | 137 | "for lower_dentry [0x%p] and lower_mnt [0x%p]; " |
| 152 | lower_dentry, lower_mnt); | 138 | "rc = [%d]\n", lower_dentry, lower_mnt, rc); |
| 153 | rc = PTR_ERR(inode_info->lower_file); | 139 | rc = PTR_ERR(inode_info->lower_file); |
| 154 | inode_info->lower_file = NULL; | 140 | inode_info->lower_file = NULL; |
| 155 | } | 141 | } |
| @@ -163,14 +149,14 @@ static int ecryptfs_init_persistent_file(struct dentry *ecryptfs_dentry) | |||
| 163 | * @lower_dentry: Existing dentry in the lower filesystem | 149 | * @lower_dentry: Existing dentry in the lower filesystem |
| 164 | * @dentry: ecryptfs' dentry | 150 | * @dentry: ecryptfs' dentry |
| 165 | * @sb: ecryptfs's super_block | 151 | * @sb: ecryptfs's super_block |
| 166 | * @flag: If set to true, then d_add is called, else d_instantiate is called | 152 | * @flags: flags to govern behavior of interpose procedure |
| 167 | * | 153 | * |
| 168 | * Interposes upper and lower dentries. | 154 | * Interposes upper and lower dentries. |
| 169 | * | 155 | * |
| 170 | * Returns zero on success; non-zero otherwise | 156 | * Returns zero on success; non-zero otherwise |
| 171 | */ | 157 | */ |
| 172 | int ecryptfs_interpose(struct dentry *lower_dentry, struct dentry *dentry, | 158 | int ecryptfs_interpose(struct dentry *lower_dentry, struct dentry *dentry, |
| 173 | struct super_block *sb, int flag) | 159 | struct super_block *sb, u32 flags) |
| 174 | { | 160 | { |
| 175 | struct inode *lower_inode; | 161 | struct inode *lower_inode; |
| 176 | struct inode *inode; | 162 | struct inode *inode; |
| @@ -207,7 +193,7 @@ int ecryptfs_interpose(struct dentry *lower_dentry, struct dentry *dentry, | |||
| 207 | init_special_inode(inode, lower_inode->i_mode, | 193 | init_special_inode(inode, lower_inode->i_mode, |
| 208 | lower_inode->i_rdev); | 194 | lower_inode->i_rdev); |
| 209 | dentry->d_op = &ecryptfs_dops; | 195 | dentry->d_op = &ecryptfs_dops; |
| 210 | if (flag) | 196 | if (flags & ECRYPTFS_INTERPOSE_FLAG_D_ADD) |
| 211 | d_add(dentry, inode); | 197 | d_add(dentry, inode); |
| 212 | else | 198 | else |
| 213 | d_instantiate(dentry, inode); | 199 | d_instantiate(dentry, inode); |
| @@ -215,13 +201,6 @@ int ecryptfs_interpose(struct dentry *lower_dentry, struct dentry *dentry, | |||
| 215 | /* This size will be overwritten for real files w/ headers and | 201 | /* This size will be overwritten for real files w/ headers and |
| 216 | * other metadata */ | 202 | * other metadata */ |
| 217 | fsstack_copy_inode_size(inode, lower_inode); | 203 | fsstack_copy_inode_size(inode, lower_inode); |
| 218 | rc = ecryptfs_init_persistent_file(dentry); | ||
| 219 | if (rc) { | ||
| 220 | printk(KERN_ERR "%s: Error attempting to initialize the " | ||
| 221 | "persistent file for the dentry with name [%s]; " | ||
| 222 | "rc = [%d]\n", __func__, dentry->d_name.name, rc); | ||
| 223 | goto out; | ||
| 224 | } | ||
| 225 | out: | 204 | out: |
| 226 | return rc; | 205 | return rc; |
| 227 | } | 206 | } |
| @@ -262,10 +241,11 @@ static int ecryptfs_init_global_auth_toks( | |||
| 262 | "session keyring for sig specified in mount " | 241 | "session keyring for sig specified in mount " |
| 263 | "option: [%s]\n", global_auth_tok->sig); | 242 | "option: [%s]\n", global_auth_tok->sig); |
| 264 | global_auth_tok->flags |= ECRYPTFS_AUTH_TOK_INVALID; | 243 | global_auth_tok->flags |= ECRYPTFS_AUTH_TOK_INVALID; |
| 265 | rc = 0; | 244 | goto out; |
| 266 | } else | 245 | } else |
| 267 | global_auth_tok->flags &= ~ECRYPTFS_AUTH_TOK_INVALID; | 246 | global_auth_tok->flags &= ~ECRYPTFS_AUTH_TOK_INVALID; |
| 268 | } | 247 | } |
| 248 | out: | ||
| 269 | return rc; | 249 | return rc; |
| 270 | } | 250 | } |
| 271 | 251 | ||
| @@ -314,7 +294,6 @@ static int ecryptfs_parse_options(struct super_block *sb, char *options) | |||
| 314 | char *cipher_name_dst; | 294 | char *cipher_name_dst; |
| 315 | char *cipher_name_src; | 295 | char *cipher_name_src; |
| 316 | char *cipher_key_bytes_src; | 296 | char *cipher_key_bytes_src; |
| 317 | int cipher_name_len; | ||
| 318 | 297 | ||
| 319 | if (!options) { | 298 | if (!options) { |
| 320 | rc = -EINVAL; | 299 | rc = -EINVAL; |
| @@ -395,17 +374,12 @@ static int ecryptfs_parse_options(struct super_block *sb, char *options) | |||
| 395 | goto out; | 374 | goto out; |
| 396 | } | 375 | } |
| 397 | if (!cipher_name_set) { | 376 | if (!cipher_name_set) { |
| 398 | cipher_name_len = strlen(ECRYPTFS_DEFAULT_CIPHER); | 377 | int cipher_name_len = strlen(ECRYPTFS_DEFAULT_CIPHER); |
| 399 | if (unlikely(cipher_name_len | 378 | |
| 400 | >= ECRYPTFS_MAX_CIPHER_NAME_SIZE)) { | 379 | BUG_ON(cipher_name_len >= ECRYPTFS_MAX_CIPHER_NAME_SIZE); |
| 401 | rc = -EINVAL; | 380 | |
| 402 | BUG(); | 381 | strcpy(mount_crypt_stat->global_default_cipher_name, |
| 403 | goto out; | 382 | ECRYPTFS_DEFAULT_CIPHER); |
| 404 | } | ||
| 405 | memcpy(mount_crypt_stat->global_default_cipher_name, | ||
| 406 | ECRYPTFS_DEFAULT_CIPHER, cipher_name_len); | ||
| 407 | mount_crypt_stat->global_default_cipher_name[cipher_name_len] | ||
| 408 | = '\0'; | ||
| 409 | } | 383 | } |
| 410 | if (!cipher_key_bytes_set) { | 384 | if (!cipher_key_bytes_set) { |
| 411 | mount_crypt_stat->global_default_cipher_key_size = 0; | 385 | mount_crypt_stat->global_default_cipher_key_size = 0; |
| @@ -430,7 +404,6 @@ static int ecryptfs_parse_options(struct super_block *sb, char *options) | |||
| 430 | printk(KERN_WARNING "One or more global auth toks could not " | 404 | printk(KERN_WARNING "One or more global auth toks could not " |
| 431 | "properly register; rc = [%d]\n", rc); | 405 | "properly register; rc = [%d]\n", rc); |
| 432 | } | 406 | } |
| 433 | rc = 0; | ||
| 434 | out: | 407 | out: |
| 435 | return rc; | 408 | return rc; |
| 436 | } | 409 | } |
| @@ -605,7 +578,7 @@ static struct file_system_type ecryptfs_fs_type = { | |||
| 605 | * Initializes the ecryptfs_inode_info_cache when it is created | 578 | * Initializes the ecryptfs_inode_info_cache when it is created |
| 606 | */ | 579 | */ |
| 607 | static void | 580 | static void |
| 608 | inode_info_init_once(struct kmem_cache *cachep, void *vptr) | 581 | inode_info_init_once(void *vptr) |
| 609 | { | 582 | { |
| 610 | struct ecryptfs_inode_info *ei = (struct ecryptfs_inode_info *)vptr; | 583 | struct ecryptfs_inode_info *ei = (struct ecryptfs_inode_info *)vptr; |
| 611 | 584 | ||
| @@ -616,7 +589,7 @@ static struct ecryptfs_cache_info { | |||
| 616 | struct kmem_cache **cache; | 589 | struct kmem_cache **cache; |
| 617 | const char *name; | 590 | const char *name; |
| 618 | size_t size; | 591 | size_t size; |
| 619 | void (*ctor)(struct kmem_cache *cache, void *obj); | 592 | void (*ctor)(void *obj); |
| 620 | } ecryptfs_cache_infos[] = { | 593 | } ecryptfs_cache_infos[] = { |
| 621 | { | 594 | { |
| 622 | .cache = &ecryptfs_auth_tok_list_item_cache, | 595 | .cache = &ecryptfs_auth_tok_list_item_cache, |
| @@ -679,6 +652,11 @@ static struct ecryptfs_cache_info { | |||
| 679 | .name = "ecryptfs_key_tfm_cache", | 652 | .name = "ecryptfs_key_tfm_cache", |
| 680 | .size = sizeof(struct ecryptfs_key_tfm), | 653 | .size = sizeof(struct ecryptfs_key_tfm), |
| 681 | }, | 654 | }, |
| 655 | { | ||
| 656 | .cache = &ecryptfs_open_req_cache, | ||
| 657 | .name = "ecryptfs_open_req_cache", | ||
| 658 | .size = sizeof(struct ecryptfs_open_req), | ||
| 659 | }, | ||
| 682 | }; | 660 | }; |
| 683 | 661 | ||
| 684 | static void ecryptfs_free_kmem_caches(void) | 662 | static void ecryptfs_free_kmem_caches(void) |
| @@ -795,11 +773,17 @@ static int __init ecryptfs_init(void) | |||
| 795 | printk(KERN_ERR "sysfs registration failed\n"); | 773 | printk(KERN_ERR "sysfs registration failed\n"); |
| 796 | goto out_unregister_filesystem; | 774 | goto out_unregister_filesystem; |
| 797 | } | 775 | } |
| 776 | rc = ecryptfs_init_kthread(); | ||
| 777 | if (rc) { | ||
| 778 | printk(KERN_ERR "%s: kthread initialization failed; " | ||
| 779 | "rc = [%d]\n", __func__, rc); | ||
| 780 | goto out_do_sysfs_unregistration; | ||
| 781 | } | ||
| 798 | rc = ecryptfs_init_messaging(ecryptfs_transport); | 782 | rc = ecryptfs_init_messaging(ecryptfs_transport); |
| 799 | if (rc) { | 783 | if (rc) { |
| 800 | ecryptfs_printk(KERN_ERR, "Failure occured while attempting to " | 784 | printk(KERN_ERR "Failure occured while attempting to " |
| 801 | "initialize the eCryptfs netlink socket\n"); | 785 | "initialize the eCryptfs netlink socket\n"); |
| 802 | goto out_do_sysfs_unregistration; | 786 | goto out_destroy_kthread; |
| 803 | } | 787 | } |
| 804 | rc = ecryptfs_init_crypto(); | 788 | rc = ecryptfs_init_crypto(); |
| 805 | if (rc) { | 789 | if (rc) { |
| @@ -814,6 +798,8 @@ static int __init ecryptfs_init(void) | |||
| 814 | goto out; | 798 | goto out; |
| 815 | out_release_messaging: | 799 | out_release_messaging: |
| 816 | ecryptfs_release_messaging(ecryptfs_transport); | 800 | ecryptfs_release_messaging(ecryptfs_transport); |
| 801 | out_destroy_kthread: | ||
| 802 | ecryptfs_destroy_kthread(); | ||
| 817 | out_do_sysfs_unregistration: | 803 | out_do_sysfs_unregistration: |
| 818 | do_sysfs_unregistration(); | 804 | do_sysfs_unregistration(); |
| 819 | out_unregister_filesystem: | 805 | out_unregister_filesystem: |
| @@ -833,6 +819,7 @@ static void __exit ecryptfs_exit(void) | |||
| 833 | printk(KERN_ERR "Failure whilst attempting to destroy crypto; " | 819 | printk(KERN_ERR "Failure whilst attempting to destroy crypto; " |
| 834 | "rc = [%d]\n", rc); | 820 | "rc = [%d]\n", rc); |
| 835 | ecryptfs_release_messaging(ecryptfs_transport); | 821 | ecryptfs_release_messaging(ecryptfs_transport); |
| 822 | ecryptfs_destroy_kthread(); | ||
| 836 | do_sysfs_unregistration(); | 823 | do_sysfs_unregistration(); |
| 837 | unregister_filesystem(&ecryptfs_fs_type); | 824 | unregister_filesystem(&ecryptfs_fs_type); |
| 838 | ecryptfs_free_kmem_caches(); | 825 | ecryptfs_free_kmem_caches(); |
