diff options
Diffstat (limited to 'fs/ecryptfs/main.c')
-rw-r--r-- | fs/ecryptfs/main.c | 82 |
1 files changed, 71 insertions, 11 deletions
diff --git a/fs/ecryptfs/main.c b/fs/ecryptfs/main.c index d0541ae8faba..26fe405a5763 100644 --- a/fs/ecryptfs/main.c +++ b/fs/ecryptfs/main.c | |||
@@ -3,9 +3,10 @@ | |||
3 | * | 3 | * |
4 | * Copyright (C) 1997-2003 Erez Zadok | 4 | * Copyright (C) 1997-2003 Erez Zadok |
5 | * Copyright (C) 2001-2003 Stony Brook University | 5 | * Copyright (C) 2001-2003 Stony Brook University |
6 | * Copyright (C) 2004-2006 International Business Machines Corp. | 6 | * Copyright (C) 2004-2007 International Business Machines Corp. |
7 | * Author(s): Michael A. Halcrow <mahalcro@us.ibm.com> | 7 | * Author(s): Michael A. Halcrow <mahalcro@us.ibm.com> |
8 | * Michael C. Thompson <mcthomps@us.ibm.com> | 8 | * Michael C. Thompson <mcthomps@us.ibm.com> |
9 | * Tyler Hicks <tyhicks@ou.edu> | ||
9 | * | 10 | * |
10 | * This program is free software; you can redistribute it and/or | 11 | * This program is free software; you can redistribute it and/or |
11 | * modify it under the terms of the GNU General Public License as | 12 | * modify it under the terms of the GNU General Public License as |
@@ -48,6 +49,43 @@ MODULE_PARM_DESC(ecryptfs_verbosity, | |||
48 | "Initial verbosity level (0 or 1; defaults to " | 49 | "Initial verbosity level (0 or 1; defaults to " |
49 | "0, which is Quiet)"); | 50 | "0, which is Quiet)"); |
50 | 51 | ||
52 | /** | ||
53 | * Module parameter that defines the number of netlink message buffer | ||
54 | * elements | ||
55 | */ | ||
56 | unsigned int ecryptfs_message_buf_len = ECRYPTFS_DEFAULT_MSG_CTX_ELEMS; | ||
57 | |||
58 | module_param(ecryptfs_message_buf_len, uint, 0); | ||
59 | MODULE_PARM_DESC(ecryptfs_message_buf_len, | ||
60 | "Number of message buffer elements"); | ||
61 | |||
62 | /** | ||
63 | * Module parameter that defines the maximum guaranteed amount of time to wait | ||
64 | * for a response through netlink. The actual sleep time will be, more than | ||
65 | * likely, a small amount greater than this specified value, but only less if | ||
66 | * the netlink message successfully arrives. | ||
67 | */ | ||
68 | signed long ecryptfs_message_wait_timeout = ECRYPTFS_MAX_MSG_CTX_TTL / HZ; | ||
69 | |||
70 | module_param(ecryptfs_message_wait_timeout, long, 0); | ||
71 | MODULE_PARM_DESC(ecryptfs_message_wait_timeout, | ||
72 | "Maximum number of seconds that an operation will " | ||
73 | "sleep while waiting for a message response from " | ||
74 | "userspace"); | ||
75 | |||
76 | /** | ||
77 | * Module parameter that is an estimate of the maximum number of users | ||
78 | * that will be concurrently using eCryptfs. Set this to the right | ||
79 | * value to balance performance and memory use. | ||
80 | */ | ||
81 | unsigned int ecryptfs_number_of_users = ECRYPTFS_DEFAULT_NUM_USERS; | ||
82 | |||
83 | module_param(ecryptfs_number_of_users, uint, 0); | ||
84 | MODULE_PARM_DESC(ecryptfs_number_of_users, "An estimate of the number of " | ||
85 | "concurrent users of eCryptfs"); | ||
86 | |||
87 | unsigned int ecryptfs_transport = ECRYPTFS_DEFAULT_TRANSPORT; | ||
88 | |||
51 | void __ecryptfs_printk(const char *fmt, ...) | 89 | void __ecryptfs_printk(const char *fmt, ...) |
52 | { | 90 | { |
53 | va_list args; | 91 | va_list args; |
@@ -124,7 +162,8 @@ out: | |||
124 | enum { ecryptfs_opt_sig, ecryptfs_opt_ecryptfs_sig, ecryptfs_opt_debug, | 162 | enum { ecryptfs_opt_sig, ecryptfs_opt_ecryptfs_sig, ecryptfs_opt_debug, |
125 | ecryptfs_opt_ecryptfs_debug, ecryptfs_opt_cipher, | 163 | ecryptfs_opt_ecryptfs_debug, ecryptfs_opt_cipher, |
126 | ecryptfs_opt_ecryptfs_cipher, ecryptfs_opt_ecryptfs_key_bytes, | 164 | ecryptfs_opt_ecryptfs_cipher, ecryptfs_opt_ecryptfs_key_bytes, |
127 | ecryptfs_opt_passthrough, ecryptfs_opt_err }; | 165 | ecryptfs_opt_passthrough, ecryptfs_opt_xattr_metadata, |
166 | ecryptfs_opt_encrypted_view, ecryptfs_opt_err }; | ||
128 | 167 | ||
129 | static match_table_t tokens = { | 168 | static match_table_t tokens = { |
130 | {ecryptfs_opt_sig, "sig=%s"}, | 169 | {ecryptfs_opt_sig, "sig=%s"}, |
@@ -135,6 +174,8 @@ static match_table_t tokens = { | |||
135 | {ecryptfs_opt_ecryptfs_cipher, "ecryptfs_cipher=%s"}, | 174 | {ecryptfs_opt_ecryptfs_cipher, "ecryptfs_cipher=%s"}, |
136 | {ecryptfs_opt_ecryptfs_key_bytes, "ecryptfs_key_bytes=%u"}, | 175 | {ecryptfs_opt_ecryptfs_key_bytes, "ecryptfs_key_bytes=%u"}, |
137 | {ecryptfs_opt_passthrough, "ecryptfs_passthrough"}, | 176 | {ecryptfs_opt_passthrough, "ecryptfs_passthrough"}, |
177 | {ecryptfs_opt_xattr_metadata, "ecryptfs_xattr_metadata"}, | ||
178 | {ecryptfs_opt_encrypted_view, "ecryptfs_encrypted_view"}, | ||
138 | {ecryptfs_opt_err, NULL} | 179 | {ecryptfs_opt_err, NULL} |
139 | }; | 180 | }; |
140 | 181 | ||
@@ -275,6 +316,16 @@ static int ecryptfs_parse_options(struct super_block *sb, char *options) | |||
275 | mount_crypt_stat->flags |= | 316 | mount_crypt_stat->flags |= |
276 | ECRYPTFS_PLAINTEXT_PASSTHROUGH_ENABLED; | 317 | ECRYPTFS_PLAINTEXT_PASSTHROUGH_ENABLED; |
277 | break; | 318 | break; |
319 | case ecryptfs_opt_xattr_metadata: | ||
320 | mount_crypt_stat->flags |= | ||
321 | ECRYPTFS_XATTR_METADATA_ENABLED; | ||
322 | break; | ||
323 | case ecryptfs_opt_encrypted_view: | ||
324 | mount_crypt_stat->flags |= | ||
325 | ECRYPTFS_XATTR_METADATA_ENABLED; | ||
326 | mount_crypt_stat->flags |= | ||
327 | ECRYPTFS_ENCRYPTED_VIEW_ENABLED; | ||
328 | break; | ||
278 | case ecryptfs_opt_err: | 329 | case ecryptfs_opt_err: |
279 | default: | 330 | default: |
280 | ecryptfs_printk(KERN_WARNING, | 331 | ecryptfs_printk(KERN_WARNING, |
@@ -347,9 +398,10 @@ static int ecryptfs_parse_options(struct super_block *sb, char *options) | |||
347 | rc = -EINVAL; | 398 | rc = -EINVAL; |
348 | goto out; | 399 | goto out; |
349 | } | 400 | } |
350 | if (auth_tok->token_type != ECRYPTFS_PASSWORD) { | 401 | if (auth_tok->token_type != ECRYPTFS_PASSWORD |
402 | && auth_tok->token_type != ECRYPTFS_PRIVATE_KEY) { | ||
351 | ecryptfs_printk(KERN_ERR, "Invalid auth_tok structure " | 403 | ecryptfs_printk(KERN_ERR, "Invalid auth_tok structure " |
352 | "returned from key\n"); | 404 | "returned from key query\n"); |
353 | rc = -EINVAL; | 405 | rc = -EINVAL; |
354 | goto out; | 406 | goto out; |
355 | } | 407 | } |
@@ -378,15 +430,13 @@ ecryptfs_fill_super(struct super_block *sb, void *raw_data, int silent) | |||
378 | 430 | ||
379 | /* Released in ecryptfs_put_super() */ | 431 | /* Released in ecryptfs_put_super() */ |
380 | ecryptfs_set_superblock_private(sb, | 432 | ecryptfs_set_superblock_private(sb, |
381 | kmem_cache_alloc(ecryptfs_sb_info_cache, | 433 | kmem_cache_zalloc(ecryptfs_sb_info_cache, |
382 | GFP_KERNEL)); | 434 | GFP_KERNEL)); |
383 | if (!ecryptfs_superblock_to_private(sb)) { | 435 | if (!ecryptfs_superblock_to_private(sb)) { |
384 | ecryptfs_printk(KERN_WARNING, "Out of memory\n"); | 436 | ecryptfs_printk(KERN_WARNING, "Out of memory\n"); |
385 | rc = -ENOMEM; | 437 | rc = -ENOMEM; |
386 | goto out; | 438 | goto out; |
387 | } | 439 | } |
388 | memset(ecryptfs_superblock_to_private(sb), 0, | ||
389 | sizeof(struct ecryptfs_sb_info)); | ||
390 | sb->s_op = &ecryptfs_sops; | 440 | sb->s_op = &ecryptfs_sops; |
391 | /* Released through deactivate_super(sb) from get_sb_nodev */ | 441 | /* Released through deactivate_super(sb) from get_sb_nodev */ |
392 | sb->s_root = d_alloc(NULL, &(const struct qstr) { | 442 | sb->s_root = d_alloc(NULL, &(const struct qstr) { |
@@ -402,7 +452,7 @@ ecryptfs_fill_super(struct super_block *sb, void *raw_data, int silent) | |||
402 | /* Released in d_release when dput(sb->s_root) is called */ | 452 | /* Released in d_release when dput(sb->s_root) is called */ |
403 | /* through deactivate_super(sb) from get_sb_nodev() */ | 453 | /* through deactivate_super(sb) from get_sb_nodev() */ |
404 | ecryptfs_set_dentry_private(sb->s_root, | 454 | ecryptfs_set_dentry_private(sb->s_root, |
405 | kmem_cache_alloc(ecryptfs_dentry_info_cache, | 455 | kmem_cache_zalloc(ecryptfs_dentry_info_cache, |
406 | GFP_KERNEL)); | 456 | GFP_KERNEL)); |
407 | if (!ecryptfs_dentry_to_private(sb->s_root)) { | 457 | if (!ecryptfs_dentry_to_private(sb->s_root)) { |
408 | ecryptfs_printk(KERN_ERR, | 458 | ecryptfs_printk(KERN_ERR, |
@@ -410,8 +460,6 @@ ecryptfs_fill_super(struct super_block *sb, void *raw_data, int silent) | |||
410 | rc = -ENOMEM; | 460 | rc = -ENOMEM; |
411 | goto out; | 461 | goto out; |
412 | } | 462 | } |
413 | memset(ecryptfs_dentry_to_private(sb->s_root), 0, | ||
414 | sizeof(struct ecryptfs_dentry_info)); | ||
415 | rc = 0; | 463 | rc = 0; |
416 | out: | 464 | out: |
417 | /* Should be able to rely on deactivate_super called from | 465 | /* Should be able to rely on deactivate_super called from |
@@ -594,6 +642,11 @@ static struct ecryptfs_cache_info { | |||
594 | .size = PAGE_CACHE_SIZE, | 642 | .size = PAGE_CACHE_SIZE, |
595 | }, | 643 | }, |
596 | { | 644 | { |
645 | .cache = &ecryptfs_xattr_cache, | ||
646 | .name = "ecryptfs_xattr_cache", | ||
647 | .size = PAGE_CACHE_SIZE, | ||
648 | }, | ||
649 | { | ||
597 | .cache = &ecryptfs_lower_page_cache, | 650 | .cache = &ecryptfs_lower_page_cache, |
598 | .name = "ecryptfs_lower_page_cache", | 651 | .name = "ecryptfs_lower_page_cache", |
599 | .size = PAGE_CACHE_SIZE, | 652 | .size = PAGE_CACHE_SIZE, |
@@ -699,7 +752,8 @@ static struct ecryptfs_version_str_map_elem { | |||
699 | {ECRYPTFS_VERSIONING_PASSPHRASE, "passphrase"}, | 752 | {ECRYPTFS_VERSIONING_PASSPHRASE, "passphrase"}, |
700 | {ECRYPTFS_VERSIONING_PUBKEY, "pubkey"}, | 753 | {ECRYPTFS_VERSIONING_PUBKEY, "pubkey"}, |
701 | {ECRYPTFS_VERSIONING_PLAINTEXT_PASSTHROUGH, "plaintext passthrough"}, | 754 | {ECRYPTFS_VERSIONING_PLAINTEXT_PASSTHROUGH, "plaintext passthrough"}, |
702 | {ECRYPTFS_VERSIONING_POLICY, "policy"} | 755 | {ECRYPTFS_VERSIONING_POLICY, "policy"}, |
756 | {ECRYPTFS_VERSIONING_XATTR, "metadata in extended attribute"} | ||
703 | }; | 757 | }; |
704 | 758 | ||
705 | static ssize_t version_str_show(struct ecryptfs_obj *obj, char *buff) | 759 | static ssize_t version_str_show(struct ecryptfs_obj *obj, char *buff) |
@@ -798,6 +852,11 @@ static int __init ecryptfs_init(void) | |||
798 | ecryptfs_free_kmem_caches(); | 852 | ecryptfs_free_kmem_caches(); |
799 | goto out; | 853 | goto out; |
800 | } | 854 | } |
855 | rc = ecryptfs_init_messaging(ecryptfs_transport); | ||
856 | if (rc) { | ||
857 | ecryptfs_printk(KERN_ERR, "Failure occured while attempting to " | ||
858 | "initialize the eCryptfs netlink socket\n"); | ||
859 | } | ||
801 | out: | 860 | out: |
802 | return rc; | 861 | return rc; |
803 | } | 862 | } |
@@ -809,6 +868,7 @@ static void __exit ecryptfs_exit(void) | |||
809 | sysfs_remove_file(&ecryptfs_subsys.kset.kobj, | 868 | sysfs_remove_file(&ecryptfs_subsys.kset.kobj, |
810 | &sysfs_attr_version_str.attr); | 869 | &sysfs_attr_version_str.attr); |
811 | subsystem_unregister(&ecryptfs_subsys); | 870 | subsystem_unregister(&ecryptfs_subsys); |
871 | ecryptfs_release_messaging(ecryptfs_transport); | ||
812 | unregister_filesystem(&ecryptfs_fs_type); | 872 | unregister_filesystem(&ecryptfs_fs_type); |
813 | ecryptfs_free_kmem_caches(); | 873 | ecryptfs_free_kmem_caches(); |
814 | } | 874 | } |