aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Halcrow <mhalcrow@us.ibm.com>2007-02-12 03:53:45 -0500
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-02-12 12:48:36 -0500
commit17398957aa0a05ef62535060b41d103590dcc533 (patch)
treebfb1d65281863811ad46d54f82e52e8924df3284
parentdddfa461fc8951f9b5f951c13565b6cac678635a (diff)
[PATCH] eCryptfs: xattr flags and mount options
This patch set introduces the ability to store cryptographic metadata into an lower file extended attribute rather than the lower file header region. This patch set implements two new mount options: ecryptfs_xattr_metadata - When set, newly created files will have their cryptographic metadata stored in the extended attribute region of the file rather than the header. When storing the data in the file header, there is a minimum of 8KB reserved for the header information for each file, making each file at least 12KB in size. This can take up a lot of extra disk space if the user creates a lot of small files. By storing the data in the extended attribute, each file will only occupy at least of 4KB of space. As the eCryptfs metadata set becomes larger with new features such as multi-key associations, most popular filesystems will not be able to store all of the information in the xattr region in some cases due to space constraints. However, the majority of users will only ever associate one key per file, so most users will be okay with storing their data in the xattr region. This option should be used with caution. I want to emphasize that the xattr must be maintained under all circumstances, or the file will be rendered permanently unrecoverable. The last thing I want is for a user to forget to set an xattr flag in a backup utility, only to later discover that their backups are worthless. ecryptfs_encrypted_view - When set, this option causes eCryptfs to present applications a view of encrypted files as if the cryptographic metadata were stored in the file header, whether the metadata is actually stored in the header or in the extended attributes. No matter what eCryptfs winds up doing in the lower filesystem, I want to preserve a baseline format compatibility for the encrypted files. As of right now, the metadata may be in the file header or in an xattr. There is no reason why the metadata could not be put in a separate file in future versions. Without the compatibility mode, backup utilities would have to know to back up the metadata file along with the files. The semantics of eCryptfs have always been that the lower files are self-contained units of encrypted data, and the only additional information required to decrypt any given eCryptfs file is the key. That is what has always been emphasized about eCryptfs lower files, and that is what users expect. Providing the encrypted view option will provide a way to userspace applications wherein they can always get to the same old familiar eCryptfs encrypted files, regardless of what eCryptfs winds up doing with the metadata behind the scenes. This patch: Add extended attribute support to version bit vector, flags to indicate when xattr or encrypted view modes are enabled, and support for the new mount options. Signed-off-by: Michael Halcrow <mhalcrow@us.ibm.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--fs/ecryptfs/crypto.c20
-rw-r--r--fs/ecryptfs/ecryptfs_kernel.h15
-rw-r--r--fs/ecryptfs/main.c18
3 files changed, 46 insertions, 7 deletions
diff --git a/fs/ecryptfs/crypto.c b/fs/ecryptfs/crypto.c
index 75bbfae55081..6d85aabb0179 100644
--- a/fs/ecryptfs/crypto.c
+++ b/fs/ecryptfs/crypto.c
@@ -915,6 +915,22 @@ static void ecryptfs_generate_new_key(struct ecryptfs_crypt_stat *crypt_stat)
915} 915}
916 916
917/** 917/**
918 * ecryptfs_copy_mount_wide_flags_to_inode_flags
919 *
920 * This function propagates the mount-wide flags to individual inode
921 * flags.
922 */
923static void ecryptfs_copy_mount_wide_flags_to_inode_flags(
924 struct ecryptfs_crypt_stat *crypt_stat,
925 struct ecryptfs_mount_crypt_stat *mount_crypt_stat)
926{
927 if (mount_crypt_stat->flags & ECRYPTFS_XATTR_METADATA_ENABLED)
928 crypt_stat->flags |= ECRYPTFS_METADATA_IN_XATTR;
929 if (mount_crypt_stat->flags & ECRYPTFS_ENCRYPTED_VIEW_ENABLED)
930 crypt_stat->flags |= ECRYPTFS_VIEW_AS_ENCRYPTED;
931}
932
933/**
918 * ecryptfs_set_default_crypt_stat_vals 934 * ecryptfs_set_default_crypt_stat_vals
919 * @crypt_stat 935 * @crypt_stat
920 * 936 *
@@ -924,6 +940,8 @@ static void ecryptfs_set_default_crypt_stat_vals(
924 struct ecryptfs_crypt_stat *crypt_stat, 940 struct ecryptfs_crypt_stat *crypt_stat,
925 struct ecryptfs_mount_crypt_stat *mount_crypt_stat) 941 struct ecryptfs_mount_crypt_stat *mount_crypt_stat)
926{ 942{
943 ecryptfs_copy_mount_wide_flags_to_inode_flags(crypt_stat,
944 mount_crypt_stat);
927 ecryptfs_set_default_sizes(crypt_stat); 945 ecryptfs_set_default_sizes(crypt_stat);
928 strcpy(crypt_stat->cipher, ECRYPTFS_DEFAULT_CIPHER); 946 strcpy(crypt_stat->cipher, ECRYPTFS_DEFAULT_CIPHER);
929 crypt_stat->key_size = ECRYPTFS_DEFAULT_KEY_BYTES; 947 crypt_stat->key_size = ECRYPTFS_DEFAULT_KEY_BYTES;
@@ -969,6 +987,8 @@ int ecryptfs_new_file_context(struct dentry *ecryptfs_dentry)
969 "file using mount_crypt_stat\n"); 987 "file using mount_crypt_stat\n");
970 ECRYPTFS_SET_FLAG(crypt_stat->flags, ECRYPTFS_ENCRYPTED); 988 ECRYPTFS_SET_FLAG(crypt_stat->flags, ECRYPTFS_ENCRYPTED);
971 ECRYPTFS_SET_FLAG(crypt_stat->flags, ECRYPTFS_KEY_VALID); 989 ECRYPTFS_SET_FLAG(crypt_stat->flags, ECRYPTFS_KEY_VALID);
990 ecryptfs_copy_mount_wide_flags_to_inode_flags(crypt_stat,
991 mount_crypt_stat);
972 memcpy(crypt_stat->keysigs[crypt_stat->num_keysigs++], 992 memcpy(crypt_stat->keysigs[crypt_stat->num_keysigs++],
973 mount_crypt_stat->global_auth_tok_sig, 993 mount_crypt_stat->global_auth_tok_sig,
974 ECRYPTFS_SIG_SIZE_HEX); 994 ECRYPTFS_SIG_SIZE_HEX);
diff --git a/fs/ecryptfs/ecryptfs_kernel.h b/fs/ecryptfs/ecryptfs_kernel.h
index f21385f97da5..7bbd6e6e2743 100644
--- a/fs/ecryptfs/ecryptfs_kernel.h
+++ b/fs/ecryptfs/ecryptfs_kernel.h
@@ -43,13 +43,14 @@
43 * module; userspace tools such as the mount helper read 43 * module; userspace tools such as the mount helper read
44 * ECRYPTFS_VERSIONING_MASK from a sysfs handle in order to determine 44 * ECRYPTFS_VERSIONING_MASK from a sysfs handle in order to determine
45 * how to behave. */ 45 * how to behave. */
46#define ECRYPTFS_VERSIONING_PASSPHRASE 0x00000001 46#define ECRYPTFS_VERSIONING_PASSPHRASE 0x00000001
47#define ECRYPTFS_VERSIONING_PUBKEY 0x00000002 47#define ECRYPTFS_VERSIONING_PUBKEY 0x00000002
48#define ECRYPTFS_VERSIONING_PLAINTEXT_PASSTHROUGH 0x00000004 48#define ECRYPTFS_VERSIONING_PLAINTEXT_PASSTHROUGH 0x00000004
49#define ECRYPTFS_VERSIONING_POLICY 0x00000008 49#define ECRYPTFS_VERSIONING_POLICY 0x00000008
50#define ECRYPTFS_VERSIONING_XATTR 0x00000010
50#define ECRYPTFS_VERSIONING_MASK (ECRYPTFS_VERSIONING_PASSPHRASE \ 51#define ECRYPTFS_VERSIONING_MASK (ECRYPTFS_VERSIONING_PASSPHRASE \
51 | ECRYPTFS_VERSIONING_PLAINTEXT_PASSTHROUGH \ 52 | ECRYPTFS_VERSIONING_PLAINTEXT_PASSTHROUGH \
52 | ECRYPTFS_VERSIONING_PUBKEY) 53 | ECRYPTFS_VERSIONING_PUBKEY)
53 54
54#define ECRYPTFS_MAX_PASSWORD_LENGTH 64 55#define ECRYPTFS_MAX_PASSWORD_LENGTH 64
55#define ECRYPTFS_MAX_PASSPHRASE_BYTES ECRYPTFS_MAX_PASSWORD_LENGTH 56#define ECRYPTFS_MAX_PASSPHRASE_BYTES ECRYPTFS_MAX_PASSWORD_LENGTH
@@ -227,6 +228,8 @@ struct ecryptfs_crypt_stat {
227#define ECRYPTFS_ENABLE_HMAC 0x00000020 228#define ECRYPTFS_ENABLE_HMAC 0x00000020
228#define ECRYPTFS_ENCRYPT_IV_PAGES 0x00000040 229#define ECRYPTFS_ENCRYPT_IV_PAGES 0x00000040
229#define ECRYPTFS_KEY_VALID 0x00000080 230#define ECRYPTFS_KEY_VALID 0x00000080
231#define ECRYPTFS_METADATA_IN_XATTR 0x00000100
232#define ECRYPTFS_VIEW_AS_ENCRYPTED 0x00000200
230 u32 flags; 233 u32 flags;
231 unsigned int file_version; 234 unsigned int file_version;
232 size_t iv_bytes; 235 size_t iv_bytes;
@@ -273,6 +276,8 @@ struct ecryptfs_dentry_info {
273struct ecryptfs_mount_crypt_stat { 276struct ecryptfs_mount_crypt_stat {
274 /* Pointers to memory we do not own, do not free these */ 277 /* Pointers to memory we do not own, do not free these */
275#define ECRYPTFS_PLAINTEXT_PASSTHROUGH_ENABLED 0x00000001 278#define ECRYPTFS_PLAINTEXT_PASSTHROUGH_ENABLED 0x00000001
279#define ECRYPTFS_XATTR_METADATA_ENABLED 0x00000002
280#define ECRYPTFS_ENCRYPTED_VIEW_ENABLED 0x00000004
276 u32 flags; 281 u32 flags;
277 struct ecryptfs_auth_tok *global_auth_tok; 282 struct ecryptfs_auth_tok *global_auth_tok;
278 struct key *global_auth_tok_key; 283 struct key *global_auth_tok_key;
diff --git a/fs/ecryptfs/main.c b/fs/ecryptfs/main.c
index 87f05c4bd509..a3efdccbbcc8 100644
--- a/fs/ecryptfs/main.c
+++ b/fs/ecryptfs/main.c
@@ -162,7 +162,8 @@ out:
162enum { ecryptfs_opt_sig, ecryptfs_opt_ecryptfs_sig, ecryptfs_opt_debug, 162enum { ecryptfs_opt_sig, ecryptfs_opt_ecryptfs_sig, ecryptfs_opt_debug,
163 ecryptfs_opt_ecryptfs_debug, ecryptfs_opt_cipher, 163 ecryptfs_opt_ecryptfs_debug, ecryptfs_opt_cipher,
164 ecryptfs_opt_ecryptfs_cipher, ecryptfs_opt_ecryptfs_key_bytes, 164 ecryptfs_opt_ecryptfs_cipher, ecryptfs_opt_ecryptfs_key_bytes,
165 ecryptfs_opt_passthrough, ecryptfs_opt_err }; 165 ecryptfs_opt_passthrough, ecryptfs_opt_xattr_metadata,
166 ecryptfs_opt_encrypted_view, ecryptfs_opt_err };
166 167
167static match_table_t tokens = { 168static match_table_t tokens = {
168 {ecryptfs_opt_sig, "sig=%s"}, 169 {ecryptfs_opt_sig, "sig=%s"},
@@ -173,6 +174,8 @@ static match_table_t tokens = {
173 {ecryptfs_opt_ecryptfs_cipher, "ecryptfs_cipher=%s"}, 174 {ecryptfs_opt_ecryptfs_cipher, "ecryptfs_cipher=%s"},
174 {ecryptfs_opt_ecryptfs_key_bytes, "ecryptfs_key_bytes=%u"}, 175 {ecryptfs_opt_ecryptfs_key_bytes, "ecryptfs_key_bytes=%u"},
175 {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"},
176 {ecryptfs_opt_err, NULL} 179 {ecryptfs_opt_err, NULL}
177}; 180};
178 181
@@ -313,6 +316,16 @@ static int ecryptfs_parse_options(struct super_block *sb, char *options)
313 mount_crypt_stat->flags |= 316 mount_crypt_stat->flags |=
314 ECRYPTFS_PLAINTEXT_PASSTHROUGH_ENABLED; 317 ECRYPTFS_PLAINTEXT_PASSTHROUGH_ENABLED;
315 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;
316 case ecryptfs_opt_err: 329 case ecryptfs_opt_err:
317 default: 330 default:
318 ecryptfs_printk(KERN_WARNING, 331 ecryptfs_printk(KERN_WARNING,
@@ -734,7 +747,8 @@ static struct ecryptfs_version_str_map_elem {
734 {ECRYPTFS_VERSIONING_PASSPHRASE, "passphrase"}, 747 {ECRYPTFS_VERSIONING_PASSPHRASE, "passphrase"},
735 {ECRYPTFS_VERSIONING_PUBKEY, "pubkey"}, 748 {ECRYPTFS_VERSIONING_PUBKEY, "pubkey"},
736 {ECRYPTFS_VERSIONING_PLAINTEXT_PASSTHROUGH, "plaintext passthrough"}, 749 {ECRYPTFS_VERSIONING_PLAINTEXT_PASSTHROUGH, "plaintext passthrough"},
737 {ECRYPTFS_VERSIONING_POLICY, "policy"} 750 {ECRYPTFS_VERSIONING_POLICY, "policy"},
751 {ECRYPTFS_VERSIONING_XATTR, "metadata in extended attribute"}
738}; 752};
739 753
740static ssize_t version_str_show(struct ecryptfs_obj *obj, char *buff) 754static ssize_t version_str_show(struct ecryptfs_obj *obj, char *buff)