diff options
author | Michael Halcrow <mhalcrow@us.ibm.com> | 2007-02-12 03:53:45 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-02-12 12:48:36 -0500 |
commit | 17398957aa0a05ef62535060b41d103590dcc533 (patch) | |
tree | bfb1d65281863811ad46d54f82e52e8924df3284 /fs | |
parent | dddfa461fc8951f9b5f951c13565b6cac678635a (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>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/ecryptfs/crypto.c | 20 | ||||
-rw-r--r-- | fs/ecryptfs/ecryptfs_kernel.h | 15 | ||||
-rw-r--r-- | fs/ecryptfs/main.c | 18 |
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 | */ | ||
923 | static 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 { | |||
273 | struct ecryptfs_mount_crypt_stat { | 276 | struct 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: | |||
162 | enum { ecryptfs_opt_sig, ecryptfs_opt_ecryptfs_sig, ecryptfs_opt_debug, | 162 | enum { 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 | ||
167 | static match_table_t tokens = { | 168 | static 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 | ||
740 | static ssize_t version_str_show(struct ecryptfs_obj *obj, char *buff) | 754 | static ssize_t version_str_show(struct ecryptfs_obj *obj, char *buff) |