diff options
author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2007-02-13 01:43:25 -0500 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2007-02-13 01:43:25 -0500 |
commit | d9bc125caf592b7d081021f32ce5b717efdf70c8 (patch) | |
tree | 263b7066ba22ddce21db610c0300f6eaac6f2064 /fs/ecryptfs | |
parent | 43d78ef2ba5bec26d0315859e8324bfc0be23766 (diff) | |
parent | ec2f9d1331f658433411c58077871e1eef4ee1b4 (diff) |
Merge branch 'master' of /home/trondmy/kernel/linux-2.6/
Conflicts:
net/sunrpc/auth_gss/gss_krb5_crypto.c
net/sunrpc/auth_gss/gss_spkm3_token.c
net/sunrpc/clnt.c
Merge with mainline and fix conflicts.
Diffstat (limited to 'fs/ecryptfs')
-rw-r--r-- | fs/ecryptfs/Makefile | 2 | ||||
-rw-r--r-- | fs/ecryptfs/crypto.c | 337 | ||||
-rw-r--r-- | fs/ecryptfs/debug.c | 6 | ||||
-rw-r--r-- | fs/ecryptfs/ecryptfs_kernel.h | 161 | ||||
-rw-r--r-- | fs/ecryptfs/file.c | 52 | ||||
-rw-r--r-- | fs/ecryptfs/inode.c | 93 | ||||
-rw-r--r-- | fs/ecryptfs/keystore.c | 802 | ||||
-rw-r--r-- | fs/ecryptfs/main.c | 82 | ||||
-rw-r--r-- | fs/ecryptfs/messaging.c | 515 | ||||
-rw-r--r-- | fs/ecryptfs/mmap.c | 378 | ||||
-rw-r--r-- | fs/ecryptfs/netlink.c | 255 | ||||
-rw-r--r-- | fs/ecryptfs/super.c | 2 |
12 files changed, 2214 insertions, 471 deletions
diff --git a/fs/ecryptfs/Makefile b/fs/ecryptfs/Makefile index ca6562451eeb..1f1107237eab 100644 --- a/fs/ecryptfs/Makefile +++ b/fs/ecryptfs/Makefile | |||
@@ -4,4 +4,4 @@ | |||
4 | 4 | ||
5 | obj-$(CONFIG_ECRYPT_FS) += ecryptfs.o | 5 | obj-$(CONFIG_ECRYPT_FS) += ecryptfs.o |
6 | 6 | ||
7 | ecryptfs-objs := dentry.o file.o inode.o main.o super.o mmap.o crypto.o keystore.o debug.o | 7 | ecryptfs-objs := dentry.o file.o inode.o main.o super.o mmap.o crypto.o keystore.o messaging.o netlink.o debug.o |
diff --git a/fs/ecryptfs/crypto.c b/fs/ecryptfs/crypto.c index 7196f50fe152..6ac630625b70 100644 --- a/fs/ecryptfs/crypto.c +++ b/fs/ecryptfs/crypto.c | |||
@@ -3,7 +3,7 @@ | |||
3 | * | 3 | * |
4 | * Copyright (C) 1997-2004 Erez Zadok | 4 | * Copyright (C) 1997-2004 Erez Zadok |
5 | * Copyright (C) 2001-2004 Stony Brook University | 5 | * Copyright (C) 2001-2004 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 | * | 9 | * |
@@ -207,7 +207,7 @@ ecryptfs_init_crypt_stat(struct ecryptfs_crypt_stat *crypt_stat) | |||
207 | mutex_init(&crypt_stat->cs_mutex); | 207 | mutex_init(&crypt_stat->cs_mutex); |
208 | mutex_init(&crypt_stat->cs_tfm_mutex); | 208 | mutex_init(&crypt_stat->cs_tfm_mutex); |
209 | mutex_init(&crypt_stat->cs_hash_tfm_mutex); | 209 | mutex_init(&crypt_stat->cs_hash_tfm_mutex); |
210 | ECRYPTFS_SET_FLAG(crypt_stat->flags, ECRYPTFS_STRUCT_INITIALIZED); | 210 | crypt_stat->flags |= ECRYPTFS_STRUCT_INITIALIZED; |
211 | } | 211 | } |
212 | 212 | ||
213 | /** | 213 | /** |
@@ -305,8 +305,7 @@ static int encrypt_scatterlist(struct ecryptfs_crypt_stat *crypt_stat, | |||
305 | int rc = 0; | 305 | int rc = 0; |
306 | 306 | ||
307 | BUG_ON(!crypt_stat || !crypt_stat->tfm | 307 | BUG_ON(!crypt_stat || !crypt_stat->tfm |
308 | || !ECRYPTFS_CHECK_FLAG(crypt_stat->flags, | 308 | || !(crypt_stat->flags & ECRYPTFS_STRUCT_INITIALIZED)); |
309 | ECRYPTFS_STRUCT_INITIALIZED)); | ||
310 | if (unlikely(ecryptfs_verbosity > 0)) { | 309 | if (unlikely(ecryptfs_verbosity > 0)) { |
311 | ecryptfs_printk(KERN_DEBUG, "Key size [%d]; key:\n", | 310 | ecryptfs_printk(KERN_DEBUG, "Key size [%d]; key:\n", |
312 | crypt_stat->key_size); | 311 | crypt_stat->key_size); |
@@ -429,10 +428,10 @@ static int ecryptfs_read_in_page(struct ecryptfs_page_crypt_context *ctx, | |||
429 | goto out; | 428 | goto out; |
430 | } | 429 | } |
431 | } else { | 430 | } else { |
432 | rc = ecryptfs_grab_and_map_lower_page(lower_page, NULL, | 431 | *lower_page = grab_cache_page(lower_inode->i_mapping, |
433 | lower_inode, | 432 | lower_page_idx); |
434 | lower_page_idx); | 433 | if (!(*lower_page)) { |
435 | if (rc) { | 434 | rc = -EINVAL; |
436 | ecryptfs_printk( | 435 | ecryptfs_printk( |
437 | KERN_ERR, "Error attempting to grab and map " | 436 | KERN_ERR, "Error attempting to grab and map " |
438 | "lower page with index [0x%.16x]; rc = [%d]\n", | 437 | "lower page with index [0x%.16x]; rc = [%d]\n", |
@@ -485,7 +484,7 @@ int ecryptfs_encrypt_page(struct ecryptfs_page_crypt_context *ctx) | |||
485 | lower_inode = ecryptfs_inode_to_lower(ctx->page->mapping->host); | 484 | lower_inode = ecryptfs_inode_to_lower(ctx->page->mapping->host); |
486 | inode_info = ecryptfs_inode_to_private(ctx->page->mapping->host); | 485 | inode_info = ecryptfs_inode_to_private(ctx->page->mapping->host); |
487 | crypt_stat = &inode_info->crypt_stat; | 486 | crypt_stat = &inode_info->crypt_stat; |
488 | if (!ECRYPTFS_CHECK_FLAG(crypt_stat->flags, ECRYPTFS_ENCRYPTED)) { | 487 | if (!(crypt_stat->flags & ECRYPTFS_ENCRYPTED)) { |
489 | rc = ecryptfs_copy_page_to_lower(ctx->page, lower_inode, | 488 | rc = ecryptfs_copy_page_to_lower(ctx->page, lower_inode, |
490 | ctx->param.lower_file); | 489 | ctx->param.lower_file); |
491 | if (rc) | 490 | if (rc) |
@@ -617,7 +616,7 @@ int ecryptfs_decrypt_page(struct file *file, struct page *page) | |||
617 | crypt_stat = &(ecryptfs_inode_to_private( | 616 | crypt_stat = &(ecryptfs_inode_to_private( |
618 | page->mapping->host)->crypt_stat); | 617 | page->mapping->host)->crypt_stat); |
619 | lower_inode = ecryptfs_inode_to_lower(page->mapping->host); | 618 | lower_inode = ecryptfs_inode_to_lower(page->mapping->host); |
620 | if (!ECRYPTFS_CHECK_FLAG(crypt_stat->flags, ECRYPTFS_ENCRYPTED)) { | 619 | if (!(crypt_stat->flags & ECRYPTFS_ENCRYPTED)) { |
621 | rc = ecryptfs_do_readpage(file, page, page->index); | 620 | rc = ecryptfs_do_readpage(file, page, page->index); |
622 | if (rc) | 621 | if (rc) |
623 | ecryptfs_printk(KERN_ERR, "Error attempting to copy " | 622 | ecryptfs_printk(KERN_ERR, "Error attempting to copy " |
@@ -828,9 +827,7 @@ int ecryptfs_init_crypt_ctx(struct ecryptfs_crypt_stat *crypt_stat) | |||
828 | mutex_unlock(&crypt_stat->cs_tfm_mutex); | 827 | mutex_unlock(&crypt_stat->cs_tfm_mutex); |
829 | goto out; | 828 | goto out; |
830 | } | 829 | } |
831 | crypto_blkcipher_set_flags(crypt_stat->tfm, | 830 | crypto_blkcipher_set_flags(crypt_stat->tfm, CRYPTO_TFM_REQ_WEAK_KEY); |
832 | (ECRYPTFS_DEFAULT_CHAINING_MODE | ||
833 | | CRYPTO_TFM_REQ_WEAK_KEY)); | ||
834 | mutex_unlock(&crypt_stat->cs_tfm_mutex); | 831 | mutex_unlock(&crypt_stat->cs_tfm_mutex); |
835 | rc = 0; | 832 | rc = 0; |
836 | out: | 833 | out: |
@@ -865,7 +862,10 @@ void ecryptfs_set_default_sizes(struct ecryptfs_crypt_stat *crypt_stat) | |||
865 | ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE; | 862 | ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE; |
866 | } else | 863 | } else |
867 | crypt_stat->header_extent_size = PAGE_CACHE_SIZE; | 864 | crypt_stat->header_extent_size = PAGE_CACHE_SIZE; |
868 | crypt_stat->num_header_extents_at_front = 1; | 865 | if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR) |
866 | crypt_stat->num_header_extents_at_front = 0; | ||
867 | else | ||
868 | crypt_stat->num_header_extents_at_front = 1; | ||
869 | } | 869 | } |
870 | 870 | ||
871 | /** | 871 | /** |
@@ -881,7 +881,7 @@ int ecryptfs_compute_root_iv(struct ecryptfs_crypt_stat *crypt_stat) | |||
881 | 881 | ||
882 | BUG_ON(crypt_stat->iv_bytes > MD5_DIGEST_SIZE); | 882 | BUG_ON(crypt_stat->iv_bytes > MD5_DIGEST_SIZE); |
883 | BUG_ON(crypt_stat->iv_bytes <= 0); | 883 | BUG_ON(crypt_stat->iv_bytes <= 0); |
884 | if (!ECRYPTFS_CHECK_FLAG(crypt_stat->flags, ECRYPTFS_KEY_VALID)) { | 884 | if (!(crypt_stat->flags & ECRYPTFS_KEY_VALID)) { |
885 | rc = -EINVAL; | 885 | rc = -EINVAL; |
886 | ecryptfs_printk(KERN_WARNING, "Session key not valid; " | 886 | ecryptfs_printk(KERN_WARNING, "Session key not valid; " |
887 | "cannot generate root IV\n"); | 887 | "cannot generate root IV\n"); |
@@ -898,8 +898,7 @@ int ecryptfs_compute_root_iv(struct ecryptfs_crypt_stat *crypt_stat) | |||
898 | out: | 898 | out: |
899 | if (rc) { | 899 | if (rc) { |
900 | memset(crypt_stat->root_iv, 0, crypt_stat->iv_bytes); | 900 | memset(crypt_stat->root_iv, 0, crypt_stat->iv_bytes); |
901 | ECRYPTFS_SET_FLAG(crypt_stat->flags, | 901 | crypt_stat->flags |= ECRYPTFS_SECURITY_WARNING; |
902 | ECRYPTFS_SECURITY_WARNING); | ||
903 | } | 902 | } |
904 | return rc; | 903 | return rc; |
905 | } | 904 | } |
@@ -907,7 +906,7 @@ out: | |||
907 | static void ecryptfs_generate_new_key(struct ecryptfs_crypt_stat *crypt_stat) | 906 | static void ecryptfs_generate_new_key(struct ecryptfs_crypt_stat *crypt_stat) |
908 | { | 907 | { |
909 | get_random_bytes(crypt_stat->key, crypt_stat->key_size); | 908 | get_random_bytes(crypt_stat->key, crypt_stat->key_size); |
910 | ECRYPTFS_SET_FLAG(crypt_stat->flags, ECRYPTFS_KEY_VALID); | 909 | crypt_stat->flags |= ECRYPTFS_KEY_VALID; |
911 | ecryptfs_compute_root_iv(crypt_stat); | 910 | ecryptfs_compute_root_iv(crypt_stat); |
912 | if (unlikely(ecryptfs_verbosity > 0)) { | 911 | if (unlikely(ecryptfs_verbosity > 0)) { |
913 | ecryptfs_printk(KERN_DEBUG, "Generated new session key:\n"); | 912 | ecryptfs_printk(KERN_DEBUG, "Generated new session key:\n"); |
@@ -917,6 +916,22 @@ static void ecryptfs_generate_new_key(struct ecryptfs_crypt_stat *crypt_stat) | |||
917 | } | 916 | } |
918 | 917 | ||
919 | /** | 918 | /** |
919 | * ecryptfs_copy_mount_wide_flags_to_inode_flags | ||
920 | * | ||
921 | * This function propagates the mount-wide flags to individual inode | ||
922 | * flags. | ||
923 | */ | ||
924 | static void ecryptfs_copy_mount_wide_flags_to_inode_flags( | ||
925 | struct ecryptfs_crypt_stat *crypt_stat, | ||
926 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat) | ||
927 | { | ||
928 | if (mount_crypt_stat->flags & ECRYPTFS_XATTR_METADATA_ENABLED) | ||
929 | crypt_stat->flags |= ECRYPTFS_METADATA_IN_XATTR; | ||
930 | if (mount_crypt_stat->flags & ECRYPTFS_ENCRYPTED_VIEW_ENABLED) | ||
931 | crypt_stat->flags |= ECRYPTFS_VIEW_AS_ENCRYPTED; | ||
932 | } | ||
933 | |||
934 | /** | ||
920 | * ecryptfs_set_default_crypt_stat_vals | 935 | * ecryptfs_set_default_crypt_stat_vals |
921 | * @crypt_stat | 936 | * @crypt_stat |
922 | * | 937 | * |
@@ -926,10 +941,12 @@ static void ecryptfs_set_default_crypt_stat_vals( | |||
926 | struct ecryptfs_crypt_stat *crypt_stat, | 941 | struct ecryptfs_crypt_stat *crypt_stat, |
927 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat) | 942 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat) |
928 | { | 943 | { |
944 | ecryptfs_copy_mount_wide_flags_to_inode_flags(crypt_stat, | ||
945 | mount_crypt_stat); | ||
929 | ecryptfs_set_default_sizes(crypt_stat); | 946 | ecryptfs_set_default_sizes(crypt_stat); |
930 | strcpy(crypt_stat->cipher, ECRYPTFS_DEFAULT_CIPHER); | 947 | strcpy(crypt_stat->cipher, ECRYPTFS_DEFAULT_CIPHER); |
931 | crypt_stat->key_size = ECRYPTFS_DEFAULT_KEY_BYTES; | 948 | crypt_stat->key_size = ECRYPTFS_DEFAULT_KEY_BYTES; |
932 | ECRYPTFS_CLEAR_FLAG(crypt_stat->flags, ECRYPTFS_KEY_VALID); | 949 | crypt_stat->flags &= ~(ECRYPTFS_KEY_VALID); |
933 | crypt_stat->file_version = ECRYPTFS_FILE_VERSION; | 950 | crypt_stat->file_version = ECRYPTFS_FILE_VERSION; |
934 | crypt_stat->mount_crypt_stat = mount_crypt_stat; | 951 | crypt_stat->mount_crypt_stat = mount_crypt_stat; |
935 | } | 952 | } |
@@ -969,8 +986,10 @@ int ecryptfs_new_file_context(struct dentry *ecryptfs_dentry) | |||
969 | if (mount_crypt_stat->global_auth_tok) { | 986 | if (mount_crypt_stat->global_auth_tok) { |
970 | ecryptfs_printk(KERN_DEBUG, "Initializing context for new " | 987 | ecryptfs_printk(KERN_DEBUG, "Initializing context for new " |
971 | "file using mount_crypt_stat\n"); | 988 | "file using mount_crypt_stat\n"); |
972 | ECRYPTFS_SET_FLAG(crypt_stat->flags, ECRYPTFS_ENCRYPTED); | 989 | crypt_stat->flags |= ECRYPTFS_ENCRYPTED; |
973 | ECRYPTFS_SET_FLAG(crypt_stat->flags, ECRYPTFS_KEY_VALID); | 990 | crypt_stat->flags |= ECRYPTFS_KEY_VALID; |
991 | ecryptfs_copy_mount_wide_flags_to_inode_flags(crypt_stat, | ||
992 | mount_crypt_stat); | ||
974 | memcpy(crypt_stat->keysigs[crypt_stat->num_keysigs++], | 993 | memcpy(crypt_stat->keysigs[crypt_stat->num_keysigs++], |
975 | mount_crypt_stat->global_auth_tok_sig, | 994 | mount_crypt_stat->global_auth_tok_sig, |
976 | ECRYPTFS_SIG_SIZE_HEX); | 995 | ECRYPTFS_SIG_SIZE_HEX); |
@@ -1003,7 +1022,7 @@ int ecryptfs_new_file_context(struct dentry *ecryptfs_dentry) | |||
1003 | * | 1022 | * |
1004 | * Returns one if marker found; zero if not found | 1023 | * Returns one if marker found; zero if not found |
1005 | */ | 1024 | */ |
1006 | int contains_ecryptfs_marker(char *data) | 1025 | static int contains_ecryptfs_marker(char *data) |
1007 | { | 1026 | { |
1008 | u32 m_1, m_2; | 1027 | u32 m_1, m_2; |
1009 | 1028 | ||
@@ -1029,7 +1048,8 @@ struct ecryptfs_flag_map_elem { | |||
1029 | /* Add support for additional flags by adding elements here. */ | 1048 | /* Add support for additional flags by adding elements here. */ |
1030 | static struct ecryptfs_flag_map_elem ecryptfs_flag_map[] = { | 1049 | static struct ecryptfs_flag_map_elem ecryptfs_flag_map[] = { |
1031 | {0x00000001, ECRYPTFS_ENABLE_HMAC}, | 1050 | {0x00000001, ECRYPTFS_ENABLE_HMAC}, |
1032 | {0x00000002, ECRYPTFS_ENCRYPTED} | 1051 | {0x00000002, ECRYPTFS_ENCRYPTED}, |
1052 | {0x00000004, ECRYPTFS_METADATA_IN_XATTR} | ||
1033 | }; | 1053 | }; |
1034 | 1054 | ||
1035 | /** | 1055 | /** |
@@ -1052,11 +1072,9 @@ static int ecryptfs_process_flags(struct ecryptfs_crypt_stat *crypt_stat, | |||
1052 | for (i = 0; i < ((sizeof(ecryptfs_flag_map) | 1072 | for (i = 0; i < ((sizeof(ecryptfs_flag_map) |
1053 | / sizeof(struct ecryptfs_flag_map_elem))); i++) | 1073 | / sizeof(struct ecryptfs_flag_map_elem))); i++) |
1054 | if (flags & ecryptfs_flag_map[i].file_flag) { | 1074 | if (flags & ecryptfs_flag_map[i].file_flag) { |
1055 | ECRYPTFS_SET_FLAG(crypt_stat->flags, | 1075 | crypt_stat->flags |= ecryptfs_flag_map[i].local_flag; |
1056 | ecryptfs_flag_map[i].local_flag); | ||
1057 | } else | 1076 | } else |
1058 | ECRYPTFS_CLEAR_FLAG(crypt_stat->flags, | 1077 | crypt_stat->flags &= ~(ecryptfs_flag_map[i].local_flag); |
1059 | ecryptfs_flag_map[i].local_flag); | ||
1060 | /* Version is in top 8 bits of the 32-bit flag vector */ | 1078 | /* Version is in top 8 bits of the 32-bit flag vector */ |
1061 | crypt_stat->file_version = ((flags >> 24) & 0xFF); | 1079 | crypt_stat->file_version = ((flags >> 24) & 0xFF); |
1062 | (*bytes_read) = 4; | 1080 | (*bytes_read) = 4; |
@@ -1093,8 +1111,7 @@ write_ecryptfs_flags(char *page_virt, struct ecryptfs_crypt_stat *crypt_stat, | |||
1093 | 1111 | ||
1094 | for (i = 0; i < ((sizeof(ecryptfs_flag_map) | 1112 | for (i = 0; i < ((sizeof(ecryptfs_flag_map) |
1095 | / sizeof(struct ecryptfs_flag_map_elem))); i++) | 1113 | / sizeof(struct ecryptfs_flag_map_elem))); i++) |
1096 | if (ECRYPTFS_CHECK_FLAG(crypt_stat->flags, | 1114 | if (crypt_stat->flags & ecryptfs_flag_map[i].local_flag) |
1097 | ecryptfs_flag_map[i].local_flag)) | ||
1098 | flags |= ecryptfs_flag_map[i].file_flag; | 1115 | flags |= ecryptfs_flag_map[i].file_flag; |
1099 | /* Version is in top 8 bits of the 32-bit flag vector */ | 1116 | /* Version is in top 8 bits of the 32-bit flag vector */ |
1100 | flags |= ((((u8)crypt_stat->file_version) << 24) & 0xFF000000); | 1117 | flags |= ((((u8)crypt_stat->file_version) << 24) & 0xFF000000); |
@@ -1189,8 +1206,8 @@ int ecryptfs_cipher_code_to_string(char *str, u16 cipher_code) | |||
1189 | * | 1206 | * |
1190 | * Returns zero on success; non-zero otherwise | 1207 | * Returns zero on success; non-zero otherwise |
1191 | */ | 1208 | */ |
1192 | int ecryptfs_read_header_region(char *data, struct dentry *dentry, | 1209 | static int ecryptfs_read_header_region(char *data, struct dentry *dentry, |
1193 | struct vfsmount *mnt) | 1210 | struct vfsmount *mnt) |
1194 | { | 1211 | { |
1195 | struct file *lower_file; | 1212 | struct file *lower_file; |
1196 | mm_segment_t oldfs; | 1213 | mm_segment_t oldfs; |
@@ -1219,9 +1236,25 @@ out: | |||
1219 | return rc; | 1236 | return rc; |
1220 | } | 1237 | } |
1221 | 1238 | ||
1222 | static void | 1239 | int ecryptfs_read_and_validate_header_region(char *data, struct dentry *dentry, |
1223 | write_header_metadata(char *virt, struct ecryptfs_crypt_stat *crypt_stat, | 1240 | struct vfsmount *mnt) |
1224 | size_t *written) | 1241 | { |
1242 | int rc; | ||
1243 | |||
1244 | rc = ecryptfs_read_header_region(data, dentry, mnt); | ||
1245 | if (rc) | ||
1246 | goto out; | ||
1247 | if (!contains_ecryptfs_marker(data + ECRYPTFS_FILE_SIZE_BYTES)) | ||
1248 | rc = -EINVAL; | ||
1249 | out: | ||
1250 | return rc; | ||
1251 | } | ||
1252 | |||
1253 | |||
1254 | void | ||
1255 | ecryptfs_write_header_metadata(char *virt, | ||
1256 | struct ecryptfs_crypt_stat *crypt_stat, | ||
1257 | size_t *written) | ||
1225 | { | 1258 | { |
1226 | u32 header_extent_size; | 1259 | u32 header_extent_size; |
1227 | u16 num_header_extents_at_front; | 1260 | u16 num_header_extents_at_front; |
@@ -1270,9 +1303,9 @@ struct kmem_cache *ecryptfs_header_cache_2; | |||
1270 | * | 1303 | * |
1271 | * Returns zero on success | 1304 | * Returns zero on success |
1272 | */ | 1305 | */ |
1273 | int ecryptfs_write_headers_virt(char *page_virt, | 1306 | static int ecryptfs_write_headers_virt(char *page_virt, size_t *size, |
1274 | struct ecryptfs_crypt_stat *crypt_stat, | 1307 | struct ecryptfs_crypt_stat *crypt_stat, |
1275 | struct dentry *ecryptfs_dentry) | 1308 | struct dentry *ecryptfs_dentry) |
1276 | { | 1309 | { |
1277 | int rc; | 1310 | int rc; |
1278 | size_t written; | 1311 | size_t written; |
@@ -1283,7 +1316,8 @@ int ecryptfs_write_headers_virt(char *page_virt, | |||
1283 | offset += written; | 1316 | offset += written; |
1284 | write_ecryptfs_flags((page_virt + offset), crypt_stat, &written); | 1317 | write_ecryptfs_flags((page_virt + offset), crypt_stat, &written); |
1285 | offset += written; | 1318 | offset += written; |
1286 | write_header_metadata((page_virt + offset), crypt_stat, &written); | 1319 | ecryptfs_write_header_metadata((page_virt + offset), crypt_stat, |
1320 | &written); | ||
1287 | offset += written; | 1321 | offset += written; |
1288 | rc = ecryptfs_generate_key_packet_set((page_virt + offset), crypt_stat, | 1322 | rc = ecryptfs_generate_key_packet_set((page_virt + offset), crypt_stat, |
1289 | ecryptfs_dentry, &written, | 1323 | ecryptfs_dentry, &written, |
@@ -1291,11 +1325,70 @@ int ecryptfs_write_headers_virt(char *page_virt, | |||
1291 | if (rc) | 1325 | if (rc) |
1292 | ecryptfs_printk(KERN_WARNING, "Error generating key packet " | 1326 | ecryptfs_printk(KERN_WARNING, "Error generating key packet " |
1293 | "set; rc = [%d]\n", rc); | 1327 | "set; rc = [%d]\n", rc); |
1328 | if (size) { | ||
1329 | offset += written; | ||
1330 | *size = offset; | ||
1331 | } | ||
1332 | return rc; | ||
1333 | } | ||
1334 | |||
1335 | static int ecryptfs_write_metadata_to_contents(struct ecryptfs_crypt_stat *crypt_stat, | ||
1336 | struct file *lower_file, | ||
1337 | char *page_virt) | ||
1338 | { | ||
1339 | mm_segment_t oldfs; | ||
1340 | int current_header_page; | ||
1341 | int header_pages; | ||
1342 | ssize_t size; | ||
1343 | int rc = 0; | ||
1344 | |||
1345 | lower_file->f_pos = 0; | ||
1346 | oldfs = get_fs(); | ||
1347 | set_fs(get_ds()); | ||
1348 | size = vfs_write(lower_file, (char __user *)page_virt, PAGE_CACHE_SIZE, | ||
1349 | &lower_file->f_pos); | ||
1350 | if (size < 0) { | ||
1351 | rc = (int)size; | ||
1352 | printk(KERN_ERR "Error attempting to write lower page; " | ||
1353 | "rc = [%d]\n", rc); | ||
1354 | set_fs(oldfs); | ||
1355 | goto out; | ||
1356 | } | ||
1357 | header_pages = ((crypt_stat->header_extent_size | ||
1358 | * crypt_stat->num_header_extents_at_front) | ||
1359 | / PAGE_CACHE_SIZE); | ||
1360 | memset(page_virt, 0, PAGE_CACHE_SIZE); | ||
1361 | current_header_page = 1; | ||
1362 | while (current_header_page < header_pages) { | ||
1363 | size = vfs_write(lower_file, (char __user *)page_virt, | ||
1364 | PAGE_CACHE_SIZE, &lower_file->f_pos); | ||
1365 | if (size < 0) { | ||
1366 | rc = (int)size; | ||
1367 | printk(KERN_ERR "Error attempting to write lower page; " | ||
1368 | "rc = [%d]\n", rc); | ||
1369 | set_fs(oldfs); | ||
1370 | goto out; | ||
1371 | } | ||
1372 | current_header_page++; | ||
1373 | } | ||
1374 | set_fs(oldfs); | ||
1375 | out: | ||
1376 | return rc; | ||
1377 | } | ||
1378 | |||
1379 | static int ecryptfs_write_metadata_to_xattr(struct dentry *ecryptfs_dentry, | ||
1380 | struct ecryptfs_crypt_stat *crypt_stat, | ||
1381 | char *page_virt, size_t size) | ||
1382 | { | ||
1383 | int rc; | ||
1384 | |||
1385 | rc = ecryptfs_setxattr(ecryptfs_dentry, ECRYPTFS_XATTR_NAME, page_virt, | ||
1386 | size, 0); | ||
1294 | return rc; | 1387 | return rc; |
1295 | } | 1388 | } |
1296 | 1389 | ||
1297 | /** | 1390 | /** |
1298 | * ecryptfs_write_headers | 1391 | * ecryptfs_write_metadata |
1299 | * @lower_file: The lower file struct, which was returned from dentry_open | 1392 | * @lower_file: The lower file struct, which was returned from dentry_open |
1300 | * | 1393 | * |
1301 | * Write the file headers out. This will likely involve a userspace | 1394 | * Write the file headers out. This will likely involve a userspace |
@@ -1306,22 +1399,18 @@ int ecryptfs_write_headers_virt(char *page_virt, | |||
1306 | * | 1399 | * |
1307 | * Returns zero on success; non-zero on error | 1400 | * Returns zero on success; non-zero on error |
1308 | */ | 1401 | */ |
1309 | int ecryptfs_write_headers(struct dentry *ecryptfs_dentry, | 1402 | int ecryptfs_write_metadata(struct dentry *ecryptfs_dentry, |
1310 | struct file *lower_file) | 1403 | struct file *lower_file) |
1311 | { | 1404 | { |
1312 | mm_segment_t oldfs; | ||
1313 | struct ecryptfs_crypt_stat *crypt_stat; | 1405 | struct ecryptfs_crypt_stat *crypt_stat; |
1314 | char *page_virt; | 1406 | char *page_virt; |
1315 | int current_header_page; | 1407 | size_t size; |
1316 | int header_pages; | ||
1317 | int rc = 0; | 1408 | int rc = 0; |
1318 | 1409 | ||
1319 | crypt_stat = &ecryptfs_inode_to_private( | 1410 | crypt_stat = &ecryptfs_inode_to_private( |
1320 | ecryptfs_dentry->d_inode)->crypt_stat; | 1411 | ecryptfs_dentry->d_inode)->crypt_stat; |
1321 | if (likely(ECRYPTFS_CHECK_FLAG(crypt_stat->flags, | 1412 | if (likely(crypt_stat->flags & ECRYPTFS_ENCRYPTED)) { |
1322 | ECRYPTFS_ENCRYPTED))) { | 1413 | if (!(crypt_stat->flags & ECRYPTFS_KEY_VALID)) { |
1323 | if (!ECRYPTFS_CHECK_FLAG(crypt_stat->flags, | ||
1324 | ECRYPTFS_KEY_VALID)) { | ||
1325 | ecryptfs_printk(KERN_DEBUG, "Key is " | 1414 | ecryptfs_printk(KERN_DEBUG, "Key is " |
1326 | "invalid; bailing out\n"); | 1415 | "invalid; bailing out\n"); |
1327 | rc = -EINVAL; | 1416 | rc = -EINVAL; |
@@ -1334,54 +1423,42 @@ int ecryptfs_write_headers(struct dentry *ecryptfs_dentry, | |||
1334 | goto out; | 1423 | goto out; |
1335 | } | 1424 | } |
1336 | /* Released in this function */ | 1425 | /* Released in this function */ |
1337 | page_virt = kmem_cache_alloc(ecryptfs_header_cache_0, GFP_USER); | 1426 | page_virt = kmem_cache_zalloc(ecryptfs_header_cache_0, GFP_USER); |
1338 | if (!page_virt) { | 1427 | if (!page_virt) { |
1339 | ecryptfs_printk(KERN_ERR, "Out of memory\n"); | 1428 | ecryptfs_printk(KERN_ERR, "Out of memory\n"); |
1340 | rc = -ENOMEM; | 1429 | rc = -ENOMEM; |
1341 | goto out; | 1430 | goto out; |
1342 | } | 1431 | } |
1343 | memset(page_virt, 0, PAGE_CACHE_SIZE); | 1432 | rc = ecryptfs_write_headers_virt(page_virt, &size, crypt_stat, |
1344 | rc = ecryptfs_write_headers_virt(page_virt, crypt_stat, | 1433 | ecryptfs_dentry); |
1345 | ecryptfs_dentry); | ||
1346 | if (unlikely(rc)) { | 1434 | if (unlikely(rc)) { |
1347 | ecryptfs_printk(KERN_ERR, "Error whilst writing headers\n"); | 1435 | ecryptfs_printk(KERN_ERR, "Error whilst writing headers\n"); |
1348 | memset(page_virt, 0, PAGE_CACHE_SIZE); | 1436 | memset(page_virt, 0, PAGE_CACHE_SIZE); |
1349 | goto out_free; | 1437 | goto out_free; |
1350 | } | 1438 | } |
1351 | ecryptfs_printk(KERN_DEBUG, | 1439 | if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR) |
1352 | "Writing key packet set to underlying file\n"); | 1440 | rc = ecryptfs_write_metadata_to_xattr(ecryptfs_dentry, |
1353 | lower_file->f_pos = 0; | 1441 | crypt_stat, page_virt, |
1354 | oldfs = get_fs(); | 1442 | size); |
1355 | set_fs(get_ds()); | 1443 | else |
1356 | ecryptfs_printk(KERN_DEBUG, "Calling lower_file->f_op->" | 1444 | rc = ecryptfs_write_metadata_to_contents(crypt_stat, lower_file, |
1357 | "write() w/ header page; lower_file->f_pos = " | 1445 | page_virt); |
1358 | "[0x%.16x]\n", lower_file->f_pos); | 1446 | if (rc) { |
1359 | lower_file->f_op->write(lower_file, (char __user *)page_virt, | 1447 | printk(KERN_ERR "Error writing metadata out to lower file; " |
1360 | PAGE_CACHE_SIZE, &lower_file->f_pos); | 1448 | "rc = [%d]\n", rc); |
1361 | header_pages = ((crypt_stat->header_extent_size | 1449 | goto out_free; |
1362 | * crypt_stat->num_header_extents_at_front) | ||
1363 | / PAGE_CACHE_SIZE); | ||
1364 | memset(page_virt, 0, PAGE_CACHE_SIZE); | ||
1365 | current_header_page = 1; | ||
1366 | while (current_header_page < header_pages) { | ||
1367 | ecryptfs_printk(KERN_DEBUG, "Calling lower_file->f_op->" | ||
1368 | "write() w/ zero'd page; lower_file->f_pos = " | ||
1369 | "[0x%.16x]\n", lower_file->f_pos); | ||
1370 | lower_file->f_op->write(lower_file, (char __user *)page_virt, | ||
1371 | PAGE_CACHE_SIZE, &lower_file->f_pos); | ||
1372 | current_header_page++; | ||
1373 | } | 1450 | } |
1374 | set_fs(oldfs); | ||
1375 | ecryptfs_printk(KERN_DEBUG, | ||
1376 | "Done writing key packet set to underlying file.\n"); | ||
1377 | out_free: | 1451 | out_free: |
1378 | kmem_cache_free(ecryptfs_header_cache_0, page_virt); | 1452 | kmem_cache_free(ecryptfs_header_cache_0, page_virt); |
1379 | out: | 1453 | out: |
1380 | return rc; | 1454 | return rc; |
1381 | } | 1455 | } |
1382 | 1456 | ||
1457 | #define ECRYPTFS_DONT_VALIDATE_HEADER_SIZE 0 | ||
1458 | #define ECRYPTFS_VALIDATE_HEADER_SIZE 1 | ||
1383 | static int parse_header_metadata(struct ecryptfs_crypt_stat *crypt_stat, | 1459 | static int parse_header_metadata(struct ecryptfs_crypt_stat *crypt_stat, |
1384 | char *virt, int *bytes_read) | 1460 | char *virt, int *bytes_read, |
1461 | int validate_header_size) | ||
1385 | { | 1462 | { |
1386 | int rc = 0; | 1463 | int rc = 0; |
1387 | u32 header_extent_size; | 1464 | u32 header_extent_size; |
@@ -1396,9 +1473,10 @@ static int parse_header_metadata(struct ecryptfs_crypt_stat *crypt_stat, | |||
1396 | crypt_stat->num_header_extents_at_front = | 1473 | crypt_stat->num_header_extents_at_front = |
1397 | (int)num_header_extents_at_front; | 1474 | (int)num_header_extents_at_front; |
1398 | (*bytes_read) = 6; | 1475 | (*bytes_read) = 6; |
1399 | if ((crypt_stat->header_extent_size | 1476 | if ((validate_header_size == ECRYPTFS_VALIDATE_HEADER_SIZE) |
1400 | * crypt_stat->num_header_extents_at_front) | 1477 | && ((crypt_stat->header_extent_size |
1401 | < ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE) { | 1478 | * crypt_stat->num_header_extents_at_front) |
1479 | < ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE)) { | ||
1402 | rc = -EINVAL; | 1480 | rc = -EINVAL; |
1403 | ecryptfs_printk(KERN_WARNING, "Invalid header extent size: " | 1481 | ecryptfs_printk(KERN_WARNING, "Invalid header extent size: " |
1404 | "[%d]\n", crypt_stat->header_extent_size); | 1482 | "[%d]\n", crypt_stat->header_extent_size); |
@@ -1429,7 +1507,8 @@ static void set_default_header_data(struct ecryptfs_crypt_stat *crypt_stat) | |||
1429 | */ | 1507 | */ |
1430 | static int ecryptfs_read_headers_virt(char *page_virt, | 1508 | static int ecryptfs_read_headers_virt(char *page_virt, |
1431 | struct ecryptfs_crypt_stat *crypt_stat, | 1509 | struct ecryptfs_crypt_stat *crypt_stat, |
1432 | struct dentry *ecryptfs_dentry) | 1510 | struct dentry *ecryptfs_dentry, |
1511 | int validate_header_size) | ||
1433 | { | 1512 | { |
1434 | int rc = 0; | 1513 | int rc = 0; |
1435 | int offset; | 1514 | int offset; |
@@ -1463,7 +1542,7 @@ static int ecryptfs_read_headers_virt(char *page_virt, | |||
1463 | offset += bytes_read; | 1542 | offset += bytes_read; |
1464 | if (crypt_stat->file_version >= 1) { | 1543 | if (crypt_stat->file_version >= 1) { |
1465 | rc = parse_header_metadata(crypt_stat, (page_virt + offset), | 1544 | rc = parse_header_metadata(crypt_stat, (page_virt + offset), |
1466 | &bytes_read); | 1545 | &bytes_read, validate_header_size); |
1467 | if (rc) { | 1546 | if (rc) { |
1468 | ecryptfs_printk(KERN_WARNING, "Error reading header " | 1547 | ecryptfs_printk(KERN_WARNING, "Error reading header " |
1469 | "metadata; rc = [%d]\n", rc); | 1548 | "metadata; rc = [%d]\n", rc); |
@@ -1478,12 +1557,60 @@ out: | |||
1478 | } | 1557 | } |
1479 | 1558 | ||
1480 | /** | 1559 | /** |
1481 | * ecryptfs_read_headers | 1560 | * ecryptfs_read_xattr_region |
1561 | * | ||
1562 | * Attempts to read the crypto metadata from the extended attribute | ||
1563 | * region of the lower file. | ||
1564 | */ | ||
1565 | int ecryptfs_read_xattr_region(char *page_virt, struct dentry *ecryptfs_dentry) | ||
1566 | { | ||
1567 | ssize_t size; | ||
1568 | int rc = 0; | ||
1569 | |||
1570 | size = ecryptfs_getxattr(ecryptfs_dentry, ECRYPTFS_XATTR_NAME, | ||
1571 | page_virt, ECRYPTFS_DEFAULT_EXTENT_SIZE); | ||
1572 | if (size < 0) { | ||
1573 | printk(KERN_DEBUG "Error attempting to read the [%s] " | ||
1574 | "xattr from the lower file; return value = [%zd]\n", | ||
1575 | ECRYPTFS_XATTR_NAME, size); | ||
1576 | rc = -EINVAL; | ||
1577 | goto out; | ||
1578 | } | ||
1579 | out: | ||
1580 | return rc; | ||
1581 | } | ||
1582 | |||
1583 | int ecryptfs_read_and_validate_xattr_region(char *page_virt, | ||
1584 | struct dentry *ecryptfs_dentry) | ||
1585 | { | ||
1586 | int rc; | ||
1587 | |||
1588 | rc = ecryptfs_read_xattr_region(page_virt, ecryptfs_dentry); | ||
1589 | if (rc) | ||
1590 | goto out; | ||
1591 | if (!contains_ecryptfs_marker(page_virt + ECRYPTFS_FILE_SIZE_BYTES)) { | ||
1592 | printk(KERN_WARNING "Valid data found in [%s] xattr, but " | ||
1593 | "the marker is invalid\n", ECRYPTFS_XATTR_NAME); | ||
1594 | rc = -EINVAL; | ||
1595 | } | ||
1596 | out: | ||
1597 | return rc; | ||
1598 | } | ||
1599 | |||
1600 | /** | ||
1601 | * ecryptfs_read_metadata | ||
1602 | * | ||
1603 | * Common entry point for reading file metadata. From here, we could | ||
1604 | * retrieve the header information from the header region of the file, | ||
1605 | * the xattr region of the file, or some other repostory that is | ||
1606 | * stored separately from the file itself. The current implementation | ||
1607 | * supports retrieving the metadata information from the file contents | ||
1608 | * and from the xattr region. | ||
1482 | * | 1609 | * |
1483 | * Returns zero if valid headers found and parsed; non-zero otherwise | 1610 | * Returns zero if valid headers found and parsed; non-zero otherwise |
1484 | */ | 1611 | */ |
1485 | int ecryptfs_read_headers(struct dentry *ecryptfs_dentry, | 1612 | int ecryptfs_read_metadata(struct dentry *ecryptfs_dentry, |
1486 | struct file *lower_file) | 1613 | struct file *lower_file) |
1487 | { | 1614 | { |
1488 | int rc = 0; | 1615 | int rc = 0; |
1489 | char *page_virt = NULL; | 1616 | char *page_virt = NULL; |
@@ -1491,7 +1618,12 @@ int ecryptfs_read_headers(struct dentry *ecryptfs_dentry, | |||
1491 | ssize_t bytes_read; | 1618 | ssize_t bytes_read; |
1492 | struct ecryptfs_crypt_stat *crypt_stat = | 1619 | struct ecryptfs_crypt_stat *crypt_stat = |
1493 | &ecryptfs_inode_to_private(ecryptfs_dentry->d_inode)->crypt_stat; | 1620 | &ecryptfs_inode_to_private(ecryptfs_dentry->d_inode)->crypt_stat; |
1621 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat = | ||
1622 | &ecryptfs_superblock_to_private( | ||
1623 | ecryptfs_dentry->d_sb)->mount_crypt_stat; | ||
1494 | 1624 | ||
1625 | ecryptfs_copy_mount_wide_flags_to_inode_flags(crypt_stat, | ||
1626 | mount_crypt_stat); | ||
1495 | /* Read the first page from the underlying file */ | 1627 | /* Read the first page from the underlying file */ |
1496 | page_virt = kmem_cache_alloc(ecryptfs_header_cache_1, GFP_USER); | 1628 | page_virt = kmem_cache_alloc(ecryptfs_header_cache_1, GFP_USER); |
1497 | if (!page_virt) { | 1629 | if (!page_virt) { |
@@ -1512,11 +1644,36 @@ int ecryptfs_read_headers(struct dentry *ecryptfs_dentry, | |||
1512 | goto out; | 1644 | goto out; |
1513 | } | 1645 | } |
1514 | rc = ecryptfs_read_headers_virt(page_virt, crypt_stat, | 1646 | rc = ecryptfs_read_headers_virt(page_virt, crypt_stat, |
1515 | ecryptfs_dentry); | 1647 | ecryptfs_dentry, |
1648 | ECRYPTFS_VALIDATE_HEADER_SIZE); | ||
1516 | if (rc) { | 1649 | if (rc) { |
1517 | ecryptfs_printk(KERN_DEBUG, "Valid eCryptfs headers not " | 1650 | rc = ecryptfs_read_xattr_region(page_virt, |
1518 | "found\n"); | 1651 | ecryptfs_dentry); |
1519 | rc = -EINVAL; | 1652 | if (rc) { |
1653 | printk(KERN_DEBUG "Valid eCryptfs headers not found in " | ||
1654 | "file header region or xattr region\n"); | ||
1655 | rc = -EINVAL; | ||
1656 | goto out; | ||
1657 | } | ||
1658 | rc = ecryptfs_read_headers_virt(page_virt, crypt_stat, | ||
1659 | ecryptfs_dentry, | ||
1660 | ECRYPTFS_DONT_VALIDATE_HEADER_SIZE); | ||
1661 | if (rc) { | ||
1662 | printk(KERN_DEBUG "Valid eCryptfs headers not found in " | ||
1663 | "file xattr region either\n"); | ||
1664 | rc = -EINVAL; | ||
1665 | } | ||
1666 | if (crypt_stat->mount_crypt_stat->flags | ||
1667 | & ECRYPTFS_XATTR_METADATA_ENABLED) { | ||
1668 | crypt_stat->flags |= ECRYPTFS_METADATA_IN_XATTR; | ||
1669 | } else { | ||
1670 | printk(KERN_WARNING "Attempt to access file with " | ||
1671 | "crypto metadata only in the extended attribute " | ||
1672 | "region, but eCryptfs was mounted without " | ||
1673 | "xattr support enabled. eCryptfs will not treat " | ||
1674 | "this like an encrypted file.\n"); | ||
1675 | rc = -EINVAL; | ||
1676 | } | ||
1520 | } | 1677 | } |
1521 | out: | 1678 | out: |
1522 | if (page_virt) { | 1679 | if (page_virt) { |
diff --git a/fs/ecryptfs/debug.c b/fs/ecryptfs/debug.c index 61f8e894284f..434c7efd80f8 100644 --- a/fs/ecryptfs/debug.c +++ b/fs/ecryptfs/debug.c | |||
@@ -36,7 +36,7 @@ void ecryptfs_dump_auth_tok(struct ecryptfs_auth_tok *auth_tok) | |||
36 | 36 | ||
37 | ecryptfs_printk(KERN_DEBUG, "Auth tok at mem loc [%p]:\n", | 37 | ecryptfs_printk(KERN_DEBUG, "Auth tok at mem loc [%p]:\n", |
38 | auth_tok); | 38 | auth_tok); |
39 | if (ECRYPTFS_CHECK_FLAG(auth_tok->flags, ECRYPTFS_PRIVATE_KEY)) { | 39 | if (auth_tok->flags & ECRYPTFS_PRIVATE_KEY) { |
40 | ecryptfs_printk(KERN_DEBUG, " * private key type\n"); | 40 | ecryptfs_printk(KERN_DEBUG, " * private key type\n"); |
41 | ecryptfs_printk(KERN_DEBUG, " * (NO PRIVATE KEY SUPPORT " | 41 | ecryptfs_printk(KERN_DEBUG, " * (NO PRIVATE KEY SUPPORT " |
42 | "IN ECRYPTFS VERSION 0.1)\n"); | 42 | "IN ECRYPTFS VERSION 0.1)\n"); |
@@ -46,8 +46,8 @@ void ecryptfs_dump_auth_tok(struct ecryptfs_auth_tok *auth_tok) | |||
46 | ECRYPTFS_SALT_SIZE); | 46 | ECRYPTFS_SALT_SIZE); |
47 | salt[ECRYPTFS_SALT_SIZE * 2] = '\0'; | 47 | salt[ECRYPTFS_SALT_SIZE * 2] = '\0'; |
48 | ecryptfs_printk(KERN_DEBUG, " * salt = [%s]\n", salt); | 48 | ecryptfs_printk(KERN_DEBUG, " * salt = [%s]\n", salt); |
49 | if (ECRYPTFS_CHECK_FLAG(auth_tok->token.password.flags, | 49 | if (auth_tok->token.password.flags & |
50 | ECRYPTFS_PERSISTENT_PASSWORD)) { | 50 | ECRYPTFS_PERSISTENT_PASSWORD) { |
51 | ecryptfs_printk(KERN_DEBUG, " * persistent\n"); | 51 | ecryptfs_printk(KERN_DEBUG, " * persistent\n"); |
52 | } | 52 | } |
53 | memcpy(sig, auth_tok->token.password.signature, | 53 | memcpy(sig, auth_tok->token.password.signature, |
diff --git a/fs/ecryptfs/ecryptfs_kernel.h b/fs/ecryptfs/ecryptfs_kernel.h index afb64bdbe6ad..b3609b7cdf11 100644 --- a/fs/ecryptfs/ecryptfs_kernel.h +++ b/fs/ecryptfs/ecryptfs_kernel.h | |||
@@ -4,8 +4,10 @@ | |||
4 | * | 4 | * |
5 | * Copyright (C) 1997-2003 Erez Zadok | 5 | * Copyright (C) 1997-2003 Erez Zadok |
6 | * Copyright (C) 2001-2003 Stony Brook University | 6 | * Copyright (C) 2001-2003 Stony Brook University |
7 | * Copyright (C) 2004-2006 International Business Machines Corp. | 7 | * Copyright (C) 2004-2007 International Business Machines Corp. |
8 | * Author(s): Michael A. Halcrow <mahalcro@us.ibm.com> | 8 | * Author(s): Michael A. Halcrow <mahalcro@us.ibm.com> |
9 | * Trevor S. Highland <trevor.highland@gmail.com> | ||
10 | * Tyler Hicks <tyhicks@ou.edu> | ||
9 | * | 11 | * |
10 | * This program is free software; you can redistribute it and/or | 12 | * This program is free software; you can redistribute it and/or |
11 | * modify it under the terms of the GNU General Public License as | 13 | * modify it under the terms of the GNU General Public License as |
@@ -31,22 +33,25 @@ | |||
31 | #include <linux/fs_stack.h> | 33 | #include <linux/fs_stack.h> |
32 | #include <linux/namei.h> | 34 | #include <linux/namei.h> |
33 | #include <linux/scatterlist.h> | 35 | #include <linux/scatterlist.h> |
36 | #include <linux/hash.h> | ||
34 | 37 | ||
35 | /* Version verification for shared data structures w/ userspace */ | 38 | /* Version verification for shared data structures w/ userspace */ |
36 | #define ECRYPTFS_VERSION_MAJOR 0x00 | 39 | #define ECRYPTFS_VERSION_MAJOR 0x00 |
37 | #define ECRYPTFS_VERSION_MINOR 0x04 | 40 | #define ECRYPTFS_VERSION_MINOR 0x04 |
38 | #define ECRYPTFS_SUPPORTED_FILE_VERSION 0x01 | 41 | #define ECRYPTFS_SUPPORTED_FILE_VERSION 0x02 |
39 | /* These flags indicate which features are supported by the kernel | 42 | /* These flags indicate which features are supported by the kernel |
40 | * module; userspace tools such as the mount helper read | 43 | * module; userspace tools such as the mount helper read |
41 | * ECRYPTFS_VERSIONING_MASK from a sysfs handle in order to determine | 44 | * ECRYPTFS_VERSIONING_MASK from a sysfs handle in order to determine |
42 | * how to behave. */ | 45 | * how to behave. */ |
43 | #define ECRYPTFS_VERSIONING_PASSPHRASE 0x00000001 | 46 | #define ECRYPTFS_VERSIONING_PASSPHRASE 0x00000001 |
44 | #define ECRYPTFS_VERSIONING_PUBKEY 0x00000002 | 47 | #define ECRYPTFS_VERSIONING_PUBKEY 0x00000002 |
45 | #define ECRYPTFS_VERSIONING_PLAINTEXT_PASSTHROUGH 0x00000004 | 48 | #define ECRYPTFS_VERSIONING_PLAINTEXT_PASSTHROUGH 0x00000004 |
46 | #define ECRYPTFS_VERSIONING_POLICY 0x00000008 | 49 | #define ECRYPTFS_VERSIONING_POLICY 0x00000008 |
50 | #define ECRYPTFS_VERSIONING_XATTR 0x00000010 | ||
47 | #define ECRYPTFS_VERSIONING_MASK (ECRYPTFS_VERSIONING_PASSPHRASE \ | 51 | #define ECRYPTFS_VERSIONING_MASK (ECRYPTFS_VERSIONING_PASSPHRASE \ |
48 | | ECRYPTFS_VERSIONING_PLAINTEXT_PASSTHROUGH) | 52 | | ECRYPTFS_VERSIONING_PLAINTEXT_PASSTHROUGH \ |
49 | 53 | | ECRYPTFS_VERSIONING_PUBKEY \ | |
54 | | ECRYPTFS_VERSIONING_XATTR) | ||
50 | #define ECRYPTFS_MAX_PASSWORD_LENGTH 64 | 55 | #define ECRYPTFS_MAX_PASSWORD_LENGTH 64 |
51 | #define ECRYPTFS_MAX_PASSPHRASE_BYTES ECRYPTFS_MAX_PASSWORD_LENGTH | 56 | #define ECRYPTFS_MAX_PASSPHRASE_BYTES ECRYPTFS_MAX_PASSWORD_LENGTH |
52 | #define ECRYPTFS_SALT_SIZE 8 | 57 | #define ECRYPTFS_SALT_SIZE 8 |
@@ -60,10 +65,25 @@ | |||
60 | #define ECRYPTFS_MAX_KEY_BYTES 64 | 65 | #define ECRYPTFS_MAX_KEY_BYTES 64 |
61 | #define ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES 512 | 66 | #define ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES 512 |
62 | #define ECRYPTFS_DEFAULT_IV_BYTES 16 | 67 | #define ECRYPTFS_DEFAULT_IV_BYTES 16 |
63 | #define ECRYPTFS_FILE_VERSION 0x01 | 68 | #define ECRYPTFS_FILE_VERSION 0x02 |
64 | #define ECRYPTFS_DEFAULT_HEADER_EXTENT_SIZE 8192 | 69 | #define ECRYPTFS_DEFAULT_HEADER_EXTENT_SIZE 8192 |
65 | #define ECRYPTFS_DEFAULT_EXTENT_SIZE 4096 | 70 | #define ECRYPTFS_DEFAULT_EXTENT_SIZE 4096 |
66 | #define ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE 8192 | 71 | #define ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE 8192 |
72 | #define ECRYPTFS_DEFAULT_MSG_CTX_ELEMS 32 | ||
73 | #define ECRYPTFS_DEFAULT_SEND_TIMEOUT HZ | ||
74 | #define ECRYPTFS_MAX_MSG_CTX_TTL (HZ*3) | ||
75 | #define ECRYPTFS_NLMSG_HELO 100 | ||
76 | #define ECRYPTFS_NLMSG_QUIT 101 | ||
77 | #define ECRYPTFS_NLMSG_REQUEST 102 | ||
78 | #define ECRYPTFS_NLMSG_RESPONSE 103 | ||
79 | #define ECRYPTFS_MAX_PKI_NAME_BYTES 16 | ||
80 | #define ECRYPTFS_DEFAULT_NUM_USERS 4 | ||
81 | #define ECRYPTFS_MAX_NUM_USERS 32768 | ||
82 | #define ECRYPTFS_TRANSPORT_NETLINK 0 | ||
83 | #define ECRYPTFS_TRANSPORT_CONNECTOR 1 | ||
84 | #define ECRYPTFS_TRANSPORT_RELAYFS 2 | ||
85 | #define ECRYPTFS_DEFAULT_TRANSPORT ECRYPTFS_TRANSPORT_NETLINK | ||
86 | #define ECRYPTFS_XATTR_NAME "user.ecryptfs" | ||
67 | 87 | ||
68 | #define RFC2440_CIPHER_DES3_EDE 0x02 | 88 | #define RFC2440_CIPHER_DES3_EDE 0x02 |
69 | #define RFC2440_CIPHER_CAST_5 0x03 | 89 | #define RFC2440_CIPHER_CAST_5 0x03 |
@@ -74,9 +94,7 @@ | |||
74 | #define RFC2440_CIPHER_TWOFISH 0x0a | 94 | #define RFC2440_CIPHER_TWOFISH 0x0a |
75 | #define RFC2440_CIPHER_CAST_6 0x0b | 95 | #define RFC2440_CIPHER_CAST_6 0x0b |
76 | 96 | ||
77 | #define ECRYPTFS_SET_FLAG(flag_bit_vector, flag) (flag_bit_vector |= (flag)) | 97 | #define RFC2440_CIPHER_RSA 0x01 |
78 | #define ECRYPTFS_CLEAR_FLAG(flag_bit_vector, flag) (flag_bit_vector &= ~(flag)) | ||
79 | #define ECRYPTFS_CHECK_FLAG(flag_bit_vector, flag) (flag_bit_vector & (flag)) | ||
80 | 98 | ||
81 | /** | 99 | /** |
82 | * For convenience, we may need to pass around the encrypted session | 100 | * For convenience, we may need to pass around the encrypted session |
@@ -114,6 +132,14 @@ struct ecryptfs_password { | |||
114 | 132 | ||
115 | enum ecryptfs_token_types {ECRYPTFS_PASSWORD, ECRYPTFS_PRIVATE_KEY}; | 133 | enum ecryptfs_token_types {ECRYPTFS_PASSWORD, ECRYPTFS_PRIVATE_KEY}; |
116 | 134 | ||
135 | struct ecryptfs_private_key { | ||
136 | u32 key_size; | ||
137 | u32 data_len; | ||
138 | u8 signature[ECRYPTFS_PASSWORD_SIG_SIZE + 1]; | ||
139 | char pki_type[ECRYPTFS_MAX_PKI_NAME_BYTES + 1]; | ||
140 | u8 data[]; | ||
141 | }; | ||
142 | |||
117 | /* May be a password or a private key */ | 143 | /* May be a password or a private key */ |
118 | struct ecryptfs_auth_tok { | 144 | struct ecryptfs_auth_tok { |
119 | u16 version; /* 8-bit major and 8-bit minor */ | 145 | u16 version; /* 8-bit major and 8-bit minor */ |
@@ -123,7 +149,7 @@ struct ecryptfs_auth_tok { | |||
123 | u8 reserved[32]; | 149 | u8 reserved[32]; |
124 | union { | 150 | union { |
125 | struct ecryptfs_password password; | 151 | struct ecryptfs_password password; |
126 | /* Private key is in future eCryptfs releases */ | 152 | struct ecryptfs_private_key private_key; |
127 | } token; | 153 | } token; |
128 | } __attribute__ ((packed)); | 154 | } __attribute__ ((packed)); |
129 | 155 | ||
@@ -176,10 +202,14 @@ ecryptfs_get_key_payload_data(struct key *key) | |||
176 | #define ECRYPTFS_FILE_SIZE_BYTES 8 | 202 | #define ECRYPTFS_FILE_SIZE_BYTES 8 |
177 | #define ECRYPTFS_DEFAULT_CIPHER "aes" | 203 | #define ECRYPTFS_DEFAULT_CIPHER "aes" |
178 | #define ECRYPTFS_DEFAULT_KEY_BYTES 16 | 204 | #define ECRYPTFS_DEFAULT_KEY_BYTES 16 |
179 | #define ECRYPTFS_DEFAULT_CHAINING_MODE CRYPTO_TFM_MODE_CBC | ||
180 | #define ECRYPTFS_DEFAULT_HASH "md5" | 205 | #define ECRYPTFS_DEFAULT_HASH "md5" |
206 | #define ECRYPTFS_TAG_1_PACKET_TYPE 0x01 | ||
181 | #define ECRYPTFS_TAG_3_PACKET_TYPE 0x8C | 207 | #define ECRYPTFS_TAG_3_PACKET_TYPE 0x8C |
182 | #define ECRYPTFS_TAG_11_PACKET_TYPE 0xED | 208 | #define ECRYPTFS_TAG_11_PACKET_TYPE 0xED |
209 | #define ECRYPTFS_TAG_64_PACKET_TYPE 0x40 | ||
210 | #define ECRYPTFS_TAG_65_PACKET_TYPE 0x41 | ||
211 | #define ECRYPTFS_TAG_66_PACKET_TYPE 0x42 | ||
212 | #define ECRYPTFS_TAG_67_PACKET_TYPE 0x43 | ||
183 | #define MD5_DIGEST_SIZE 16 | 213 | #define MD5_DIGEST_SIZE 16 |
184 | 214 | ||
185 | /** | 215 | /** |
@@ -196,6 +226,8 @@ struct ecryptfs_crypt_stat { | |||
196 | #define ECRYPTFS_ENABLE_HMAC 0x00000020 | 226 | #define ECRYPTFS_ENABLE_HMAC 0x00000020 |
197 | #define ECRYPTFS_ENCRYPT_IV_PAGES 0x00000040 | 227 | #define ECRYPTFS_ENCRYPT_IV_PAGES 0x00000040 |
198 | #define ECRYPTFS_KEY_VALID 0x00000080 | 228 | #define ECRYPTFS_KEY_VALID 0x00000080 |
229 | #define ECRYPTFS_METADATA_IN_XATTR 0x00000100 | ||
230 | #define ECRYPTFS_VIEW_AS_ENCRYPTED 0x00000200 | ||
199 | u32 flags; | 231 | u32 flags; |
200 | unsigned int file_version; | 232 | unsigned int file_version; |
201 | size_t iv_bytes; | 233 | size_t iv_bytes; |
@@ -242,6 +274,8 @@ struct ecryptfs_dentry_info { | |||
242 | struct ecryptfs_mount_crypt_stat { | 274 | struct ecryptfs_mount_crypt_stat { |
243 | /* Pointers to memory we do not own, do not free these */ | 275 | /* Pointers to memory we do not own, do not free these */ |
244 | #define ECRYPTFS_PLAINTEXT_PASSTHROUGH_ENABLED 0x00000001 | 276 | #define ECRYPTFS_PLAINTEXT_PASSTHROUGH_ENABLED 0x00000001 |
277 | #define ECRYPTFS_XATTR_METADATA_ENABLED 0x00000002 | ||
278 | #define ECRYPTFS_ENCRYPTED_VIEW_ENABLED 0x00000004 | ||
245 | u32 flags; | 279 | u32 flags; |
246 | struct ecryptfs_auth_tok *global_auth_tok; | 280 | struct ecryptfs_auth_tok *global_auth_tok; |
247 | struct key *global_auth_tok_key; | 281 | struct key *global_auth_tok_key; |
@@ -272,6 +306,33 @@ struct ecryptfs_auth_tok_list_item { | |||
272 | struct ecryptfs_auth_tok auth_tok; | 306 | struct ecryptfs_auth_tok auth_tok; |
273 | }; | 307 | }; |
274 | 308 | ||
309 | struct ecryptfs_message { | ||
310 | u32 index; | ||
311 | u32 data_len; | ||
312 | u8 data[]; | ||
313 | }; | ||
314 | |||
315 | struct ecryptfs_msg_ctx { | ||
316 | #define ECRYPTFS_MSG_CTX_STATE_FREE 0x0001 | ||
317 | #define ECRYPTFS_MSG_CTX_STATE_PENDING 0x0002 | ||
318 | #define ECRYPTFS_MSG_CTX_STATE_DONE 0x0003 | ||
319 | u32 state; | ||
320 | unsigned int index; | ||
321 | unsigned int counter; | ||
322 | struct ecryptfs_message *msg; | ||
323 | struct task_struct *task; | ||
324 | struct list_head node; | ||
325 | struct mutex mux; | ||
326 | }; | ||
327 | |||
328 | extern unsigned int ecryptfs_transport; | ||
329 | |||
330 | struct ecryptfs_daemon_id { | ||
331 | pid_t pid; | ||
332 | uid_t uid; | ||
333 | struct hlist_node id_chain; | ||
334 | }; | ||
335 | |||
275 | static inline struct ecryptfs_file_info * | 336 | static inline struct ecryptfs_file_info * |
276 | ecryptfs_file_to_private(struct file *file) | 337 | ecryptfs_file_to_private(struct file *file) |
277 | { | 338 | { |
@@ -385,13 +446,16 @@ void __ecryptfs_printk(const char *fmt, ...); | |||
385 | 446 | ||
386 | extern const struct file_operations ecryptfs_main_fops; | 447 | extern const struct file_operations ecryptfs_main_fops; |
387 | extern const struct file_operations ecryptfs_dir_fops; | 448 | extern const struct file_operations ecryptfs_dir_fops; |
388 | extern struct inode_operations ecryptfs_main_iops; | 449 | extern const struct inode_operations ecryptfs_main_iops; |
389 | extern struct inode_operations ecryptfs_dir_iops; | 450 | extern const struct inode_operations ecryptfs_dir_iops; |
390 | extern struct inode_operations ecryptfs_symlink_iops; | 451 | extern const struct inode_operations ecryptfs_symlink_iops; |
391 | extern struct super_operations ecryptfs_sops; | 452 | extern const struct super_operations ecryptfs_sops; |
392 | extern struct dentry_operations ecryptfs_dops; | 453 | extern struct dentry_operations ecryptfs_dops; |
393 | extern struct address_space_operations ecryptfs_aops; | 454 | extern struct address_space_operations ecryptfs_aops; |
394 | extern int ecryptfs_verbosity; | 455 | extern int ecryptfs_verbosity; |
456 | extern unsigned int ecryptfs_message_buf_len; | ||
457 | extern signed long ecryptfs_message_wait_timeout; | ||
458 | extern unsigned int ecryptfs_number_of_users; | ||
395 | 459 | ||
396 | extern struct kmem_cache *ecryptfs_auth_tok_list_item_cache; | 460 | extern struct kmem_cache *ecryptfs_auth_tok_list_item_cache; |
397 | extern struct kmem_cache *ecryptfs_file_info_cache; | 461 | extern struct kmem_cache *ecryptfs_file_info_cache; |
@@ -401,6 +465,7 @@ extern struct kmem_cache *ecryptfs_sb_info_cache; | |||
401 | extern struct kmem_cache *ecryptfs_header_cache_0; | 465 | extern struct kmem_cache *ecryptfs_header_cache_0; |
402 | extern struct kmem_cache *ecryptfs_header_cache_1; | 466 | extern struct kmem_cache *ecryptfs_header_cache_1; |
403 | extern struct kmem_cache *ecryptfs_header_cache_2; | 467 | extern struct kmem_cache *ecryptfs_header_cache_2; |
468 | extern struct kmem_cache *ecryptfs_xattr_cache; | ||
404 | extern struct kmem_cache *ecryptfs_lower_page_cache; | 469 | extern struct kmem_cache *ecryptfs_lower_page_cache; |
405 | 470 | ||
406 | int ecryptfs_interpose(struct dentry *hidden_dentry, | 471 | int ecryptfs_interpose(struct dentry *hidden_dentry, |
@@ -427,9 +492,13 @@ int ecryptfs_init_crypt_ctx(struct ecryptfs_crypt_stat *crypt_stat); | |||
427 | int ecryptfs_crypto_api_algify_cipher_name(char **algified_name, | 492 | int ecryptfs_crypto_api_algify_cipher_name(char **algified_name, |
428 | char *cipher_name, | 493 | char *cipher_name, |
429 | char *chaining_modifier); | 494 | char *chaining_modifier); |
430 | int ecryptfs_write_inode_size_to_header(struct file *lower_file, | 495 | #define ECRYPTFS_LOWER_I_MUTEX_NOT_HELD 0 |
431 | struct inode *lower_inode, | 496 | #define ECRYPTFS_LOWER_I_MUTEX_HELD 1 |
432 | struct inode *inode); | 497 | int ecryptfs_write_inode_size_to_metadata(struct file *lower_file, |
498 | struct inode *lower_inode, | ||
499 | struct inode *inode, | ||
500 | struct dentry *ecryptfs_dentry, | ||
501 | int lower_i_mutex_held); | ||
433 | int ecryptfs_get_lower_page(struct page **lower_page, struct inode *lower_inode, | 502 | int ecryptfs_get_lower_page(struct page **lower_page, struct inode *lower_inode, |
434 | struct file *lower_file, | 503 | struct file *lower_file, |
435 | unsigned long lower_page_index, int byte_offset, | 504 | unsigned long lower_page_index, int byte_offset, |
@@ -442,26 +511,20 @@ int ecryptfs_copy_page_to_lower(struct page *page, struct inode *lower_inode, | |||
442 | struct file *lower_file); | 511 | struct file *lower_file); |
443 | int ecryptfs_do_readpage(struct file *file, struct page *page, | 512 | int ecryptfs_do_readpage(struct file *file, struct page *page, |
444 | pgoff_t lower_page_index); | 513 | pgoff_t lower_page_index); |
445 | int ecryptfs_grab_and_map_lower_page(struct page **lower_page, | ||
446 | char **lower_virt, | ||
447 | struct inode *lower_inode, | ||
448 | unsigned long lower_page_index); | ||
449 | int ecryptfs_writepage_and_release_lower_page(struct page *lower_page, | 514 | int ecryptfs_writepage_and_release_lower_page(struct page *lower_page, |
450 | struct inode *lower_inode, | 515 | struct inode *lower_inode, |
451 | struct writeback_control *wbc); | 516 | struct writeback_control *wbc); |
452 | int ecryptfs_encrypt_page(struct ecryptfs_page_crypt_context *ctx); | 517 | int ecryptfs_encrypt_page(struct ecryptfs_page_crypt_context *ctx); |
453 | int ecryptfs_decrypt_page(struct file *file, struct page *page); | 518 | int ecryptfs_decrypt_page(struct file *file, struct page *page); |
454 | int ecryptfs_write_headers(struct dentry *ecryptfs_dentry, | 519 | int ecryptfs_write_metadata(struct dentry *ecryptfs_dentry, |
520 | struct file *lower_file); | ||
521 | int ecryptfs_read_metadata(struct dentry *ecryptfs_dentry, | ||
455 | struct file *lower_file); | 522 | struct file *lower_file); |
456 | int ecryptfs_write_headers_virt(char *page_virt, | ||
457 | struct ecryptfs_crypt_stat *crypt_stat, | ||
458 | struct dentry *ecryptfs_dentry); | ||
459 | int ecryptfs_read_headers(struct dentry *ecryptfs_dentry, | ||
460 | struct file *lower_file); | ||
461 | int ecryptfs_new_file_context(struct dentry *ecryptfs_dentry); | 523 | int ecryptfs_new_file_context(struct dentry *ecryptfs_dentry); |
462 | int contains_ecryptfs_marker(char *data); | 524 | int ecryptfs_read_and_validate_header_region(char *data, struct dentry *dentry, |
463 | int ecryptfs_read_header_region(char *data, struct dentry *dentry, | 525 | struct vfsmount *mnt); |
464 | struct vfsmount *mnt); | 526 | int ecryptfs_read_and_validate_xattr_region(char *page_virt, |
527 | struct dentry *ecryptfs_dentry); | ||
465 | u16 ecryptfs_code_for_cipher_string(struct ecryptfs_crypt_stat *crypt_stat); | 528 | u16 ecryptfs_code_for_cipher_string(struct ecryptfs_crypt_stat *crypt_stat); |
466 | int ecryptfs_cipher_code_to_string(char *str, u16 cipher_code); | 529 | int ecryptfs_cipher_code_to_string(char *str, u16 cipher_code); |
467 | void ecryptfs_set_default_sizes(struct ecryptfs_crypt_stat *crypt_stat); | 530 | void ecryptfs_set_default_sizes(struct ecryptfs_crypt_stat *crypt_stat); |
@@ -484,5 +547,37 @@ int ecryptfs_open_lower_file(struct file **lower_file, | |||
484 | struct dentry *lower_dentry, | 547 | struct dentry *lower_dentry, |
485 | struct vfsmount *lower_mnt, int flags); | 548 | struct vfsmount *lower_mnt, int flags); |
486 | int ecryptfs_close_lower_file(struct file *lower_file); | 549 | int ecryptfs_close_lower_file(struct file *lower_file); |
550 | ssize_t ecryptfs_getxattr(struct dentry *dentry, const char *name, void *value, | ||
551 | size_t size); | ||
552 | int | ||
553 | ecryptfs_setxattr(struct dentry *dentry, const char *name, const void *value, | ||
554 | size_t size, int flags); | ||
555 | int ecryptfs_read_xattr_region(char *page_virt, struct dentry *ecryptfs_dentry); | ||
556 | int ecryptfs_process_helo(unsigned int transport, uid_t uid, pid_t pid); | ||
557 | int ecryptfs_process_quit(uid_t uid, pid_t pid); | ||
558 | int ecryptfs_process_response(struct ecryptfs_message *msg, uid_t uid, | ||
559 | pid_t pid, u32 seq); | ||
560 | int ecryptfs_send_message(unsigned int transport, char *data, int data_len, | ||
561 | struct ecryptfs_msg_ctx **msg_ctx); | ||
562 | int ecryptfs_wait_for_response(struct ecryptfs_msg_ctx *msg_ctx, | ||
563 | struct ecryptfs_message **emsg); | ||
564 | int ecryptfs_init_messaging(unsigned int transport); | ||
565 | void ecryptfs_release_messaging(unsigned int transport); | ||
566 | |||
567 | int ecryptfs_send_netlink(char *data, int data_len, | ||
568 | struct ecryptfs_msg_ctx *msg_ctx, u16 msg_type, | ||
569 | u16 msg_flags, pid_t daemon_pid); | ||
570 | int ecryptfs_init_netlink(void); | ||
571 | void ecryptfs_release_netlink(void); | ||
572 | |||
573 | int ecryptfs_send_connector(char *data, int data_len, | ||
574 | struct ecryptfs_msg_ctx *msg_ctx, u16 msg_type, | ||
575 | u16 msg_flags, pid_t daemon_pid); | ||
576 | int ecryptfs_init_connector(void); | ||
577 | void ecryptfs_release_connector(void); | ||
578 | void | ||
579 | ecryptfs_write_header_metadata(char *virt, | ||
580 | struct ecryptfs_crypt_stat *crypt_stat, | ||
581 | size_t *written); | ||
487 | 582 | ||
488 | #endif /* #ifndef ECRYPTFS_KERNEL_H */ | 583 | #endif /* #ifndef ECRYPTFS_KERNEL_H */ |
diff --git a/fs/ecryptfs/file.c b/fs/ecryptfs/file.c index c5a2e5298f15..bd969adf70d7 100644 --- a/fs/ecryptfs/file.c +++ b/fs/ecryptfs/file.c | |||
@@ -3,7 +3,7 @@ | |||
3 | * | 3 | * |
4 | * Copyright (C) 1997-2004 Erez Zadok | 4 | * Copyright (C) 1997-2004 Erez Zadok |
5 | * Copyright (C) 2001-2004 Stony Brook University | 5 | * Copyright (C) 2001-2004 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 <mhalcrow@us.ibm.com> | 7 | * Author(s): Michael A. Halcrow <mhalcrow@us.ibm.com> |
8 | * Michael C. Thompson <mcthomps@us.ibm.com> | 8 | * Michael C. Thompson <mcthomps@us.ibm.com> |
9 | * | 9 | * |
@@ -250,8 +250,19 @@ static int ecryptfs_open(struct inode *inode, struct file *file) | |||
250 | struct ecryptfs_file_info *file_info; | 250 | struct ecryptfs_file_info *file_info; |
251 | int lower_flags; | 251 | int lower_flags; |
252 | 252 | ||
253 | mount_crypt_stat = &ecryptfs_superblock_to_private( | ||
254 | ecryptfs_dentry->d_sb)->mount_crypt_stat; | ||
255 | if ((mount_crypt_stat->flags & ECRYPTFS_ENCRYPTED_VIEW_ENABLED) | ||
256 | && ((file->f_flags & O_WRONLY) || (file->f_flags & O_RDWR) | ||
257 | || (file->f_flags & O_CREAT) || (file->f_flags & O_TRUNC) | ||
258 | || (file->f_flags & O_APPEND))) { | ||
259 | printk(KERN_WARNING "Mount has encrypted view enabled; " | ||
260 | "files may only be read\n"); | ||
261 | rc = -EPERM; | ||
262 | goto out; | ||
263 | } | ||
253 | /* Released in ecryptfs_release or end of function if failure */ | 264 | /* Released in ecryptfs_release or end of function if failure */ |
254 | file_info = kmem_cache_alloc(ecryptfs_file_info_cache, GFP_KERNEL); | 265 | file_info = kmem_cache_zalloc(ecryptfs_file_info_cache, GFP_KERNEL); |
255 | ecryptfs_set_file_private(file, file_info); | 266 | ecryptfs_set_file_private(file, file_info); |
256 | if (!file_info) { | 267 | if (!file_info) { |
257 | ecryptfs_printk(KERN_ERR, | 268 | ecryptfs_printk(KERN_ERR, |
@@ -259,17 +270,14 @@ static int ecryptfs_open(struct inode *inode, struct file *file) | |||
259 | rc = -ENOMEM; | 270 | rc = -ENOMEM; |
260 | goto out; | 271 | goto out; |
261 | } | 272 | } |
262 | memset(file_info, 0, sizeof(*file_info)); | ||
263 | lower_dentry = ecryptfs_dentry_to_lower(ecryptfs_dentry); | 273 | lower_dentry = ecryptfs_dentry_to_lower(ecryptfs_dentry); |
264 | crypt_stat = &ecryptfs_inode_to_private(inode)->crypt_stat; | 274 | crypt_stat = &ecryptfs_inode_to_private(inode)->crypt_stat; |
265 | mount_crypt_stat = &ecryptfs_superblock_to_private( | ||
266 | ecryptfs_dentry->d_sb)->mount_crypt_stat; | ||
267 | mutex_lock(&crypt_stat->cs_mutex); | 275 | mutex_lock(&crypt_stat->cs_mutex); |
268 | if (!ECRYPTFS_CHECK_FLAG(crypt_stat->flags, ECRYPTFS_POLICY_APPLIED)) { | 276 | if (!(crypt_stat->flags & ECRYPTFS_POLICY_APPLIED)) { |
269 | ecryptfs_printk(KERN_DEBUG, "Setting flags for stat...\n"); | 277 | ecryptfs_printk(KERN_DEBUG, "Setting flags for stat...\n"); |
270 | /* Policy code enabled in future release */ | 278 | /* Policy code enabled in future release */ |
271 | ECRYPTFS_SET_FLAG(crypt_stat->flags, ECRYPTFS_POLICY_APPLIED); | 279 | crypt_stat->flags |= ECRYPTFS_POLICY_APPLIED; |
272 | ECRYPTFS_SET_FLAG(crypt_stat->flags, ECRYPTFS_ENCRYPTED); | 280 | crypt_stat->flags |= ECRYPTFS_ENCRYPTED; |
273 | } | 281 | } |
274 | mutex_unlock(&crypt_stat->cs_mutex); | 282 | mutex_unlock(&crypt_stat->cs_mutex); |
275 | lower_flags = file->f_flags; | 283 | lower_flags = file->f_flags; |
@@ -289,31 +297,14 @@ static int ecryptfs_open(struct inode *inode, struct file *file) | |||
289 | lower_inode = lower_dentry->d_inode; | 297 | lower_inode = lower_dentry->d_inode; |
290 | if (S_ISDIR(ecryptfs_dentry->d_inode->i_mode)) { | 298 | if (S_ISDIR(ecryptfs_dentry->d_inode->i_mode)) { |
291 | ecryptfs_printk(KERN_DEBUG, "This is a directory\n"); | 299 | ecryptfs_printk(KERN_DEBUG, "This is a directory\n"); |
292 | ECRYPTFS_CLEAR_FLAG(crypt_stat->flags, ECRYPTFS_ENCRYPTED); | 300 | crypt_stat->flags &= ~(ECRYPTFS_ENCRYPTED); |
293 | rc = 0; | 301 | rc = 0; |
294 | goto out; | 302 | goto out; |
295 | } | 303 | } |
296 | mutex_lock(&crypt_stat->cs_mutex); | 304 | mutex_lock(&crypt_stat->cs_mutex); |
297 | if (i_size_read(lower_inode) < ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE) { | 305 | if (!(crypt_stat->flags & ECRYPTFS_POLICY_APPLIED) |
298 | if (!(mount_crypt_stat->flags | 306 | || !(crypt_stat->flags & ECRYPTFS_KEY_VALID)) { |
299 | & ECRYPTFS_PLAINTEXT_PASSTHROUGH_ENABLED)) { | 307 | rc = ecryptfs_read_metadata(ecryptfs_dentry, lower_file); |
300 | rc = -EIO; | ||
301 | printk(KERN_WARNING "Attempt to read file that is " | ||
302 | "not in a valid eCryptfs format, and plaintext " | ||
303 | "passthrough mode is not enabled; returning " | ||
304 | "-EIO\n"); | ||
305 | mutex_unlock(&crypt_stat->cs_mutex); | ||
306 | goto out_puts; | ||
307 | } | ||
308 | crypt_stat->flags &= ~(ECRYPTFS_ENCRYPTED); | ||
309 | rc = 0; | ||
310 | mutex_unlock(&crypt_stat->cs_mutex); | ||
311 | goto out; | ||
312 | } else if (!ECRYPTFS_CHECK_FLAG(crypt_stat->flags, | ||
313 | ECRYPTFS_POLICY_APPLIED) | ||
314 | || !ECRYPTFS_CHECK_FLAG(crypt_stat->flags, | ||
315 | ECRYPTFS_KEY_VALID)) { | ||
316 | rc = ecryptfs_read_headers(ecryptfs_dentry, lower_file); | ||
317 | if (rc) { | 308 | if (rc) { |
318 | ecryptfs_printk(KERN_DEBUG, | 309 | ecryptfs_printk(KERN_DEBUG, |
319 | "Valid headers not found\n"); | 310 | "Valid headers not found\n"); |
@@ -327,9 +318,8 @@ static int ecryptfs_open(struct inode *inode, struct file *file) | |||
327 | mutex_unlock(&crypt_stat->cs_mutex); | 318 | mutex_unlock(&crypt_stat->cs_mutex); |
328 | goto out_puts; | 319 | goto out_puts; |
329 | } | 320 | } |
330 | ECRYPTFS_CLEAR_FLAG(crypt_stat->flags, | ||
331 | ECRYPTFS_ENCRYPTED); | ||
332 | rc = 0; | 321 | rc = 0; |
322 | crypt_stat->flags &= ~(ECRYPTFS_ENCRYPTED); | ||
333 | mutex_unlock(&crypt_stat->cs_mutex); | 323 | mutex_unlock(&crypt_stat->cs_mutex); |
334 | goto out; | 324 | goto out; |
335 | } | 325 | } |
diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c index 11f5e5076aef..9fa7e0b27a96 100644 --- a/fs/ecryptfs/inode.c +++ b/fs/ecryptfs/inode.c | |||
@@ -3,7 +3,7 @@ | |||
3 | * | 3 | * |
4 | * Copyright (C) 1997-2004 Erez Zadok | 4 | * Copyright (C) 1997-2004 Erez Zadok |
5 | * Copyright (C) 2001-2004 Stony Brook University | 5 | * Copyright (C) 2001-2004 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. Thompsion <mcthomps@us.ibm.com> | 8 | * Michael C. Thompsion <mcthomps@us.ibm.com> |
9 | * | 9 | * |
@@ -161,17 +161,17 @@ static int grow_file(struct dentry *ecryptfs_dentry, struct file *lower_file, | |||
161 | ecryptfs_set_file_lower(&fake_file, lower_file); | 161 | ecryptfs_set_file_lower(&fake_file, lower_file); |
162 | rc = ecryptfs_fill_zeros(&fake_file, 1); | 162 | rc = ecryptfs_fill_zeros(&fake_file, 1); |
163 | if (rc) { | 163 | if (rc) { |
164 | ECRYPTFS_SET_FLAG( | 164 | ecryptfs_inode_to_private(inode)->crypt_stat.flags |= |
165 | ecryptfs_inode_to_private(inode)->crypt_stat.flags, | 165 | ECRYPTFS_SECURITY_WARNING; |
166 | ECRYPTFS_SECURITY_WARNING); | ||
167 | ecryptfs_printk(KERN_WARNING, "Error attempting to fill zeros " | 166 | ecryptfs_printk(KERN_WARNING, "Error attempting to fill zeros " |
168 | "in file; rc = [%d]\n", rc); | 167 | "in file; rc = [%d]\n", rc); |
169 | goto out; | 168 | goto out; |
170 | } | 169 | } |
171 | i_size_write(inode, 0); | 170 | i_size_write(inode, 0); |
172 | ecryptfs_write_inode_size_to_header(lower_file, lower_inode, inode); | 171 | ecryptfs_write_inode_size_to_metadata(lower_file, lower_inode, inode, |
173 | ECRYPTFS_SET_FLAG(ecryptfs_inode_to_private(inode)->crypt_stat.flags, | 172 | ecryptfs_dentry, |
174 | ECRYPTFS_NEW_FILE); | 173 | ECRYPTFS_LOWER_I_MUTEX_NOT_HELD); |
174 | ecryptfs_inode_to_private(inode)->crypt_stat.flags |= ECRYPTFS_NEW_FILE; | ||
175 | out: | 175 | out: |
176 | return rc; | 176 | return rc; |
177 | } | 177 | } |
@@ -199,7 +199,7 @@ static int ecryptfs_initialize_file(struct dentry *ecryptfs_dentry) | |||
199 | lower_dentry->d_name.name); | 199 | lower_dentry->d_name.name); |
200 | inode = ecryptfs_dentry->d_inode; | 200 | inode = ecryptfs_dentry->d_inode; |
201 | crypt_stat = &ecryptfs_inode_to_private(inode)->crypt_stat; | 201 | crypt_stat = &ecryptfs_inode_to_private(inode)->crypt_stat; |
202 | lower_flags = ((O_CREAT | O_WRONLY | O_TRUNC) & O_ACCMODE) | O_RDWR; | 202 | lower_flags = ((O_CREAT | O_TRUNC) & O_ACCMODE) | O_RDWR; |
203 | #if BITS_PER_LONG != 32 | 203 | #if BITS_PER_LONG != 32 |
204 | lower_flags |= O_LARGEFILE; | 204 | lower_flags |= O_LARGEFILE; |
205 | #endif | 205 | #endif |
@@ -214,10 +214,10 @@ static int ecryptfs_initialize_file(struct dentry *ecryptfs_dentry) | |||
214 | lower_inode = lower_dentry->d_inode; | 214 | lower_inode = lower_dentry->d_inode; |
215 | if (S_ISDIR(ecryptfs_dentry->d_inode->i_mode)) { | 215 | if (S_ISDIR(ecryptfs_dentry->d_inode->i_mode)) { |
216 | ecryptfs_printk(KERN_DEBUG, "This is a directory\n"); | 216 | ecryptfs_printk(KERN_DEBUG, "This is a directory\n"); |
217 | ECRYPTFS_CLEAR_FLAG(crypt_stat->flags, ECRYPTFS_ENCRYPTED); | 217 | crypt_stat->flags &= ~(ECRYPTFS_ENCRYPTED); |
218 | goto out_fput; | 218 | goto out_fput; |
219 | } | 219 | } |
220 | ECRYPTFS_SET_FLAG(crypt_stat->flags, ECRYPTFS_NEW_FILE); | 220 | crypt_stat->flags |= ECRYPTFS_NEW_FILE; |
221 | ecryptfs_printk(KERN_DEBUG, "Initializing crypto context\n"); | 221 | ecryptfs_printk(KERN_DEBUG, "Initializing crypto context\n"); |
222 | rc = ecryptfs_new_file_context(ecryptfs_dentry); | 222 | rc = ecryptfs_new_file_context(ecryptfs_dentry); |
223 | if (rc) { | 223 | if (rc) { |
@@ -225,7 +225,7 @@ static int ecryptfs_initialize_file(struct dentry *ecryptfs_dentry) | |||
225 | "context\n"); | 225 | "context\n"); |
226 | goto out_fput; | 226 | goto out_fput; |
227 | } | 227 | } |
228 | rc = ecryptfs_write_headers(ecryptfs_dentry, lower_file); | 228 | rc = ecryptfs_write_metadata(ecryptfs_dentry, lower_file); |
229 | if (rc) { | 229 | if (rc) { |
230 | ecryptfs_printk(KERN_DEBUG, "Error writing headers\n"); | 230 | ecryptfs_printk(KERN_DEBUG, "Error writing headers\n"); |
231 | goto out_fput; | 231 | goto out_fput; |
@@ -287,6 +287,7 @@ static struct dentry *ecryptfs_lookup(struct inode *dir, struct dentry *dentry, | |||
287 | char *encoded_name; | 287 | char *encoded_name; |
288 | unsigned int encoded_namelen; | 288 | unsigned int encoded_namelen; |
289 | struct ecryptfs_crypt_stat *crypt_stat = NULL; | 289 | struct ecryptfs_crypt_stat *crypt_stat = NULL; |
290 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat; | ||
290 | char *page_virt = NULL; | 291 | char *page_virt = NULL; |
291 | struct inode *lower_inode; | 292 | struct inode *lower_inode; |
292 | u64 file_size; | 293 | u64 file_size; |
@@ -361,34 +362,44 @@ static struct dentry *ecryptfs_lookup(struct inode *dir, struct dentry *dentry, | |||
361 | goto out; | 362 | goto out; |
362 | } | 363 | } |
363 | /* Released in this function */ | 364 | /* Released in this function */ |
364 | page_virt = | 365 | page_virt = kmem_cache_zalloc(ecryptfs_header_cache_2, |
365 | (char *)kmem_cache_alloc(ecryptfs_header_cache_2, | 366 | GFP_USER); |
366 | GFP_USER); | ||
367 | if (!page_virt) { | 367 | if (!page_virt) { |
368 | rc = -ENOMEM; | 368 | rc = -ENOMEM; |
369 | ecryptfs_printk(KERN_ERR, | 369 | ecryptfs_printk(KERN_ERR, |
370 | "Cannot ecryptfs_kmalloc a page\n"); | 370 | "Cannot ecryptfs_kmalloc a page\n"); |
371 | goto out_dput; | 371 | goto out_dput; |
372 | } | 372 | } |
373 | memset(page_virt, 0, PAGE_CACHE_SIZE); | ||
374 | rc = ecryptfs_read_header_region(page_virt, lower_dentry, nd->mnt); | ||
375 | crypt_stat = &ecryptfs_inode_to_private(dentry->d_inode)->crypt_stat; | 373 | crypt_stat = &ecryptfs_inode_to_private(dentry->d_inode)->crypt_stat; |
376 | if (!ECRYPTFS_CHECK_FLAG(crypt_stat->flags, ECRYPTFS_POLICY_APPLIED)) | 374 | if (!(crypt_stat->flags & ECRYPTFS_POLICY_APPLIED)) |
377 | ecryptfs_set_default_sizes(crypt_stat); | 375 | ecryptfs_set_default_sizes(crypt_stat); |
376 | rc = ecryptfs_read_and_validate_header_region(page_virt, lower_dentry, | ||
377 | nd->mnt); | ||
378 | if (rc) { | 378 | if (rc) { |
379 | rc = 0; | 379 | rc = ecryptfs_read_and_validate_xattr_region(page_virt, dentry); |
380 | ecryptfs_printk(KERN_WARNING, "Error reading header region;" | 380 | if (rc) { |
381 | " assuming unencrypted\n"); | 381 | printk(KERN_DEBUG "Valid metadata not found in header " |
382 | } else { | 382 | "region or xattr region; treating file as " |
383 | if (!contains_ecryptfs_marker(page_virt | 383 | "unencrypted\n"); |
384 | + ECRYPTFS_FILE_SIZE_BYTES)) { | 384 | rc = 0; |
385 | kmem_cache_free(ecryptfs_header_cache_2, page_virt); | 385 | kmem_cache_free(ecryptfs_header_cache_2, page_virt); |
386 | goto out; | 386 | goto out; |
387 | } | 387 | } |
388 | crypt_stat->flags |= ECRYPTFS_METADATA_IN_XATTR; | ||
389 | } | ||
390 | mount_crypt_stat = &ecryptfs_superblock_to_private( | ||
391 | dentry->d_sb)->mount_crypt_stat; | ||
392 | if (mount_crypt_stat->flags & ECRYPTFS_ENCRYPTED_VIEW_ENABLED) { | ||
393 | if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR) | ||
394 | file_size = (crypt_stat->header_extent_size | ||
395 | + i_size_read(lower_dentry->d_inode)); | ||
396 | else | ||
397 | file_size = i_size_read(lower_dentry->d_inode); | ||
398 | } else { | ||
388 | memcpy(&file_size, page_virt, sizeof(file_size)); | 399 | memcpy(&file_size, page_virt, sizeof(file_size)); |
389 | file_size = be64_to_cpu(file_size); | 400 | file_size = be64_to_cpu(file_size); |
390 | i_size_write(dentry->d_inode, (loff_t)file_size); | ||
391 | } | 401 | } |
402 | i_size_write(dentry->d_inode, (loff_t)file_size); | ||
392 | kmem_cache_free(ecryptfs_header_cache_2, page_virt); | 403 | kmem_cache_free(ecryptfs_header_cache_2, page_virt); |
393 | goto out; | 404 | goto out; |
394 | 405 | ||
@@ -782,20 +793,26 @@ int ecryptfs_truncate(struct dentry *dentry, loff_t new_length) | |||
782 | goto out_fput; | 793 | goto out_fput; |
783 | } | 794 | } |
784 | i_size_write(inode, new_length); | 795 | i_size_write(inode, new_length); |
785 | rc = ecryptfs_write_inode_size_to_header(lower_file, | 796 | rc = ecryptfs_write_inode_size_to_metadata( |
786 | lower_dentry->d_inode, | 797 | lower_file, lower_dentry->d_inode, inode, dentry, |
787 | inode); | 798 | ECRYPTFS_LOWER_I_MUTEX_NOT_HELD); |
788 | if (rc) { | 799 | if (rc) { |
789 | ecryptfs_printk(KERN_ERR, | 800 | printk(KERN_ERR "Problem with " |
790 | "Problem with ecryptfs_write" | 801 | "ecryptfs_write_inode_size_to_metadata; " |
791 | "_inode_size\n"); | 802 | "rc = [%d]\n", rc); |
792 | goto out_fput; | 803 | goto out_fput; |
793 | } | 804 | } |
794 | } else { /* new_length < i_size_read(inode) */ | 805 | } else { /* new_length < i_size_read(inode) */ |
795 | vmtruncate(inode, new_length); | 806 | vmtruncate(inode, new_length); |
796 | ecryptfs_write_inode_size_to_header(lower_file, | 807 | rc = ecryptfs_write_inode_size_to_metadata( |
797 | lower_dentry->d_inode, | 808 | lower_file, lower_dentry->d_inode, inode, dentry, |
798 | inode); | 809 | ECRYPTFS_LOWER_I_MUTEX_NOT_HELD); |
810 | if (rc) { | ||
811 | printk(KERN_ERR "Problem with " | ||
812 | "ecryptfs_write_inode_size_to_metadata; " | ||
813 | "rc = [%d]\n", rc); | ||
814 | goto out_fput; | ||
815 | } | ||
799 | /* We are reducing the size of the ecryptfs file, and need to | 816 | /* We are reducing the size of the ecryptfs file, and need to |
800 | * know if we need to reduce the size of the lower file. */ | 817 | * know if we need to reduce the size of the lower file. */ |
801 | lower_size_before_truncate = | 818 | lower_size_before_truncate = |
@@ -882,7 +899,7 @@ out: | |||
882 | return rc; | 899 | return rc; |
883 | } | 900 | } |
884 | 901 | ||
885 | static int | 902 | int |
886 | ecryptfs_setxattr(struct dentry *dentry, const char *name, const void *value, | 903 | ecryptfs_setxattr(struct dentry *dentry, const char *name, const void *value, |
887 | size_t size, int flags) | 904 | size_t size, int flags) |
888 | { | 905 | { |
@@ -902,7 +919,7 @@ out: | |||
902 | return rc; | 919 | return rc; |
903 | } | 920 | } |
904 | 921 | ||
905 | static ssize_t | 922 | ssize_t |
906 | ecryptfs_getxattr(struct dentry *dentry, const char *name, void *value, | 923 | ecryptfs_getxattr(struct dentry *dentry, const char *name, void *value, |
907 | size_t size) | 924 | size_t size) |
908 | { | 925 | { |
@@ -972,7 +989,7 @@ int ecryptfs_inode_set(struct inode *inode, void *lower_inode) | |||
972 | return 0; | 989 | return 0; |
973 | } | 990 | } |
974 | 991 | ||
975 | struct inode_operations ecryptfs_symlink_iops = { | 992 | const struct inode_operations ecryptfs_symlink_iops = { |
976 | .readlink = ecryptfs_readlink, | 993 | .readlink = ecryptfs_readlink, |
977 | .follow_link = ecryptfs_follow_link, | 994 | .follow_link = ecryptfs_follow_link, |
978 | .put_link = ecryptfs_put_link, | 995 | .put_link = ecryptfs_put_link, |
@@ -984,7 +1001,7 @@ struct inode_operations ecryptfs_symlink_iops = { | |||
984 | .removexattr = ecryptfs_removexattr | 1001 | .removexattr = ecryptfs_removexattr |
985 | }; | 1002 | }; |
986 | 1003 | ||
987 | struct inode_operations ecryptfs_dir_iops = { | 1004 | const struct inode_operations ecryptfs_dir_iops = { |
988 | .create = ecryptfs_create, | 1005 | .create = ecryptfs_create, |
989 | .lookup = ecryptfs_lookup, | 1006 | .lookup = ecryptfs_lookup, |
990 | .link = ecryptfs_link, | 1007 | .link = ecryptfs_link, |
@@ -1002,7 +1019,7 @@ struct inode_operations ecryptfs_dir_iops = { | |||
1002 | .removexattr = ecryptfs_removexattr | 1019 | .removexattr = ecryptfs_removexattr |
1003 | }; | 1020 | }; |
1004 | 1021 | ||
1005 | struct inode_operations ecryptfs_main_iops = { | 1022 | const struct inode_operations ecryptfs_main_iops = { |
1006 | .permission = ecryptfs_permission, | 1023 | .permission = ecryptfs_permission, |
1007 | .setattr = ecryptfs_setattr, | 1024 | .setattr = ecryptfs_setattr, |
1008 | .setxattr = ecryptfs_setxattr, | 1025 | .setxattr = ecryptfs_setxattr, |
diff --git a/fs/ecryptfs/keystore.c b/fs/ecryptfs/keystore.c index 745c0f1bfbbd..c209f67e7a26 100644 --- a/fs/ecryptfs/keystore.c +++ b/fs/ecryptfs/keystore.c | |||
@@ -7,6 +7,7 @@ | |||
7 | * Copyright (C) 2004-2006 International Business Machines Corp. | 7 | * Copyright (C) 2004-2006 International Business Machines Corp. |
8 | * Author(s): Michael A. Halcrow <mhalcrow@us.ibm.com> | 8 | * Author(s): Michael A. Halcrow <mhalcrow@us.ibm.com> |
9 | * Michael C. Thompson <mcthomps@us.ibm.com> | 9 | * Michael C. Thompson <mcthomps@us.ibm.com> |
10 | * Trevor S. Highland <trevor.highland@gmail.com> | ||
10 | * | 11 | * |
11 | * This program is free software; you can redistribute it and/or | 12 | * This program is free software; you can redistribute it and/or |
12 | * modify it under the terms of the GNU General Public License as | 13 | * modify it under the terms of the GNU General Public License as |
@@ -64,26 +65,6 @@ int process_request_key_err(long err_code) | |||
64 | return rc; | 65 | return rc; |
65 | } | 66 | } |
66 | 67 | ||
67 | static void wipe_auth_tok_list(struct list_head *auth_tok_list_head) | ||
68 | { | ||
69 | struct list_head *walker; | ||
70 | struct ecryptfs_auth_tok_list_item *auth_tok_list_item; | ||
71 | |||
72 | walker = auth_tok_list_head->next; | ||
73 | while (walker != auth_tok_list_head) { | ||
74 | auth_tok_list_item = | ||
75 | list_entry(walker, struct ecryptfs_auth_tok_list_item, | ||
76 | list); | ||
77 | walker = auth_tok_list_item->list.next; | ||
78 | memset(auth_tok_list_item, 0, | ||
79 | sizeof(struct ecryptfs_auth_tok_list_item)); | ||
80 | kmem_cache_free(ecryptfs_auth_tok_list_item_cache, | ||
81 | auth_tok_list_item); | ||
82 | } | ||
83 | } | ||
84 | |||
85 | struct kmem_cache *ecryptfs_auth_tok_list_item_cache; | ||
86 | |||
87 | /** | 68 | /** |
88 | * parse_packet_length | 69 | * parse_packet_length |
89 | * @data: Pointer to memory containing length at offset | 70 | * @data: Pointer to memory containing length at offset |
@@ -102,12 +83,12 @@ static int parse_packet_length(unsigned char *data, size_t *size, | |||
102 | (*size) = 0; | 83 | (*size) = 0; |
103 | if (data[0] < 192) { | 84 | if (data[0] < 192) { |
104 | /* One-byte length */ | 85 | /* One-byte length */ |
105 | (*size) = data[0]; | 86 | (*size) = (unsigned char)data[0]; |
106 | (*length_size) = 1; | 87 | (*length_size) = 1; |
107 | } else if (data[0] < 224) { | 88 | } else if (data[0] < 224) { |
108 | /* Two-byte length */ | 89 | /* Two-byte length */ |
109 | (*size) = ((data[0] - 192) * 256); | 90 | (*size) = (((unsigned char)(data[0]) - 192) * 256); |
110 | (*size) += (data[1] + 192); | 91 | (*size) += ((unsigned char)(data[1]) + 192); |
111 | (*length_size) = 2; | 92 | (*length_size) = 2; |
112 | } else if (data[0] == 255) { | 93 | } else if (data[0] == 255) { |
113 | /* Five-byte length; we're not supposed to see this */ | 94 | /* Five-byte length; we're not supposed to see this */ |
@@ -154,6 +135,499 @@ static int write_packet_length(char *dest, size_t size, | |||
154 | return rc; | 135 | return rc; |
155 | } | 136 | } |
156 | 137 | ||
138 | static int | ||
139 | write_tag_64_packet(char *signature, struct ecryptfs_session_key *session_key, | ||
140 | char **packet, size_t *packet_len) | ||
141 | { | ||
142 | size_t i = 0; | ||
143 | size_t data_len; | ||
144 | size_t packet_size_len; | ||
145 | char *message; | ||
146 | int rc; | ||
147 | |||
148 | /* | ||
149 | * ***** TAG 64 Packet Format ***** | ||
150 | * | Content Type | 1 byte | | ||
151 | * | Key Identifier Size | 1 or 2 bytes | | ||
152 | * | Key Identifier | arbitrary | | ||
153 | * | Encrypted File Encryption Key Size | 1 or 2 bytes | | ||
154 | * | Encrypted File Encryption Key | arbitrary | | ||
155 | */ | ||
156 | data_len = (5 + ECRYPTFS_SIG_SIZE_HEX | ||
157 | + session_key->encrypted_key_size); | ||
158 | *packet = kmalloc(data_len, GFP_KERNEL); | ||
159 | message = *packet; | ||
160 | if (!message) { | ||
161 | ecryptfs_printk(KERN_ERR, "Unable to allocate memory\n"); | ||
162 | rc = -ENOMEM; | ||
163 | goto out; | ||
164 | } | ||
165 | message[i++] = ECRYPTFS_TAG_64_PACKET_TYPE; | ||
166 | rc = write_packet_length(&message[i], ECRYPTFS_SIG_SIZE_HEX, | ||
167 | &packet_size_len); | ||
168 | if (rc) { | ||
169 | ecryptfs_printk(KERN_ERR, "Error generating tag 64 packet " | ||
170 | "header; cannot generate packet length\n"); | ||
171 | goto out; | ||
172 | } | ||
173 | i += packet_size_len; | ||
174 | memcpy(&message[i], signature, ECRYPTFS_SIG_SIZE_HEX); | ||
175 | i += ECRYPTFS_SIG_SIZE_HEX; | ||
176 | rc = write_packet_length(&message[i], session_key->encrypted_key_size, | ||
177 | &packet_size_len); | ||
178 | if (rc) { | ||
179 | ecryptfs_printk(KERN_ERR, "Error generating tag 64 packet " | ||
180 | "header; cannot generate packet length\n"); | ||
181 | goto out; | ||
182 | } | ||
183 | i += packet_size_len; | ||
184 | memcpy(&message[i], session_key->encrypted_key, | ||
185 | session_key->encrypted_key_size); | ||
186 | i += session_key->encrypted_key_size; | ||
187 | *packet_len = i; | ||
188 | out: | ||
189 | return rc; | ||
190 | } | ||
191 | |||
192 | static int | ||
193 | parse_tag_65_packet(struct ecryptfs_session_key *session_key, u16 *cipher_code, | ||
194 | struct ecryptfs_message *msg) | ||
195 | { | ||
196 | size_t i = 0; | ||
197 | char *data; | ||
198 | size_t data_len; | ||
199 | size_t m_size; | ||
200 | size_t message_len; | ||
201 | u16 checksum = 0; | ||
202 | u16 expected_checksum = 0; | ||
203 | int rc; | ||
204 | |||
205 | /* | ||
206 | * ***** TAG 65 Packet Format ***** | ||
207 | * | Content Type | 1 byte | | ||
208 | * | Status Indicator | 1 byte | | ||
209 | * | File Encryption Key Size | 1 or 2 bytes | | ||
210 | * | File Encryption Key | arbitrary | | ||
211 | */ | ||
212 | message_len = msg->data_len; | ||
213 | data = msg->data; | ||
214 | if (message_len < 4) { | ||
215 | rc = -EIO; | ||
216 | goto out; | ||
217 | } | ||
218 | if (data[i++] != ECRYPTFS_TAG_65_PACKET_TYPE) { | ||
219 | ecryptfs_printk(KERN_ERR, "Type should be ECRYPTFS_TAG_65\n"); | ||
220 | rc = -EIO; | ||
221 | goto out; | ||
222 | } | ||
223 | if (data[i++]) { | ||
224 | ecryptfs_printk(KERN_ERR, "Status indicator has non-zero value " | ||
225 | "[%d]\n", data[i-1]); | ||
226 | rc = -EIO; | ||
227 | goto out; | ||
228 | } | ||
229 | rc = parse_packet_length(&data[i], &m_size, &data_len); | ||
230 | if (rc) { | ||
231 | ecryptfs_printk(KERN_WARNING, "Error parsing packet length; " | ||
232 | "rc = [%d]\n", rc); | ||
233 | goto out; | ||
234 | } | ||
235 | i += data_len; | ||
236 | if (message_len < (i + m_size)) { | ||
237 | ecryptfs_printk(KERN_ERR, "The received netlink message is " | ||
238 | "shorter than expected\n"); | ||
239 | rc = -EIO; | ||
240 | goto out; | ||
241 | } | ||
242 | if (m_size < 3) { | ||
243 | ecryptfs_printk(KERN_ERR, | ||
244 | "The decrypted key is not long enough to " | ||
245 | "include a cipher code and checksum\n"); | ||
246 | rc = -EIO; | ||
247 | goto out; | ||
248 | } | ||
249 | *cipher_code = data[i++]; | ||
250 | /* The decrypted key includes 1 byte cipher code and 2 byte checksum */ | ||
251 | session_key->decrypted_key_size = m_size - 3; | ||
252 | if (session_key->decrypted_key_size > ECRYPTFS_MAX_KEY_BYTES) { | ||
253 | ecryptfs_printk(KERN_ERR, "key_size [%d] larger than " | ||
254 | "the maximum key size [%d]\n", | ||
255 | session_key->decrypted_key_size, | ||
256 | ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES); | ||
257 | rc = -EIO; | ||
258 | goto out; | ||
259 | } | ||
260 | memcpy(session_key->decrypted_key, &data[i], | ||
261 | session_key->decrypted_key_size); | ||
262 | i += session_key->decrypted_key_size; | ||
263 | expected_checksum += (unsigned char)(data[i++]) << 8; | ||
264 | expected_checksum += (unsigned char)(data[i++]); | ||
265 | for (i = 0; i < session_key->decrypted_key_size; i++) | ||
266 | checksum += session_key->decrypted_key[i]; | ||
267 | if (expected_checksum != checksum) { | ||
268 | ecryptfs_printk(KERN_ERR, "Invalid checksum for file " | ||
269 | "encryption key; expected [%x]; calculated " | ||
270 | "[%x]\n", expected_checksum, checksum); | ||
271 | rc = -EIO; | ||
272 | } | ||
273 | out: | ||
274 | return rc; | ||
275 | } | ||
276 | |||
277 | |||
278 | static int | ||
279 | write_tag_66_packet(char *signature, size_t cipher_code, | ||
280 | struct ecryptfs_crypt_stat *crypt_stat, char **packet, | ||
281 | size_t *packet_len) | ||
282 | { | ||
283 | size_t i = 0; | ||
284 | size_t j; | ||
285 | size_t data_len; | ||
286 | size_t checksum = 0; | ||
287 | size_t packet_size_len; | ||
288 | char *message; | ||
289 | int rc; | ||
290 | |||
291 | /* | ||
292 | * ***** TAG 66 Packet Format ***** | ||
293 | * | Content Type | 1 byte | | ||
294 | * | Key Identifier Size | 1 or 2 bytes | | ||
295 | * | Key Identifier | arbitrary | | ||
296 | * | File Encryption Key Size | 1 or 2 bytes | | ||
297 | * | File Encryption Key | arbitrary | | ||
298 | */ | ||
299 | data_len = (5 + ECRYPTFS_SIG_SIZE_HEX + crypt_stat->key_size); | ||
300 | *packet = kmalloc(data_len, GFP_KERNEL); | ||
301 | message = *packet; | ||
302 | if (!message) { | ||
303 | ecryptfs_printk(KERN_ERR, "Unable to allocate memory\n"); | ||
304 | rc = -ENOMEM; | ||
305 | goto out; | ||
306 | } | ||
307 | message[i++] = ECRYPTFS_TAG_66_PACKET_TYPE; | ||
308 | rc = write_packet_length(&message[i], ECRYPTFS_SIG_SIZE_HEX, | ||
309 | &packet_size_len); | ||
310 | if (rc) { | ||
311 | ecryptfs_printk(KERN_ERR, "Error generating tag 66 packet " | ||
312 | "header; cannot generate packet length\n"); | ||
313 | goto out; | ||
314 | } | ||
315 | i += packet_size_len; | ||
316 | memcpy(&message[i], signature, ECRYPTFS_SIG_SIZE_HEX); | ||
317 | i += ECRYPTFS_SIG_SIZE_HEX; | ||
318 | /* The encrypted key includes 1 byte cipher code and 2 byte checksum */ | ||
319 | rc = write_packet_length(&message[i], crypt_stat->key_size + 3, | ||
320 | &packet_size_len); | ||
321 | if (rc) { | ||
322 | ecryptfs_printk(KERN_ERR, "Error generating tag 66 packet " | ||
323 | "header; cannot generate packet length\n"); | ||
324 | goto out; | ||
325 | } | ||
326 | i += packet_size_len; | ||
327 | message[i++] = cipher_code; | ||
328 | memcpy(&message[i], crypt_stat->key, crypt_stat->key_size); | ||
329 | i += crypt_stat->key_size; | ||
330 | for (j = 0; j < crypt_stat->key_size; j++) | ||
331 | checksum += crypt_stat->key[j]; | ||
332 | message[i++] = (checksum / 256) % 256; | ||
333 | message[i++] = (checksum % 256); | ||
334 | *packet_len = i; | ||
335 | out: | ||
336 | return rc; | ||
337 | } | ||
338 | |||
339 | static int | ||
340 | parse_tag_67_packet(struct ecryptfs_key_record *key_rec, | ||
341 | struct ecryptfs_message *msg) | ||
342 | { | ||
343 | size_t i = 0; | ||
344 | char *data; | ||
345 | size_t data_len; | ||
346 | size_t message_len; | ||
347 | int rc; | ||
348 | |||
349 | /* | ||
350 | * ***** TAG 65 Packet Format ***** | ||
351 | * | Content Type | 1 byte | | ||
352 | * | Status Indicator | 1 byte | | ||
353 | * | Encrypted File Encryption Key Size | 1 or 2 bytes | | ||
354 | * | Encrypted File Encryption Key | arbitrary | | ||
355 | */ | ||
356 | message_len = msg->data_len; | ||
357 | data = msg->data; | ||
358 | /* verify that everything through the encrypted FEK size is present */ | ||
359 | if (message_len < 4) { | ||
360 | rc = -EIO; | ||
361 | goto out; | ||
362 | } | ||
363 | if (data[i++] != ECRYPTFS_TAG_67_PACKET_TYPE) { | ||
364 | ecryptfs_printk(KERN_ERR, "Type should be ECRYPTFS_TAG_67\n"); | ||
365 | rc = -EIO; | ||
366 | goto out; | ||
367 | } | ||
368 | if (data[i++]) { | ||
369 | ecryptfs_printk(KERN_ERR, "Status indicator has non zero value" | ||
370 | " [%d]\n", data[i-1]); | ||
371 | rc = -EIO; | ||
372 | goto out; | ||
373 | } | ||
374 | rc = parse_packet_length(&data[i], &key_rec->enc_key_size, &data_len); | ||
375 | if (rc) { | ||
376 | ecryptfs_printk(KERN_WARNING, "Error parsing packet length; " | ||
377 | "rc = [%d]\n", rc); | ||
378 | goto out; | ||
379 | } | ||
380 | i += data_len; | ||
381 | if (message_len < (i + key_rec->enc_key_size)) { | ||
382 | ecryptfs_printk(KERN_ERR, "message_len [%d]; max len is [%d]\n", | ||
383 | message_len, (i + key_rec->enc_key_size)); | ||
384 | rc = -EIO; | ||
385 | goto out; | ||
386 | } | ||
387 | if (key_rec->enc_key_size > ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES) { | ||
388 | ecryptfs_printk(KERN_ERR, "Encrypted key_size [%d] larger than " | ||
389 | "the maximum key size [%d]\n", | ||
390 | key_rec->enc_key_size, | ||
391 | ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES); | ||
392 | rc = -EIO; | ||
393 | goto out; | ||
394 | } | ||
395 | memcpy(key_rec->enc_key, &data[i], key_rec->enc_key_size); | ||
396 | out: | ||
397 | return rc; | ||
398 | } | ||
399 | |||
400 | /** | ||
401 | * decrypt_pki_encrypted_session_key - Decrypt the session key with | ||
402 | * the given auth_tok. | ||
403 | * | ||
404 | * Returns Zero on success; non-zero error otherwise. | ||
405 | */ | ||
406 | static int decrypt_pki_encrypted_session_key( | ||
407 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat, | ||
408 | struct ecryptfs_auth_tok *auth_tok, | ||
409 | struct ecryptfs_crypt_stat *crypt_stat) | ||
410 | { | ||
411 | u16 cipher_code = 0; | ||
412 | struct ecryptfs_msg_ctx *msg_ctx; | ||
413 | struct ecryptfs_message *msg = NULL; | ||
414 | char *netlink_message; | ||
415 | size_t netlink_message_length; | ||
416 | int rc; | ||
417 | |||
418 | rc = write_tag_64_packet(mount_crypt_stat->global_auth_tok_sig, | ||
419 | &(auth_tok->session_key), | ||
420 | &netlink_message, &netlink_message_length); | ||
421 | if (rc) { | ||
422 | ecryptfs_printk(KERN_ERR, "Failed to write tag 64 packet"); | ||
423 | goto out; | ||
424 | } | ||
425 | rc = ecryptfs_send_message(ecryptfs_transport, netlink_message, | ||
426 | netlink_message_length, &msg_ctx); | ||
427 | if (rc) { | ||
428 | ecryptfs_printk(KERN_ERR, "Error sending netlink message\n"); | ||
429 | goto out; | ||
430 | } | ||
431 | rc = ecryptfs_wait_for_response(msg_ctx, &msg); | ||
432 | if (rc) { | ||
433 | ecryptfs_printk(KERN_ERR, "Failed to receive tag 65 packet " | ||
434 | "from the user space daemon\n"); | ||
435 | rc = -EIO; | ||
436 | goto out; | ||
437 | } | ||
438 | rc = parse_tag_65_packet(&(auth_tok->session_key), | ||
439 | &cipher_code, msg); | ||
440 | if (rc) { | ||
441 | printk(KERN_ERR "Failed to parse tag 65 packet; rc = [%d]\n", | ||
442 | rc); | ||
443 | goto out; | ||
444 | } | ||
445 | auth_tok->session_key.flags |= ECRYPTFS_CONTAINS_DECRYPTED_KEY; | ||
446 | memcpy(crypt_stat->key, auth_tok->session_key.decrypted_key, | ||
447 | auth_tok->session_key.decrypted_key_size); | ||
448 | crypt_stat->key_size = auth_tok->session_key.decrypted_key_size; | ||
449 | rc = ecryptfs_cipher_code_to_string(crypt_stat->cipher, cipher_code); | ||
450 | if (rc) { | ||
451 | ecryptfs_printk(KERN_ERR, "Cipher code [%d] is invalid\n", | ||
452 | cipher_code) | ||
453 | goto out; | ||
454 | } | ||
455 | crypt_stat->flags |= ECRYPTFS_KEY_VALID; | ||
456 | if (ecryptfs_verbosity > 0) { | ||
457 | ecryptfs_printk(KERN_DEBUG, "Decrypted session key:\n"); | ||
458 | ecryptfs_dump_hex(crypt_stat->key, | ||
459 | crypt_stat->key_size); | ||
460 | } | ||
461 | out: | ||
462 | if (msg) | ||
463 | kfree(msg); | ||
464 | return rc; | ||
465 | } | ||
466 | |||
467 | static void wipe_auth_tok_list(struct list_head *auth_tok_list_head) | ||
468 | { | ||
469 | struct list_head *walker; | ||
470 | struct ecryptfs_auth_tok_list_item *auth_tok_list_item; | ||
471 | |||
472 | walker = auth_tok_list_head->next; | ||
473 | while (walker != auth_tok_list_head) { | ||
474 | auth_tok_list_item = | ||
475 | list_entry(walker, struct ecryptfs_auth_tok_list_item, | ||
476 | list); | ||
477 | walker = auth_tok_list_item->list.next; | ||
478 | memset(auth_tok_list_item, 0, | ||
479 | sizeof(struct ecryptfs_auth_tok_list_item)); | ||
480 | kmem_cache_free(ecryptfs_auth_tok_list_item_cache, | ||
481 | auth_tok_list_item); | ||
482 | } | ||
483 | auth_tok_list_head->next = NULL; | ||
484 | } | ||
485 | |||
486 | struct kmem_cache *ecryptfs_auth_tok_list_item_cache; | ||
487 | |||
488 | |||
489 | /** | ||
490 | * parse_tag_1_packet | ||
491 | * @crypt_stat: The cryptographic context to modify based on packet | ||
492 | * contents. | ||
493 | * @data: The raw bytes of the packet. | ||
494 | * @auth_tok_list: eCryptfs parses packets into authentication tokens; | ||
495 | * a new authentication token will be placed at the end | ||
496 | * of this list for this packet. | ||
497 | * @new_auth_tok: Pointer to a pointer to memory that this function | ||
498 | * allocates; sets the memory address of the pointer to | ||
499 | * NULL on error. This object is added to the | ||
500 | * auth_tok_list. | ||
501 | * @packet_size: This function writes the size of the parsed packet | ||
502 | * into this memory location; zero on error. | ||
503 | * | ||
504 | * Returns zero on success; non-zero on error. | ||
505 | */ | ||
506 | static int | ||
507 | parse_tag_1_packet(struct ecryptfs_crypt_stat *crypt_stat, | ||
508 | unsigned char *data, struct list_head *auth_tok_list, | ||
509 | struct ecryptfs_auth_tok **new_auth_tok, | ||
510 | size_t *packet_size, size_t max_packet_size) | ||
511 | { | ||
512 | size_t body_size; | ||
513 | struct ecryptfs_auth_tok_list_item *auth_tok_list_item; | ||
514 | size_t length_size; | ||
515 | int rc = 0; | ||
516 | |||
517 | (*packet_size) = 0; | ||
518 | (*new_auth_tok) = NULL; | ||
519 | |||
520 | /* we check that: | ||
521 | * one byte for the Tag 1 ID flag | ||
522 | * two bytes for the body size | ||
523 | * do not exceed the maximum_packet_size | ||
524 | */ | ||
525 | if (unlikely((*packet_size) + 3 > max_packet_size)) { | ||
526 | ecryptfs_printk(KERN_ERR, "Packet size exceeds max\n"); | ||
527 | rc = -EINVAL; | ||
528 | goto out; | ||
529 | } | ||
530 | /* check for Tag 1 identifier - one byte */ | ||
531 | if (data[(*packet_size)++] != ECRYPTFS_TAG_1_PACKET_TYPE) { | ||
532 | ecryptfs_printk(KERN_ERR, "Enter w/ first byte != 0x%.2x\n", | ||
533 | ECRYPTFS_TAG_1_PACKET_TYPE); | ||
534 | rc = -EINVAL; | ||
535 | goto out; | ||
536 | } | ||
537 | /* Released: wipe_auth_tok_list called in ecryptfs_parse_packet_set or | ||
538 | * at end of function upon failure */ | ||
539 | auth_tok_list_item = | ||
540 | kmem_cache_alloc(ecryptfs_auth_tok_list_item_cache, | ||
541 | GFP_KERNEL); | ||
542 | if (!auth_tok_list_item) { | ||
543 | ecryptfs_printk(KERN_ERR, "Unable to allocate memory\n"); | ||
544 | rc = -ENOMEM; | ||
545 | goto out; | ||
546 | } | ||
547 | memset(auth_tok_list_item, 0, | ||
548 | sizeof(struct ecryptfs_auth_tok_list_item)); | ||
549 | (*new_auth_tok) = &auth_tok_list_item->auth_tok; | ||
550 | /* check for body size - one to two bytes | ||
551 | * | ||
552 | * ***** TAG 1 Packet Format ***** | ||
553 | * | version number | 1 byte | | ||
554 | * | key ID | 8 bytes | | ||
555 | * | public key algorithm | 1 byte | | ||
556 | * | encrypted session key | arbitrary | | ||
557 | */ | ||
558 | rc = parse_packet_length(&data[(*packet_size)], &body_size, | ||
559 | &length_size); | ||
560 | if (rc) { | ||
561 | ecryptfs_printk(KERN_WARNING, "Error parsing packet length; " | ||
562 | "rc = [%d]\n", rc); | ||
563 | goto out_free; | ||
564 | } | ||
565 | if (unlikely(body_size < (0x02 + ECRYPTFS_SIG_SIZE))) { | ||
566 | ecryptfs_printk(KERN_WARNING, "Invalid body size ([%d])\n", | ||
567 | body_size); | ||
568 | rc = -EINVAL; | ||
569 | goto out_free; | ||
570 | } | ||
571 | (*packet_size) += length_size; | ||
572 | if (unlikely((*packet_size) + body_size > max_packet_size)) { | ||
573 | ecryptfs_printk(KERN_ERR, "Packet size exceeds max\n"); | ||
574 | rc = -EINVAL; | ||
575 | goto out_free; | ||
576 | } | ||
577 | /* Version 3 (from RFC2440) - one byte */ | ||
578 | if (unlikely(data[(*packet_size)++] != 0x03)) { | ||
579 | ecryptfs_printk(KERN_DEBUG, "Unknown version number " | ||
580 | "[%d]\n", data[(*packet_size) - 1]); | ||
581 | rc = -EINVAL; | ||
582 | goto out_free; | ||
583 | } | ||
584 | /* Read Signature */ | ||
585 | ecryptfs_to_hex((*new_auth_tok)->token.private_key.signature, | ||
586 | &data[(*packet_size)], ECRYPTFS_SIG_SIZE); | ||
587 | *packet_size += ECRYPTFS_SIG_SIZE; | ||
588 | /* This byte is skipped because the kernel does not need to | ||
589 | * know which public key encryption algorithm was used */ | ||
590 | (*packet_size)++; | ||
591 | (*new_auth_tok)->session_key.encrypted_key_size = | ||
592 | body_size - (0x02 + ECRYPTFS_SIG_SIZE); | ||
593 | if ((*new_auth_tok)->session_key.encrypted_key_size | ||
594 | > ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES) { | ||
595 | ecryptfs_printk(KERN_ERR, "Tag 1 packet contains key larger " | ||
596 | "than ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES"); | ||
597 | rc = -EINVAL; | ||
598 | goto out; | ||
599 | } | ||
600 | ecryptfs_printk(KERN_DEBUG, "Encrypted key size = [%d]\n", | ||
601 | (*new_auth_tok)->session_key.encrypted_key_size); | ||
602 | memcpy((*new_auth_tok)->session_key.encrypted_key, | ||
603 | &data[(*packet_size)], (body_size - 0x02 - ECRYPTFS_SIG_SIZE)); | ||
604 | (*packet_size) += (*new_auth_tok)->session_key.encrypted_key_size; | ||
605 | (*new_auth_tok)->session_key.flags &= | ||
606 | ~ECRYPTFS_CONTAINS_DECRYPTED_KEY; | ||
607 | (*new_auth_tok)->session_key.flags |= | ||
608 | ECRYPTFS_CONTAINS_ENCRYPTED_KEY; | ||
609 | (*new_auth_tok)->token_type = ECRYPTFS_PRIVATE_KEY; | ||
610 | (*new_auth_tok)->flags |= ECRYPTFS_PRIVATE_KEY; | ||
611 | /* TODO: Why are we setting this flag here? Don't we want the | ||
612 | * userspace to decrypt the session key? */ | ||
613 | (*new_auth_tok)->session_key.flags &= | ||
614 | ~(ECRYPTFS_USERSPACE_SHOULD_TRY_TO_DECRYPT); | ||
615 | (*new_auth_tok)->session_key.flags &= | ||
616 | ~(ECRYPTFS_USERSPACE_SHOULD_TRY_TO_ENCRYPT); | ||
617 | list_add(&auth_tok_list_item->list, auth_tok_list); | ||
618 | goto out; | ||
619 | out_free: | ||
620 | (*new_auth_tok) = NULL; | ||
621 | memset(auth_tok_list_item, 0, | ||
622 | sizeof(struct ecryptfs_auth_tok_list_item)); | ||
623 | kmem_cache_free(ecryptfs_auth_tok_list_item_cache, | ||
624 | auth_tok_list_item); | ||
625 | out: | ||
626 | if (rc) | ||
627 | (*packet_size) = 0; | ||
628 | return rc; | ||
629 | } | ||
630 | |||
157 | /** | 631 | /** |
158 | * parse_tag_3_packet | 632 | * parse_tag_3_packet |
159 | * @crypt_stat: The cryptographic context to modify based on packet | 633 | * @crypt_stat: The cryptographic context to modify based on packet |
@@ -178,10 +652,10 @@ parse_tag_3_packet(struct ecryptfs_crypt_stat *crypt_stat, | |||
178 | struct ecryptfs_auth_tok **new_auth_tok, | 652 | struct ecryptfs_auth_tok **new_auth_tok, |
179 | size_t *packet_size, size_t max_packet_size) | 653 | size_t *packet_size, size_t max_packet_size) |
180 | { | 654 | { |
181 | int rc = 0; | ||
182 | size_t body_size; | 655 | size_t body_size; |
183 | struct ecryptfs_auth_tok_list_item *auth_tok_list_item; | 656 | struct ecryptfs_auth_tok_list_item *auth_tok_list_item; |
184 | size_t length_size; | 657 | size_t length_size; |
658 | int rc = 0; | ||
185 | 659 | ||
186 | (*packet_size) = 0; | 660 | (*packet_size) = 0; |
187 | (*new_auth_tok) = NULL; | 661 | (*new_auth_tok) = NULL; |
@@ -207,14 +681,12 @@ parse_tag_3_packet(struct ecryptfs_crypt_stat *crypt_stat, | |||
207 | /* Released: wipe_auth_tok_list called in ecryptfs_parse_packet_set or | 681 | /* Released: wipe_auth_tok_list called in ecryptfs_parse_packet_set or |
208 | * at end of function upon failure */ | 682 | * at end of function upon failure */ |
209 | auth_tok_list_item = | 683 | auth_tok_list_item = |
210 | kmem_cache_alloc(ecryptfs_auth_tok_list_item_cache, GFP_KERNEL); | 684 | kmem_cache_zalloc(ecryptfs_auth_tok_list_item_cache, GFP_KERNEL); |
211 | if (!auth_tok_list_item) { | 685 | if (!auth_tok_list_item) { |
212 | ecryptfs_printk(KERN_ERR, "Unable to allocate memory\n"); | 686 | ecryptfs_printk(KERN_ERR, "Unable to allocate memory\n"); |
213 | rc = -ENOMEM; | 687 | rc = -ENOMEM; |
214 | goto out; | 688 | goto out; |
215 | } | 689 | } |
216 | memset(auth_tok_list_item, 0, | ||
217 | sizeof(struct ecryptfs_auth_tok_list_item)); | ||
218 | (*new_auth_tok) = &auth_tok_list_item->auth_tok; | 690 | (*new_auth_tok) = &auth_tok_list_item->auth_tok; |
219 | 691 | ||
220 | /* check for body size - one to two bytes */ | 692 | /* check for body size - one to two bytes */ |
@@ -321,10 +793,10 @@ parse_tag_3_packet(struct ecryptfs_crypt_stat *crypt_stat, | |||
321 | (*new_auth_tok)->token_type = ECRYPTFS_PASSWORD; | 793 | (*new_auth_tok)->token_type = ECRYPTFS_PASSWORD; |
322 | /* TODO: Parametarize; we might actually want userspace to | 794 | /* TODO: Parametarize; we might actually want userspace to |
323 | * decrypt the session key. */ | 795 | * decrypt the session key. */ |
324 | ECRYPTFS_CLEAR_FLAG((*new_auth_tok)->session_key.flags, | 796 | (*new_auth_tok)->session_key.flags &= |
325 | ECRYPTFS_USERSPACE_SHOULD_TRY_TO_DECRYPT); | 797 | ~(ECRYPTFS_USERSPACE_SHOULD_TRY_TO_DECRYPT); |
326 | ECRYPTFS_CLEAR_FLAG((*new_auth_tok)->session_key.flags, | 798 | (*new_auth_tok)->session_key.flags &= |
327 | ECRYPTFS_USERSPACE_SHOULD_TRY_TO_ENCRYPT); | 799 | ~(ECRYPTFS_USERSPACE_SHOULD_TRY_TO_ENCRYPT); |
328 | list_add(&auth_tok_list_item->list, auth_tok_list); | 800 | list_add(&auth_tok_list_item->list, auth_tok_list); |
329 | goto out; | 801 | goto out; |
330 | out_free: | 802 | out_free: |
@@ -360,9 +832,9 @@ parse_tag_11_packet(unsigned char *data, unsigned char *contents, | |||
360 | size_t max_contents_bytes, size_t *tag_11_contents_size, | 832 | size_t max_contents_bytes, size_t *tag_11_contents_size, |
361 | size_t *packet_size, size_t max_packet_size) | 833 | size_t *packet_size, size_t max_packet_size) |
362 | { | 834 | { |
363 | int rc = 0; | ||
364 | size_t body_size; | 835 | size_t body_size; |
365 | size_t length_size; | 836 | size_t length_size; |
837 | int rc = 0; | ||
366 | 838 | ||
367 | (*packet_size) = 0; | 839 | (*packet_size) = 0; |
368 | (*tag_11_contents_size) = 0; | 840 | (*tag_11_contents_size) = 0; |
@@ -461,7 +933,6 @@ static int decrypt_session_key(struct ecryptfs_auth_tok *auth_tok, | |||
461 | struct ecryptfs_password *password_s_ptr; | 933 | struct ecryptfs_password *password_s_ptr; |
462 | struct scatterlist src_sg[2], dst_sg[2]; | 934 | struct scatterlist src_sg[2], dst_sg[2]; |
463 | struct mutex *tfm_mutex = NULL; | 935 | struct mutex *tfm_mutex = NULL; |
464 | /* TODO: Use virt_to_scatterlist for these */ | ||
465 | char *encrypted_session_key; | 936 | char *encrypted_session_key; |
466 | char *session_key; | 937 | char *session_key; |
467 | struct blkcipher_desc desc = { | 938 | struct blkcipher_desc desc = { |
@@ -470,8 +941,7 @@ static int decrypt_session_key(struct ecryptfs_auth_tok *auth_tok, | |||
470 | int rc = 0; | 941 | int rc = 0; |
471 | 942 | ||
472 | password_s_ptr = &auth_tok->token.password; | 943 | password_s_ptr = &auth_tok->token.password; |
473 | if (ECRYPTFS_CHECK_FLAG(password_s_ptr->flags, | 944 | if (password_s_ptr->flags & ECRYPTFS_SESSION_KEY_ENCRYPTION_KEY_SET) |
474 | ECRYPTFS_SESSION_KEY_ENCRYPTION_KEY_SET)) | ||
475 | ecryptfs_printk(KERN_DEBUG, "Session key encryption key " | 945 | ecryptfs_printk(KERN_DEBUG, "Session key encryption key " |
476 | "set; skipping key generation\n"); | 946 | "set; skipping key generation\n"); |
477 | ecryptfs_printk(KERN_DEBUG, "Session key encryption key (size [%d])" | 947 | ecryptfs_printk(KERN_DEBUG, "Session key encryption key (size [%d])" |
@@ -553,7 +1023,7 @@ static int decrypt_session_key(struct ecryptfs_auth_tok *auth_tok, | |||
553 | auth_tok->session_key.flags |= ECRYPTFS_CONTAINS_DECRYPTED_KEY; | 1023 | auth_tok->session_key.flags |= ECRYPTFS_CONTAINS_DECRYPTED_KEY; |
554 | memcpy(crypt_stat->key, auth_tok->session_key.decrypted_key, | 1024 | memcpy(crypt_stat->key, auth_tok->session_key.decrypted_key, |
555 | auth_tok->session_key.decrypted_key_size); | 1025 | auth_tok->session_key.decrypted_key_size); |
556 | ECRYPTFS_SET_FLAG(crypt_stat->flags, ECRYPTFS_KEY_VALID); | 1026 | crypt_stat->flags |= ECRYPTFS_KEY_VALID; |
557 | ecryptfs_printk(KERN_DEBUG, "Decrypted session key:\n"); | 1027 | ecryptfs_printk(KERN_DEBUG, "Decrypted session key:\n"); |
558 | if (ecryptfs_verbosity > 0) | 1028 | if (ecryptfs_verbosity > 0) |
559 | ecryptfs_dump_hex(crypt_stat->key, | 1029 | ecryptfs_dump_hex(crypt_stat->key, |
@@ -589,7 +1059,6 @@ int ecryptfs_parse_packet_set(struct ecryptfs_crypt_stat *crypt_stat, | |||
589 | struct dentry *ecryptfs_dentry) | 1059 | struct dentry *ecryptfs_dentry) |
590 | { | 1060 | { |
591 | size_t i = 0; | 1061 | size_t i = 0; |
592 | int rc = 0; | ||
593 | size_t found_auth_tok = 0; | 1062 | size_t found_auth_tok = 0; |
594 | size_t next_packet_is_auth_tok_packet; | 1063 | size_t next_packet_is_auth_tok_packet; |
595 | char sig[ECRYPTFS_SIG_SIZE_HEX]; | 1064 | char sig[ECRYPTFS_SIG_SIZE_HEX]; |
@@ -605,6 +1074,7 @@ int ecryptfs_parse_packet_set(struct ecryptfs_crypt_stat *crypt_stat, | |||
605 | unsigned char sig_tmp_space[ECRYPTFS_SIG_SIZE]; | 1074 | unsigned char sig_tmp_space[ECRYPTFS_SIG_SIZE]; |
606 | size_t tag_11_contents_size; | 1075 | size_t tag_11_contents_size; |
607 | size_t tag_11_packet_size; | 1076 | size_t tag_11_packet_size; |
1077 | int rc = 0; | ||
608 | 1078 | ||
609 | INIT_LIST_HEAD(&auth_tok_list); | 1079 | INIT_LIST_HEAD(&auth_tok_list); |
610 | /* Parse the header to find as many packets as we can, these will be | 1080 | /* Parse the header to find as many packets as we can, these will be |
@@ -656,8 +1126,21 @@ int ecryptfs_parse_packet_set(struct ecryptfs_crypt_stat *crypt_stat, | |||
656 | sig_tmp_space, tag_11_contents_size); | 1126 | sig_tmp_space, tag_11_contents_size); |
657 | new_auth_tok->token.password.signature[ | 1127 | new_auth_tok->token.password.signature[ |
658 | ECRYPTFS_PASSWORD_SIG_SIZE] = '\0'; | 1128 | ECRYPTFS_PASSWORD_SIG_SIZE] = '\0'; |
659 | ECRYPTFS_SET_FLAG(crypt_stat->flags, | 1129 | crypt_stat->flags |= ECRYPTFS_ENCRYPTED; |
660 | ECRYPTFS_ENCRYPTED); | 1130 | break; |
1131 | case ECRYPTFS_TAG_1_PACKET_TYPE: | ||
1132 | rc = parse_tag_1_packet(crypt_stat, | ||
1133 | (unsigned char *)&src[i], | ||
1134 | &auth_tok_list, &new_auth_tok, | ||
1135 | &packet_size, max_packet_size); | ||
1136 | if (rc) { | ||
1137 | ecryptfs_printk(KERN_ERR, "Error parsing " | ||
1138 | "tag 1 packet\n"); | ||
1139 | rc = -EIO; | ||
1140 | goto out_wipe_list; | ||
1141 | } | ||
1142 | i += packet_size; | ||
1143 | crypt_stat->flags |= ECRYPTFS_ENCRYPTED; | ||
661 | break; | 1144 | break; |
662 | case ECRYPTFS_TAG_11_PACKET_TYPE: | 1145 | case ECRYPTFS_TAG_11_PACKET_TYPE: |
663 | ecryptfs_printk(KERN_WARNING, "Invalid packet set " | 1146 | ecryptfs_printk(KERN_WARNING, "Invalid packet set " |
@@ -706,31 +1189,46 @@ int ecryptfs_parse_packet_set(struct ecryptfs_crypt_stat *crypt_stat, | |||
706 | goto leave_list; | 1189 | goto leave_list; |
707 | /* TODO: Transfer the common salt into the | 1190 | /* TODO: Transfer the common salt into the |
708 | * crypt_stat salt */ | 1191 | * crypt_stat salt */ |
1192 | } else if ((candidate_auth_tok->token_type | ||
1193 | == ECRYPTFS_PRIVATE_KEY) | ||
1194 | && !strncmp(candidate_auth_tok->token.private_key.signature, | ||
1195 | sig, ECRYPTFS_SIG_SIZE_HEX)) { | ||
1196 | found_auth_tok = 1; | ||
1197 | goto leave_list; | ||
709 | } | 1198 | } |
710 | } | 1199 | } |
711 | leave_list: | ||
712 | if (!found_auth_tok) { | 1200 | if (!found_auth_tok) { |
713 | ecryptfs_printk(KERN_ERR, "Could not find authentication " | 1201 | ecryptfs_printk(KERN_ERR, "Could not find authentication " |
714 | "token on temporary list for sig [%.*s]\n", | 1202 | "token on temporary list for sig [%.*s]\n", |
715 | ECRYPTFS_SIG_SIZE_HEX, sig); | 1203 | ECRYPTFS_SIG_SIZE_HEX, sig); |
716 | rc = -EIO; | 1204 | rc = -EIO; |
717 | goto out_wipe_list; | 1205 | goto out_wipe_list; |
718 | } else { | 1206 | } |
1207 | leave_list: | ||
1208 | rc = -ENOTSUPP; | ||
1209 | if (candidate_auth_tok->token_type == ECRYPTFS_PRIVATE_KEY) { | ||
1210 | memcpy(&(candidate_auth_tok->token.private_key), | ||
1211 | &(chosen_auth_tok->token.private_key), | ||
1212 | sizeof(struct ecryptfs_private_key)); | ||
1213 | rc = decrypt_pki_encrypted_session_key(mount_crypt_stat, | ||
1214 | candidate_auth_tok, | ||
1215 | crypt_stat); | ||
1216 | } else if (candidate_auth_tok->token_type == ECRYPTFS_PASSWORD) { | ||
719 | memcpy(&(candidate_auth_tok->token.password), | 1217 | memcpy(&(candidate_auth_tok->token.password), |
720 | &(chosen_auth_tok->token.password), | 1218 | &(chosen_auth_tok->token.password), |
721 | sizeof(struct ecryptfs_password)); | 1219 | sizeof(struct ecryptfs_password)); |
722 | rc = decrypt_session_key(candidate_auth_tok, crypt_stat); | 1220 | rc = decrypt_session_key(candidate_auth_tok, crypt_stat); |
723 | if (rc) { | 1221 | } |
724 | ecryptfs_printk(KERN_ERR, "Error decrypting the " | 1222 | if (rc) { |
725 | "session key\n"); | 1223 | ecryptfs_printk(KERN_ERR, "Error decrypting the " |
726 | goto out_wipe_list; | 1224 | "session key; rc = [%d]\n", rc); |
727 | } | 1225 | goto out_wipe_list; |
728 | rc = ecryptfs_compute_root_iv(crypt_stat); | 1226 | } |
729 | if (rc) { | 1227 | rc = ecryptfs_compute_root_iv(crypt_stat); |
730 | ecryptfs_printk(KERN_ERR, "Error computing " | 1228 | if (rc) { |
731 | "the root IV\n"); | 1229 | ecryptfs_printk(KERN_ERR, "Error computing " |
732 | goto out_wipe_list; | 1230 | "the root IV\n"); |
733 | } | 1231 | goto out_wipe_list; |
734 | } | 1232 | } |
735 | rc = ecryptfs_init_crypt_ctx(crypt_stat); | 1233 | rc = ecryptfs_init_crypt_ctx(crypt_stat); |
736 | if (rc) { | 1234 | if (rc) { |
@@ -743,6 +1241,145 @@ out_wipe_list: | |||
743 | out: | 1241 | out: |
744 | return rc; | 1242 | return rc; |
745 | } | 1243 | } |
1244 | static int | ||
1245 | pki_encrypt_session_key(struct ecryptfs_auth_tok *auth_tok, | ||
1246 | struct ecryptfs_crypt_stat *crypt_stat, | ||
1247 | struct ecryptfs_key_record *key_rec) | ||
1248 | { | ||
1249 | struct ecryptfs_msg_ctx *msg_ctx = NULL; | ||
1250 | char *netlink_payload; | ||
1251 | size_t netlink_payload_length; | ||
1252 | struct ecryptfs_message *msg; | ||
1253 | int rc; | ||
1254 | |||
1255 | rc = write_tag_66_packet(auth_tok->token.private_key.signature, | ||
1256 | ecryptfs_code_for_cipher_string(crypt_stat), | ||
1257 | crypt_stat, &netlink_payload, | ||
1258 | &netlink_payload_length); | ||
1259 | if (rc) { | ||
1260 | ecryptfs_printk(KERN_ERR, "Error generating tag 66 packet\n"); | ||
1261 | goto out; | ||
1262 | } | ||
1263 | rc = ecryptfs_send_message(ecryptfs_transport, netlink_payload, | ||
1264 | netlink_payload_length, &msg_ctx); | ||
1265 | if (rc) { | ||
1266 | ecryptfs_printk(KERN_ERR, "Error sending netlink message\n"); | ||
1267 | goto out; | ||
1268 | } | ||
1269 | rc = ecryptfs_wait_for_response(msg_ctx, &msg); | ||
1270 | if (rc) { | ||
1271 | ecryptfs_printk(KERN_ERR, "Failed to receive tag 67 packet " | ||
1272 | "from the user space daemon\n"); | ||
1273 | rc = -EIO; | ||
1274 | goto out; | ||
1275 | } | ||
1276 | rc = parse_tag_67_packet(key_rec, msg); | ||
1277 | if (rc) | ||
1278 | ecryptfs_printk(KERN_ERR, "Error parsing tag 67 packet\n"); | ||
1279 | kfree(msg); | ||
1280 | out: | ||
1281 | if (netlink_payload) | ||
1282 | kfree(netlink_payload); | ||
1283 | return rc; | ||
1284 | } | ||
1285 | /** | ||
1286 | * write_tag_1_packet - Write an RFC2440-compatible tag 1 (public key) packet | ||
1287 | * @dest: Buffer into which to write the packet | ||
1288 | * @max: Maximum number of bytes that can be writtn | ||
1289 | * @packet_size: This function will write the number of bytes that end | ||
1290 | * up constituting the packet; set to zero on error | ||
1291 | * | ||
1292 | * Returns zero on success; non-zero on error. | ||
1293 | */ | ||
1294 | static int | ||
1295 | write_tag_1_packet(char *dest, size_t max, struct ecryptfs_auth_tok *auth_tok, | ||
1296 | struct ecryptfs_crypt_stat *crypt_stat, | ||
1297 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat, | ||
1298 | struct ecryptfs_key_record *key_rec, size_t *packet_size) | ||
1299 | { | ||
1300 | size_t i; | ||
1301 | size_t encrypted_session_key_valid = 0; | ||
1302 | size_t key_rec_size; | ||
1303 | size_t packet_size_length; | ||
1304 | int rc = 0; | ||
1305 | |||
1306 | (*packet_size) = 0; | ||
1307 | ecryptfs_from_hex(key_rec->sig, auth_tok->token.private_key.signature, | ||
1308 | ECRYPTFS_SIG_SIZE); | ||
1309 | encrypted_session_key_valid = 0; | ||
1310 | for (i = 0; i < crypt_stat->key_size; i++) | ||
1311 | encrypted_session_key_valid |= | ||
1312 | auth_tok->session_key.encrypted_key[i]; | ||
1313 | if (encrypted_session_key_valid) { | ||
1314 | memcpy(key_rec->enc_key, | ||
1315 | auth_tok->session_key.encrypted_key, | ||
1316 | auth_tok->session_key.encrypted_key_size); | ||
1317 | goto encrypted_session_key_set; | ||
1318 | } | ||
1319 | if (auth_tok->session_key.encrypted_key_size == 0) | ||
1320 | auth_tok->session_key.encrypted_key_size = | ||
1321 | auth_tok->token.private_key.key_size; | ||
1322 | rc = pki_encrypt_session_key(auth_tok, crypt_stat, key_rec); | ||
1323 | if (rc) { | ||
1324 | ecryptfs_printk(KERN_ERR, "Failed to encrypt session key " | ||
1325 | "via a pki"); | ||
1326 | goto out; | ||
1327 | } | ||
1328 | if (ecryptfs_verbosity > 0) { | ||
1329 | ecryptfs_printk(KERN_DEBUG, "Encrypted key:\n"); | ||
1330 | ecryptfs_dump_hex(key_rec->enc_key, key_rec->enc_key_size); | ||
1331 | } | ||
1332 | encrypted_session_key_set: | ||
1333 | /* Now we have a valid key_rec. Append it to the | ||
1334 | * key_rec set. */ | ||
1335 | key_rec_size = (sizeof(struct ecryptfs_key_record) | ||
1336 | - ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES | ||
1337 | + (key_rec->enc_key_size)); | ||
1338 | /* TODO: Include a packet size limit as a parameter to this | ||
1339 | * function once we have multi-packet headers (for versions | ||
1340 | * later than 0.1 */ | ||
1341 | if (key_rec_size >= ECRYPTFS_MAX_KEYSET_SIZE) { | ||
1342 | ecryptfs_printk(KERN_ERR, "Keyset too large\n"); | ||
1343 | rc = -EINVAL; | ||
1344 | goto out; | ||
1345 | } | ||
1346 | /* ***** TAG 1 Packet Format ***** | ||
1347 | * | version number | 1 byte | | ||
1348 | * | key ID | 8 bytes | | ||
1349 | * | public key algorithm | 1 byte | | ||
1350 | * | encrypted session key | arbitrary | | ||
1351 | */ | ||
1352 | if ((0x02 + ECRYPTFS_SIG_SIZE + key_rec->enc_key_size) >= max) { | ||
1353 | ecryptfs_printk(KERN_ERR, | ||
1354 | "Authentication token is too large\n"); | ||
1355 | rc = -EINVAL; | ||
1356 | goto out; | ||
1357 | } | ||
1358 | dest[(*packet_size)++] = ECRYPTFS_TAG_1_PACKET_TYPE; | ||
1359 | /* This format is inspired by OpenPGP; see RFC 2440 | ||
1360 | * packet tag 1 */ | ||
1361 | rc = write_packet_length(&dest[(*packet_size)], | ||
1362 | (0x02 + ECRYPTFS_SIG_SIZE + | ||
1363 | key_rec->enc_key_size), | ||
1364 | &packet_size_length); | ||
1365 | if (rc) { | ||
1366 | ecryptfs_printk(KERN_ERR, "Error generating tag 1 packet " | ||
1367 | "header; cannot generate packet length\n"); | ||
1368 | goto out; | ||
1369 | } | ||
1370 | (*packet_size) += packet_size_length; | ||
1371 | dest[(*packet_size)++] = 0x03; /* version 3 */ | ||
1372 | memcpy(&dest[(*packet_size)], key_rec->sig, ECRYPTFS_SIG_SIZE); | ||
1373 | (*packet_size) += ECRYPTFS_SIG_SIZE; | ||
1374 | dest[(*packet_size)++] = RFC2440_CIPHER_RSA; | ||
1375 | memcpy(&dest[(*packet_size)], key_rec->enc_key, | ||
1376 | key_rec->enc_key_size); | ||
1377 | (*packet_size) += key_rec->enc_key_size; | ||
1378 | out: | ||
1379 | if (rc) | ||
1380 | (*packet_size) = 0; | ||
1381 | return rc; | ||
1382 | } | ||
746 | 1383 | ||
747 | /** | 1384 | /** |
748 | * write_tag_11_packet | 1385 | * write_tag_11_packet |
@@ -758,8 +1395,8 @@ static int | |||
758 | write_tag_11_packet(char *dest, int max, char *contents, size_t contents_length, | 1395 | write_tag_11_packet(char *dest, int max, char *contents, size_t contents_length, |
759 | size_t *packet_length) | 1396 | size_t *packet_length) |
760 | { | 1397 | { |
761 | int rc = 0; | ||
762 | size_t packet_size_length; | 1398 | size_t packet_size_length; |
1399 | int rc = 0; | ||
763 | 1400 | ||
764 | (*packet_length) = 0; | 1401 | (*packet_length) = 0; |
765 | if ((13 + contents_length) > max) { | 1402 | if ((13 + contents_length) > max) { |
@@ -817,7 +1454,6 @@ write_tag_3_packet(char *dest, size_t max, struct ecryptfs_auth_tok *auth_tok, | |||
817 | struct ecryptfs_key_record *key_rec, size_t *packet_size) | 1454 | struct ecryptfs_key_record *key_rec, size_t *packet_size) |
818 | { | 1455 | { |
819 | size_t i; | 1456 | size_t i; |
820 | size_t signature_is_valid = 0; | ||
821 | size_t encrypted_session_key_valid = 0; | 1457 | size_t encrypted_session_key_valid = 0; |
822 | char session_key_encryption_key[ECRYPTFS_MAX_KEY_BYTES]; | 1458 | char session_key_encryption_key[ECRYPTFS_MAX_KEY_BYTES]; |
823 | struct scatterlist dest_sg[2]; | 1459 | struct scatterlist dest_sg[2]; |
@@ -833,19 +1469,14 @@ write_tag_3_packet(char *dest, size_t max, struct ecryptfs_auth_tok *auth_tok, | |||
833 | int rc = 0; | 1469 | int rc = 0; |
834 | 1470 | ||
835 | (*packet_size) = 0; | 1471 | (*packet_size) = 0; |
836 | /* Check for a valid signature on the auth_tok */ | 1472 | ecryptfs_from_hex(key_rec->sig, auth_tok->token.password.signature, |
837 | for (i = 0; i < ECRYPTFS_SIG_SIZE_HEX; i++) | ||
838 | signature_is_valid |= auth_tok->token.password.signature[i]; | ||
839 | if (!signature_is_valid) | ||
840 | BUG(); | ||
841 | ecryptfs_from_hex((*key_rec).sig, auth_tok->token.password.signature, | ||
842 | ECRYPTFS_SIG_SIZE); | 1473 | ECRYPTFS_SIG_SIZE); |
843 | encrypted_session_key_valid = 0; | 1474 | encrypted_session_key_valid = 0; |
844 | for (i = 0; i < crypt_stat->key_size; i++) | 1475 | for (i = 0; i < crypt_stat->key_size; i++) |
845 | encrypted_session_key_valid |= | 1476 | encrypted_session_key_valid |= |
846 | auth_tok->session_key.encrypted_key[i]; | 1477 | auth_tok->session_key.encrypted_key[i]; |
847 | if (encrypted_session_key_valid) { | 1478 | if (encrypted_session_key_valid) { |
848 | memcpy((*key_rec).enc_key, | 1479 | memcpy(key_rec->enc_key, |
849 | auth_tok->session_key.encrypted_key, | 1480 | auth_tok->session_key.encrypted_key, |
850 | auth_tok->session_key.encrypted_key_size); | 1481 | auth_tok->session_key.encrypted_key_size); |
851 | goto encrypted_session_key_set; | 1482 | goto encrypted_session_key_set; |
@@ -858,10 +1489,10 @@ write_tag_3_packet(char *dest, size_t max, struct ecryptfs_auth_tok *auth_tok, | |||
858 | memset((crypt_stat->key + 24), 0, 8); | 1489 | memset((crypt_stat->key + 24), 0, 8); |
859 | auth_tok->session_key.encrypted_key_size = 32; | 1490 | auth_tok->session_key.encrypted_key_size = 32; |
860 | } | 1491 | } |
861 | (*key_rec).enc_key_size = | 1492 | key_rec->enc_key_size = |
862 | auth_tok->session_key.encrypted_key_size; | 1493 | auth_tok->session_key.encrypted_key_size; |
863 | if (ECRYPTFS_CHECK_FLAG(auth_tok->token.password.flags, | 1494 | if (auth_tok->token.password.flags & |
864 | ECRYPTFS_SESSION_KEY_ENCRYPTION_KEY_SET)) { | 1495 | ECRYPTFS_SESSION_KEY_ENCRYPTION_KEY_SET) { |
865 | ecryptfs_printk(KERN_DEBUG, "Using previously generated " | 1496 | ecryptfs_printk(KERN_DEBUG, "Using previously generated " |
866 | "session key encryption key of size [%d]\n", | 1497 | "session key encryption key of size [%d]\n", |
867 | auth_tok->token.password. | 1498 | auth_tok->token.password. |
@@ -879,15 +1510,15 @@ write_tag_3_packet(char *dest, size_t max, struct ecryptfs_auth_tok *auth_tok, | |||
879 | ecryptfs_dump_hex(session_key_encryption_key, 16); | 1510 | ecryptfs_dump_hex(session_key_encryption_key, 16); |
880 | } | 1511 | } |
881 | rc = virt_to_scatterlist(crypt_stat->key, | 1512 | rc = virt_to_scatterlist(crypt_stat->key, |
882 | (*key_rec).enc_key_size, src_sg, 2); | 1513 | key_rec->enc_key_size, src_sg, 2); |
883 | if (!rc) { | 1514 | if (!rc) { |
884 | ecryptfs_printk(KERN_ERR, "Error generating scatterlist " | 1515 | ecryptfs_printk(KERN_ERR, "Error generating scatterlist " |
885 | "for crypt_stat session key\n"); | 1516 | "for crypt_stat session key\n"); |
886 | rc = -ENOMEM; | 1517 | rc = -ENOMEM; |
887 | goto out; | 1518 | goto out; |
888 | } | 1519 | } |
889 | rc = virt_to_scatterlist((*key_rec).enc_key, | 1520 | rc = virt_to_scatterlist(key_rec->enc_key, |
890 | (*key_rec).enc_key_size, dest_sg, 2); | 1521 | key_rec->enc_key_size, dest_sg, 2); |
891 | if (!rc) { | 1522 | if (!rc) { |
892 | ecryptfs_printk(KERN_ERR, "Error generating scatterlist " | 1523 | ecryptfs_printk(KERN_ERR, "Error generating scatterlist " |
893 | "for crypt_stat encrypted session key\n"); | 1524 | "for crypt_stat encrypted session key\n"); |
@@ -943,14 +1574,14 @@ write_tag_3_packet(char *dest, size_t max, struct ecryptfs_auth_tok *auth_tok, | |||
943 | mutex_unlock(tfm_mutex); | 1574 | mutex_unlock(tfm_mutex); |
944 | ecryptfs_printk(KERN_DEBUG, "This should be the encrypted key:\n"); | 1575 | ecryptfs_printk(KERN_DEBUG, "This should be the encrypted key:\n"); |
945 | if (ecryptfs_verbosity > 0) | 1576 | if (ecryptfs_verbosity > 0) |
946 | ecryptfs_dump_hex((*key_rec).enc_key, | 1577 | ecryptfs_dump_hex(key_rec->enc_key, |
947 | (*key_rec).enc_key_size); | 1578 | key_rec->enc_key_size); |
948 | encrypted_session_key_set: | 1579 | encrypted_session_key_set: |
949 | /* Now we have a valid key_rec. Append it to the | 1580 | /* Now we have a valid key_rec. Append it to the |
950 | * key_rec set. */ | 1581 | * key_rec set. */ |
951 | key_rec_size = (sizeof(struct ecryptfs_key_record) | 1582 | key_rec_size = (sizeof(struct ecryptfs_key_record) |
952 | - ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES | 1583 | - ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES |
953 | + ((*key_rec).enc_key_size)); | 1584 | + (key_rec->enc_key_size)); |
954 | /* TODO: Include a packet size limit as a parameter to this | 1585 | /* TODO: Include a packet size limit as a parameter to this |
955 | * function once we have multi-packet headers (for versions | 1586 | * function once we have multi-packet headers (for versions |
956 | * later than 0.1 */ | 1587 | * later than 0.1 */ |
@@ -962,7 +1593,7 @@ encrypted_session_key_set: | |||
962 | /* TODO: Packet size limit */ | 1593 | /* TODO: Packet size limit */ |
963 | /* We have 5 bytes of surrounding packet data */ | 1594 | /* We have 5 bytes of surrounding packet data */ |
964 | if ((0x05 + ECRYPTFS_SALT_SIZE | 1595 | if ((0x05 + ECRYPTFS_SALT_SIZE |
965 | + (*key_rec).enc_key_size) >= max) { | 1596 | + key_rec->enc_key_size) >= max) { |
966 | ecryptfs_printk(KERN_ERR, "Authentication token is too " | 1597 | ecryptfs_printk(KERN_ERR, "Authentication token is too " |
967 | "large\n"); | 1598 | "large\n"); |
968 | rc = -EINVAL; | 1599 | rc = -EINVAL; |
@@ -974,7 +1605,7 @@ encrypted_session_key_set: | |||
974 | /* ver+cipher+s2k+hash+salt+iter+enc_key */ | 1605 | /* ver+cipher+s2k+hash+salt+iter+enc_key */ |
975 | rc = write_packet_length(&dest[(*packet_size)], | 1606 | rc = write_packet_length(&dest[(*packet_size)], |
976 | (0x05 + ECRYPTFS_SALT_SIZE | 1607 | (0x05 + ECRYPTFS_SALT_SIZE |
977 | + (*key_rec).enc_key_size), | 1608 | + key_rec->enc_key_size), |
978 | &packet_size_length); | 1609 | &packet_size_length); |
979 | if (rc) { | 1610 | if (rc) { |
980 | ecryptfs_printk(KERN_ERR, "Error generating tag 3 packet " | 1611 | ecryptfs_printk(KERN_ERR, "Error generating tag 3 packet " |
@@ -997,9 +1628,9 @@ encrypted_session_key_set: | |||
997 | ECRYPTFS_SALT_SIZE); | 1628 | ECRYPTFS_SALT_SIZE); |
998 | (*packet_size) += ECRYPTFS_SALT_SIZE; /* salt */ | 1629 | (*packet_size) += ECRYPTFS_SALT_SIZE; /* salt */ |
999 | dest[(*packet_size)++] = 0x60; /* hash iterations (65536) */ | 1630 | dest[(*packet_size)++] = 0x60; /* hash iterations (65536) */ |
1000 | memcpy(&dest[(*packet_size)], (*key_rec).enc_key, | 1631 | memcpy(&dest[(*packet_size)], key_rec->enc_key, |
1001 | (*key_rec).enc_key_size); | 1632 | key_rec->enc_key_size); |
1002 | (*packet_size) += (*key_rec).enc_key_size; | 1633 | (*packet_size) += key_rec->enc_key_size; |
1003 | out: | 1634 | out: |
1004 | if (desc.tfm && !tfm_mutex) | 1635 | if (desc.tfm && !tfm_mutex) |
1005 | crypto_free_blkcipher(desc.tfm); | 1636 | crypto_free_blkcipher(desc.tfm); |
@@ -1029,13 +1660,13 @@ ecryptfs_generate_key_packet_set(char *dest_base, | |||
1029 | struct dentry *ecryptfs_dentry, size_t *len, | 1660 | struct dentry *ecryptfs_dentry, size_t *len, |
1030 | size_t max) | 1661 | size_t max) |
1031 | { | 1662 | { |
1032 | int rc = 0; | ||
1033 | struct ecryptfs_auth_tok *auth_tok; | 1663 | struct ecryptfs_auth_tok *auth_tok; |
1034 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat = | 1664 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat = |
1035 | &ecryptfs_superblock_to_private( | 1665 | &ecryptfs_superblock_to_private( |
1036 | ecryptfs_dentry->d_sb)->mount_crypt_stat; | 1666 | ecryptfs_dentry->d_sb)->mount_crypt_stat; |
1037 | size_t written; | 1667 | size_t written; |
1038 | struct ecryptfs_key_record key_rec; | 1668 | struct ecryptfs_key_record key_rec; |
1669 | int rc = 0; | ||
1039 | 1670 | ||
1040 | (*len) = 0; | 1671 | (*len) = 0; |
1041 | if (mount_crypt_stat->global_auth_tok) { | 1672 | if (mount_crypt_stat->global_auth_tok) { |
@@ -1062,20 +1693,23 @@ ecryptfs_generate_key_packet_set(char *dest_base, | |||
1062 | goto out; | 1693 | goto out; |
1063 | } | 1694 | } |
1064 | (*len) += written; | 1695 | (*len) += written; |
1696 | } else if (auth_tok->token_type == ECRYPTFS_PRIVATE_KEY) { | ||
1697 | rc = write_tag_1_packet(dest_base + (*len), | ||
1698 | max, auth_tok, | ||
1699 | crypt_stat,mount_crypt_stat, | ||
1700 | &key_rec, &written); | ||
1701 | if (rc) { | ||
1702 | ecryptfs_printk(KERN_WARNING, "Error " | ||
1703 | "writing tag 1 packet\n"); | ||
1704 | goto out; | ||
1705 | } | ||
1706 | (*len) += written; | ||
1065 | } else { | 1707 | } else { |
1066 | ecryptfs_printk(KERN_WARNING, "Unsupported " | 1708 | ecryptfs_printk(KERN_WARNING, "Unsupported " |
1067 | "authentication token type\n"); | 1709 | "authentication token type\n"); |
1068 | rc = -EINVAL; | 1710 | rc = -EINVAL; |
1069 | goto out; | 1711 | goto out; |
1070 | } | 1712 | } |
1071 | if (rc) { | ||
1072 | ecryptfs_printk(KERN_WARNING, "Error writing " | ||
1073 | "authentication token packet with sig " | ||
1074 | "= [%s]\n", | ||
1075 | mount_crypt_stat->global_auth_tok_sig); | ||
1076 | rc = -EIO; | ||
1077 | goto out; | ||
1078 | } | ||
1079 | } else | 1713 | } else |
1080 | BUG(); | 1714 | BUG(); |
1081 | if (likely((max - (*len)) > 0)) { | 1715 | if (likely((max - (*len)) > 0)) { |
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 | } |
diff --git a/fs/ecryptfs/messaging.c b/fs/ecryptfs/messaging.c new file mode 100644 index 000000000000..47d7e7b611f7 --- /dev/null +++ b/fs/ecryptfs/messaging.c | |||
@@ -0,0 +1,515 @@ | |||
1 | /** | ||
2 | * eCryptfs: Linux filesystem encryption layer | ||
3 | * | ||
4 | * Copyright (C) 2004-2006 International Business Machines Corp. | ||
5 | * Author(s): Michael A. Halcrow <mhalcrow@us.ibm.com> | ||
6 | * Tyler Hicks <tyhicks@ou.edu> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or | ||
9 | * modify it under the terms of the GNU General Public License version | ||
10 | * 2 as published by the Free Software Foundation. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, but | ||
13 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
15 | * General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA | ||
20 | * 02111-1307, USA. | ||
21 | */ | ||
22 | |||
23 | #include "ecryptfs_kernel.h" | ||
24 | |||
25 | static LIST_HEAD(ecryptfs_msg_ctx_free_list); | ||
26 | static LIST_HEAD(ecryptfs_msg_ctx_alloc_list); | ||
27 | static struct mutex ecryptfs_msg_ctx_lists_mux; | ||
28 | |||
29 | static struct hlist_head *ecryptfs_daemon_id_hash; | ||
30 | static struct mutex ecryptfs_daemon_id_hash_mux; | ||
31 | static int ecryptfs_hash_buckets; | ||
32 | #define ecryptfs_uid_hash(uid) \ | ||
33 | hash_long((unsigned long)uid, ecryptfs_hash_buckets) | ||
34 | |||
35 | static unsigned int ecryptfs_msg_counter; | ||
36 | static struct ecryptfs_msg_ctx *ecryptfs_msg_ctx_arr; | ||
37 | |||
38 | /** | ||
39 | * ecryptfs_acquire_free_msg_ctx | ||
40 | * @msg_ctx: The context that was acquired from the free list | ||
41 | * | ||
42 | * Acquires a context element from the free list and locks the mutex | ||
43 | * on the context. Returns zero on success; non-zero on error or upon | ||
44 | * failure to acquire a free context element. Be sure to lock the | ||
45 | * list mutex before calling. | ||
46 | */ | ||
47 | static int ecryptfs_acquire_free_msg_ctx(struct ecryptfs_msg_ctx **msg_ctx) | ||
48 | { | ||
49 | struct list_head *p; | ||
50 | int rc; | ||
51 | |||
52 | if (list_empty(&ecryptfs_msg_ctx_free_list)) { | ||
53 | ecryptfs_printk(KERN_WARNING, "The eCryptfs free " | ||
54 | "context list is empty. It may be helpful to " | ||
55 | "specify the ecryptfs_message_buf_len " | ||
56 | "parameter to be greater than the current " | ||
57 | "value of [%d]\n", ecryptfs_message_buf_len); | ||
58 | rc = -ENOMEM; | ||
59 | goto out; | ||
60 | } | ||
61 | list_for_each(p, &ecryptfs_msg_ctx_free_list) { | ||
62 | *msg_ctx = list_entry(p, struct ecryptfs_msg_ctx, node); | ||
63 | if (mutex_trylock(&(*msg_ctx)->mux)) { | ||
64 | (*msg_ctx)->task = current; | ||
65 | rc = 0; | ||
66 | goto out; | ||
67 | } | ||
68 | } | ||
69 | rc = -ENOMEM; | ||
70 | out: | ||
71 | return rc; | ||
72 | } | ||
73 | |||
74 | /** | ||
75 | * ecryptfs_msg_ctx_free_to_alloc | ||
76 | * @msg_ctx: The context to move from the free list to the alloc list | ||
77 | * | ||
78 | * Be sure to lock the list mutex and the context mutex before | ||
79 | * calling. | ||
80 | */ | ||
81 | static void ecryptfs_msg_ctx_free_to_alloc(struct ecryptfs_msg_ctx *msg_ctx) | ||
82 | { | ||
83 | list_move(&msg_ctx->node, &ecryptfs_msg_ctx_alloc_list); | ||
84 | msg_ctx->state = ECRYPTFS_MSG_CTX_STATE_PENDING; | ||
85 | msg_ctx->counter = ++ecryptfs_msg_counter; | ||
86 | } | ||
87 | |||
88 | /** | ||
89 | * ecryptfs_msg_ctx_alloc_to_free | ||
90 | * @msg_ctx: The context to move from the alloc list to the free list | ||
91 | * | ||
92 | * Be sure to lock the list mutex and the context mutex before | ||
93 | * calling. | ||
94 | */ | ||
95 | static void ecryptfs_msg_ctx_alloc_to_free(struct ecryptfs_msg_ctx *msg_ctx) | ||
96 | { | ||
97 | list_move(&(msg_ctx->node), &ecryptfs_msg_ctx_free_list); | ||
98 | if (msg_ctx->msg) | ||
99 | kfree(msg_ctx->msg); | ||
100 | msg_ctx->state = ECRYPTFS_MSG_CTX_STATE_FREE; | ||
101 | } | ||
102 | |||
103 | /** | ||
104 | * ecryptfs_find_daemon_id | ||
105 | * @uid: The user id which maps to the desired daemon id | ||
106 | * @id: If return value is zero, points to the desired daemon id | ||
107 | * pointer | ||
108 | * | ||
109 | * Search the hash list for the given user id. Returns zero if the | ||
110 | * user id exists in the list; non-zero otherwise. The daemon id hash | ||
111 | * mutex should be held before calling this function. | ||
112 | */ | ||
113 | static int ecryptfs_find_daemon_id(uid_t uid, struct ecryptfs_daemon_id **id) | ||
114 | { | ||
115 | struct hlist_node *elem; | ||
116 | int rc; | ||
117 | |||
118 | hlist_for_each_entry(*id, elem, | ||
119 | &ecryptfs_daemon_id_hash[ecryptfs_uid_hash(uid)], | ||
120 | id_chain) { | ||
121 | if ((*id)->uid == uid) { | ||
122 | rc = 0; | ||
123 | goto out; | ||
124 | } | ||
125 | } | ||
126 | rc = -EINVAL; | ||
127 | out: | ||
128 | return rc; | ||
129 | } | ||
130 | |||
131 | static int ecryptfs_send_raw_message(unsigned int transport, u16 msg_type, | ||
132 | pid_t pid) | ||
133 | { | ||
134 | int rc; | ||
135 | |||
136 | switch(transport) { | ||
137 | case ECRYPTFS_TRANSPORT_NETLINK: | ||
138 | rc = ecryptfs_send_netlink(NULL, 0, NULL, msg_type, 0, pid); | ||
139 | break; | ||
140 | case ECRYPTFS_TRANSPORT_CONNECTOR: | ||
141 | case ECRYPTFS_TRANSPORT_RELAYFS: | ||
142 | default: | ||
143 | rc = -ENOSYS; | ||
144 | } | ||
145 | return rc; | ||
146 | } | ||
147 | |||
148 | /** | ||
149 | * ecryptfs_process_helo | ||
150 | * @transport: The underlying transport (netlink, etc.) | ||
151 | * @uid: The user ID owner of the message | ||
152 | * @pid: The process ID for the userspace program that sent the | ||
153 | * message | ||
154 | * | ||
155 | * Adds the uid and pid values to the daemon id hash. If a uid | ||
156 | * already has a daemon pid registered, the daemon will be | ||
157 | * unregistered before the new daemon id is put into the hash list. | ||
158 | * Returns zero after adding a new daemon id to the hash list; | ||
159 | * non-zero otherwise. | ||
160 | */ | ||
161 | int ecryptfs_process_helo(unsigned int transport, uid_t uid, pid_t pid) | ||
162 | { | ||
163 | struct ecryptfs_daemon_id *new_id; | ||
164 | struct ecryptfs_daemon_id *old_id; | ||
165 | int rc; | ||
166 | |||
167 | mutex_lock(&ecryptfs_daemon_id_hash_mux); | ||
168 | new_id = kmalloc(sizeof(*new_id), GFP_KERNEL); | ||
169 | if (!new_id) { | ||
170 | rc = -ENOMEM; | ||
171 | ecryptfs_printk(KERN_ERR, "Failed to allocate memory; unable " | ||
172 | "to register daemon [%d] for user\n", pid, uid); | ||
173 | goto unlock; | ||
174 | } | ||
175 | if (!ecryptfs_find_daemon_id(uid, &old_id)) { | ||
176 | printk(KERN_WARNING "Received request from user [%d] " | ||
177 | "to register daemon [%d]; unregistering daemon " | ||
178 | "[%d]\n", uid, pid, old_id->pid); | ||
179 | hlist_del(&old_id->id_chain); | ||
180 | rc = ecryptfs_send_raw_message(transport, ECRYPTFS_NLMSG_QUIT, | ||
181 | old_id->pid); | ||
182 | if (rc) | ||
183 | printk(KERN_WARNING "Failed to send QUIT " | ||
184 | "message to daemon [%d]; rc = [%d]\n", | ||
185 | old_id->pid, rc); | ||
186 | kfree(old_id); | ||
187 | } | ||
188 | new_id->uid = uid; | ||
189 | new_id->pid = pid; | ||
190 | hlist_add_head(&new_id->id_chain, | ||
191 | &ecryptfs_daemon_id_hash[ecryptfs_uid_hash(uid)]); | ||
192 | rc = 0; | ||
193 | unlock: | ||
194 | mutex_unlock(&ecryptfs_daemon_id_hash_mux); | ||
195 | return rc; | ||
196 | } | ||
197 | |||
198 | /** | ||
199 | * ecryptfs_process_quit | ||
200 | * @uid: The user ID owner of the message | ||
201 | * @pid: The process ID for the userspace program that sent the | ||
202 | * message | ||
203 | * | ||
204 | * Deletes the corresponding daemon id for the given uid and pid, if | ||
205 | * it is the registered that is requesting the deletion. Returns zero | ||
206 | * after deleting the desired daemon id; non-zero otherwise. | ||
207 | */ | ||
208 | int ecryptfs_process_quit(uid_t uid, pid_t pid) | ||
209 | { | ||
210 | struct ecryptfs_daemon_id *id; | ||
211 | int rc; | ||
212 | |||
213 | mutex_lock(&ecryptfs_daemon_id_hash_mux); | ||
214 | if (ecryptfs_find_daemon_id(uid, &id)) { | ||
215 | rc = -EINVAL; | ||
216 | ecryptfs_printk(KERN_ERR, "Received request from user [%d] to " | ||
217 | "unregister unrecognized daemon [%d]\n", uid, | ||
218 | pid); | ||
219 | goto unlock; | ||
220 | } | ||
221 | if (id->pid != pid) { | ||
222 | rc = -EINVAL; | ||
223 | ecryptfs_printk(KERN_WARNING, "Received request from user [%d] " | ||
224 | "with pid [%d] to unregister daemon [%d]\n", | ||
225 | uid, pid, id->pid); | ||
226 | goto unlock; | ||
227 | } | ||
228 | hlist_del(&id->id_chain); | ||
229 | kfree(id); | ||
230 | rc = 0; | ||
231 | unlock: | ||
232 | mutex_unlock(&ecryptfs_daemon_id_hash_mux); | ||
233 | return rc; | ||
234 | } | ||
235 | |||
236 | /** | ||
237 | * ecryptfs_process_reponse | ||
238 | * @msg: The ecryptfs message received; the caller should sanity check | ||
239 | * msg->data_len | ||
240 | * @pid: The process ID of the userspace application that sent the | ||
241 | * message | ||
242 | * @seq: The sequence number of the message | ||
243 | * | ||
244 | * Processes a response message after sending a operation request to | ||
245 | * userspace. Returns zero upon delivery to desired context element; | ||
246 | * non-zero upon delivery failure or error. | ||
247 | */ | ||
248 | int ecryptfs_process_response(struct ecryptfs_message *msg, uid_t uid, | ||
249 | pid_t pid, u32 seq) | ||
250 | { | ||
251 | struct ecryptfs_daemon_id *id; | ||
252 | struct ecryptfs_msg_ctx *msg_ctx; | ||
253 | int msg_size; | ||
254 | int rc; | ||
255 | |||
256 | if (msg->index >= ecryptfs_message_buf_len) { | ||
257 | rc = -EINVAL; | ||
258 | ecryptfs_printk(KERN_ERR, "Attempt to reference " | ||
259 | "context buffer at index [%d]; maximum " | ||
260 | "allowable is [%d]\n", msg->index, | ||
261 | (ecryptfs_message_buf_len - 1)); | ||
262 | goto out; | ||
263 | } | ||
264 | msg_ctx = &ecryptfs_msg_ctx_arr[msg->index]; | ||
265 | mutex_lock(&msg_ctx->mux); | ||
266 | if (ecryptfs_find_daemon_id(msg_ctx->task->euid, &id)) { | ||
267 | rc = -EBADMSG; | ||
268 | ecryptfs_printk(KERN_WARNING, "User [%d] received a " | ||
269 | "message response from process [%d] but does " | ||
270 | "not have a registered daemon\n", | ||
271 | msg_ctx->task->euid, pid); | ||
272 | goto wake_up; | ||
273 | } | ||
274 | if (msg_ctx->task->euid != uid) { | ||
275 | rc = -EBADMSG; | ||
276 | ecryptfs_printk(KERN_WARNING, "Received message from user " | ||
277 | "[%d]; expected message from user [%d]\n", | ||
278 | uid, msg_ctx->task->euid); | ||
279 | goto unlock; | ||
280 | } | ||
281 | if (id->pid != pid) { | ||
282 | rc = -EBADMSG; | ||
283 | ecryptfs_printk(KERN_ERR, "User [%d] received a " | ||
284 | "message response from an unrecognized " | ||
285 | "process [%d]\n", msg_ctx->task->euid, pid); | ||
286 | goto unlock; | ||
287 | } | ||
288 | if (msg_ctx->state != ECRYPTFS_MSG_CTX_STATE_PENDING) { | ||
289 | rc = -EINVAL; | ||
290 | ecryptfs_printk(KERN_WARNING, "Desired context element is not " | ||
291 | "pending a response\n"); | ||
292 | goto unlock; | ||
293 | } else if (msg_ctx->counter != seq) { | ||
294 | rc = -EINVAL; | ||
295 | ecryptfs_printk(KERN_WARNING, "Invalid message sequence; " | ||
296 | "expected [%d]; received [%d]\n", | ||
297 | msg_ctx->counter, seq); | ||
298 | goto unlock; | ||
299 | } | ||
300 | msg_size = sizeof(*msg) + msg->data_len; | ||
301 | msg_ctx->msg = kmalloc(msg_size, GFP_KERNEL); | ||
302 | if (!msg_ctx->msg) { | ||
303 | rc = -ENOMEM; | ||
304 | ecryptfs_printk(KERN_ERR, "Failed to allocate memory\n"); | ||
305 | goto unlock; | ||
306 | } | ||
307 | memcpy(msg_ctx->msg, msg, msg_size); | ||
308 | msg_ctx->state = ECRYPTFS_MSG_CTX_STATE_DONE; | ||
309 | rc = 0; | ||
310 | wake_up: | ||
311 | wake_up_process(msg_ctx->task); | ||
312 | unlock: | ||
313 | mutex_unlock(&msg_ctx->mux); | ||
314 | out: | ||
315 | return rc; | ||
316 | } | ||
317 | |||
318 | /** | ||
319 | * ecryptfs_send_message | ||
320 | * @transport: The transport over which to send the message (i.e., | ||
321 | * netlink) | ||
322 | * @data: The data to send | ||
323 | * @data_len: The length of data | ||
324 | * @msg_ctx: The message context allocated for the send | ||
325 | */ | ||
326 | int ecryptfs_send_message(unsigned int transport, char *data, int data_len, | ||
327 | struct ecryptfs_msg_ctx **msg_ctx) | ||
328 | { | ||
329 | struct ecryptfs_daemon_id *id; | ||
330 | int rc; | ||
331 | |||
332 | mutex_lock(&ecryptfs_daemon_id_hash_mux); | ||
333 | if (ecryptfs_find_daemon_id(current->euid, &id)) { | ||
334 | mutex_unlock(&ecryptfs_daemon_id_hash_mux); | ||
335 | rc = -ENOTCONN; | ||
336 | ecryptfs_printk(KERN_ERR, "User [%d] does not have a daemon " | ||
337 | "registered\n", current->euid); | ||
338 | goto out; | ||
339 | } | ||
340 | mutex_unlock(&ecryptfs_daemon_id_hash_mux); | ||
341 | mutex_lock(&ecryptfs_msg_ctx_lists_mux); | ||
342 | rc = ecryptfs_acquire_free_msg_ctx(msg_ctx); | ||
343 | if (rc) { | ||
344 | mutex_unlock(&ecryptfs_msg_ctx_lists_mux); | ||
345 | ecryptfs_printk(KERN_WARNING, "Could not claim a free " | ||
346 | "context element\n"); | ||
347 | goto out; | ||
348 | } | ||
349 | ecryptfs_msg_ctx_free_to_alloc(*msg_ctx); | ||
350 | mutex_unlock(&(*msg_ctx)->mux); | ||
351 | mutex_unlock(&ecryptfs_msg_ctx_lists_mux); | ||
352 | switch (transport) { | ||
353 | case ECRYPTFS_TRANSPORT_NETLINK: | ||
354 | rc = ecryptfs_send_netlink(data, data_len, *msg_ctx, | ||
355 | ECRYPTFS_NLMSG_REQUEST, 0, id->pid); | ||
356 | break; | ||
357 | case ECRYPTFS_TRANSPORT_CONNECTOR: | ||
358 | case ECRYPTFS_TRANSPORT_RELAYFS: | ||
359 | default: | ||
360 | rc = -ENOSYS; | ||
361 | } | ||
362 | if (rc) { | ||
363 | printk(KERN_ERR "Error attempting to send message to userspace " | ||
364 | "daemon; rc = [%d]\n", rc); | ||
365 | } | ||
366 | out: | ||
367 | return rc; | ||
368 | } | ||
369 | |||
370 | /** | ||
371 | * ecryptfs_wait_for_response | ||
372 | * @msg_ctx: The context that was assigned when sending a message | ||
373 | * @msg: The incoming message from userspace; not set if rc != 0 | ||
374 | * | ||
375 | * Sleeps until awaken by ecryptfs_receive_message or until the amount | ||
376 | * of time exceeds ecryptfs_message_wait_timeout. If zero is | ||
377 | * returned, msg will point to a valid message from userspace; a | ||
378 | * non-zero value is returned upon failure to receive a message or an | ||
379 | * error occurs. | ||
380 | */ | ||
381 | int ecryptfs_wait_for_response(struct ecryptfs_msg_ctx *msg_ctx, | ||
382 | struct ecryptfs_message **msg) | ||
383 | { | ||
384 | signed long timeout = ecryptfs_message_wait_timeout * HZ; | ||
385 | int rc = 0; | ||
386 | |||
387 | sleep: | ||
388 | timeout = schedule_timeout_interruptible(timeout); | ||
389 | mutex_lock(&ecryptfs_msg_ctx_lists_mux); | ||
390 | mutex_lock(&msg_ctx->mux); | ||
391 | if (msg_ctx->state != ECRYPTFS_MSG_CTX_STATE_DONE) { | ||
392 | if (timeout) { | ||
393 | mutex_unlock(&msg_ctx->mux); | ||
394 | mutex_unlock(&ecryptfs_msg_ctx_lists_mux); | ||
395 | goto sleep; | ||
396 | } | ||
397 | rc = -ENOMSG; | ||
398 | } else { | ||
399 | *msg = msg_ctx->msg; | ||
400 | msg_ctx->msg = NULL; | ||
401 | } | ||
402 | ecryptfs_msg_ctx_alloc_to_free(msg_ctx); | ||
403 | mutex_unlock(&msg_ctx->mux); | ||
404 | mutex_unlock(&ecryptfs_msg_ctx_lists_mux); | ||
405 | return rc; | ||
406 | } | ||
407 | |||
408 | int ecryptfs_init_messaging(unsigned int transport) | ||
409 | { | ||
410 | int i; | ||
411 | int rc = 0; | ||
412 | |||
413 | if (ecryptfs_number_of_users > ECRYPTFS_MAX_NUM_USERS) { | ||
414 | ecryptfs_number_of_users = ECRYPTFS_MAX_NUM_USERS; | ||
415 | ecryptfs_printk(KERN_WARNING, "Specified number of users is " | ||
416 | "too large, defaulting to [%d] users\n", | ||
417 | ecryptfs_number_of_users); | ||
418 | } | ||
419 | mutex_init(&ecryptfs_daemon_id_hash_mux); | ||
420 | mutex_lock(&ecryptfs_daemon_id_hash_mux); | ||
421 | ecryptfs_hash_buckets = 0; | ||
422 | while (ecryptfs_number_of_users >> ++ecryptfs_hash_buckets); | ||
423 | ecryptfs_daemon_id_hash = kmalloc(sizeof(struct hlist_head) | ||
424 | * ecryptfs_hash_buckets, GFP_KERNEL); | ||
425 | if (!ecryptfs_daemon_id_hash) { | ||
426 | rc = -ENOMEM; | ||
427 | ecryptfs_printk(KERN_ERR, "Failed to allocate memory\n"); | ||
428 | goto out; | ||
429 | } | ||
430 | for (i = 0; i < ecryptfs_hash_buckets; i++) | ||
431 | INIT_HLIST_HEAD(&ecryptfs_daemon_id_hash[i]); | ||
432 | mutex_unlock(&ecryptfs_daemon_id_hash_mux); | ||
433 | |||
434 | ecryptfs_msg_ctx_arr = kmalloc((sizeof(struct ecryptfs_msg_ctx) | ||
435 | * ecryptfs_message_buf_len), GFP_KERNEL); | ||
436 | if (!ecryptfs_msg_ctx_arr) { | ||
437 | rc = -ENOMEM; | ||
438 | ecryptfs_printk(KERN_ERR, "Failed to allocate memory\n"); | ||
439 | goto out; | ||
440 | } | ||
441 | mutex_init(&ecryptfs_msg_ctx_lists_mux); | ||
442 | mutex_lock(&ecryptfs_msg_ctx_lists_mux); | ||
443 | ecryptfs_msg_counter = 0; | ||
444 | for (i = 0; i < ecryptfs_message_buf_len; i++) { | ||
445 | INIT_LIST_HEAD(&ecryptfs_msg_ctx_arr[i].node); | ||
446 | mutex_init(&ecryptfs_msg_ctx_arr[i].mux); | ||
447 | mutex_lock(&ecryptfs_msg_ctx_arr[i].mux); | ||
448 | ecryptfs_msg_ctx_arr[i].index = i; | ||
449 | ecryptfs_msg_ctx_arr[i].state = ECRYPTFS_MSG_CTX_STATE_FREE; | ||
450 | ecryptfs_msg_ctx_arr[i].counter = 0; | ||
451 | ecryptfs_msg_ctx_arr[i].task = NULL; | ||
452 | ecryptfs_msg_ctx_arr[i].msg = NULL; | ||
453 | list_add_tail(&ecryptfs_msg_ctx_arr[i].node, | ||
454 | &ecryptfs_msg_ctx_free_list); | ||
455 | mutex_unlock(&ecryptfs_msg_ctx_arr[i].mux); | ||
456 | } | ||
457 | mutex_unlock(&ecryptfs_msg_ctx_lists_mux); | ||
458 | switch(transport) { | ||
459 | case ECRYPTFS_TRANSPORT_NETLINK: | ||
460 | rc = ecryptfs_init_netlink(); | ||
461 | if (rc) | ||
462 | ecryptfs_release_messaging(transport); | ||
463 | break; | ||
464 | case ECRYPTFS_TRANSPORT_CONNECTOR: | ||
465 | case ECRYPTFS_TRANSPORT_RELAYFS: | ||
466 | default: | ||
467 | rc = -ENOSYS; | ||
468 | } | ||
469 | out: | ||
470 | return rc; | ||
471 | } | ||
472 | |||
473 | void ecryptfs_release_messaging(unsigned int transport) | ||
474 | { | ||
475 | if (ecryptfs_msg_ctx_arr) { | ||
476 | int i; | ||
477 | |||
478 | mutex_lock(&ecryptfs_msg_ctx_lists_mux); | ||
479 | for (i = 0; i < ecryptfs_message_buf_len; i++) { | ||
480 | mutex_lock(&ecryptfs_msg_ctx_arr[i].mux); | ||
481 | if (ecryptfs_msg_ctx_arr[i].msg) | ||
482 | kfree(ecryptfs_msg_ctx_arr[i].msg); | ||
483 | mutex_unlock(&ecryptfs_msg_ctx_arr[i].mux); | ||
484 | } | ||
485 | kfree(ecryptfs_msg_ctx_arr); | ||
486 | mutex_unlock(&ecryptfs_msg_ctx_lists_mux); | ||
487 | } | ||
488 | if (ecryptfs_daemon_id_hash) { | ||
489 | struct hlist_node *elem; | ||
490 | struct ecryptfs_daemon_id *id; | ||
491 | int i; | ||
492 | |||
493 | mutex_lock(&ecryptfs_daemon_id_hash_mux); | ||
494 | for (i = 0; i < ecryptfs_hash_buckets; i++) { | ||
495 | hlist_for_each_entry(id, elem, | ||
496 | &ecryptfs_daemon_id_hash[i], | ||
497 | id_chain) { | ||
498 | hlist_del(elem); | ||
499 | kfree(id); | ||
500 | } | ||
501 | } | ||
502 | kfree(ecryptfs_daemon_id_hash); | ||
503 | mutex_unlock(&ecryptfs_daemon_id_hash_mux); | ||
504 | } | ||
505 | switch(transport) { | ||
506 | case ECRYPTFS_TRANSPORT_NETLINK: | ||
507 | ecryptfs_release_netlink(); | ||
508 | break; | ||
509 | case ECRYPTFS_TRANSPORT_CONNECTOR: | ||
510 | case ECRYPTFS_TRANSPORT_RELAYFS: | ||
511 | default: | ||
512 | break; | ||
513 | } | ||
514 | return; | ||
515 | } | ||
diff --git a/fs/ecryptfs/mmap.c b/fs/ecryptfs/mmap.c index 06843d24f239..3a6f65c3f14f 100644 --- a/fs/ecryptfs/mmap.c +++ b/fs/ecryptfs/mmap.c | |||
@@ -6,7 +6,7 @@ | |||
6 | * | 6 | * |
7 | * Copyright (C) 1997-2003 Erez Zadok | 7 | * Copyright (C) 1997-2003 Erez Zadok |
8 | * Copyright (C) 2001-2003 Stony Brook University | 8 | * Copyright (C) 2001-2003 Stony Brook University |
9 | * Copyright (C) 2004-2006 International Business Machines Corp. | 9 | * Copyright (C) 2004-2007 International Business Machines Corp. |
10 | * Author(s): Michael A. Halcrow <mahalcro@us.ibm.com> | 10 | * Author(s): Michael A. Halcrow <mahalcro@us.ibm.com> |
11 | * | 11 | * |
12 | * This program is free software; you can redistribute it and/or | 12 | * This program is free software; you can redistribute it and/or |
@@ -234,22 +234,13 @@ int ecryptfs_do_readpage(struct file *file, struct page *page, | |||
234 | goto out; | 234 | goto out; |
235 | } | 235 | } |
236 | wait_on_page_locked(lower_page); | 236 | wait_on_page_locked(lower_page); |
237 | page_data = (char *)kmap(page); | 237 | page_data = kmap_atomic(page, KM_USER0); |
238 | if (!page_data) { | 238 | lower_page_data = kmap_atomic(lower_page, KM_USER1); |
239 | rc = -ENOMEM; | ||
240 | ecryptfs_printk(KERN_ERR, "Error mapping page\n"); | ||
241 | goto out; | ||
242 | } | ||
243 | lower_page_data = (char *)kmap(lower_page); | ||
244 | if (!lower_page_data) { | ||
245 | rc = -ENOMEM; | ||
246 | ecryptfs_printk(KERN_ERR, "Error mapping page\n"); | ||
247 | kunmap(page); | ||
248 | goto out; | ||
249 | } | ||
250 | memcpy(page_data, lower_page_data, PAGE_CACHE_SIZE); | 239 | memcpy(page_data, lower_page_data, PAGE_CACHE_SIZE); |
251 | kunmap(lower_page); | 240 | kunmap_atomic(lower_page_data, KM_USER1); |
252 | kunmap(page); | 241 | flush_dcache_page(lower_page); |
242 | kunmap_atomic(page_data, KM_USER0); | ||
243 | flush_dcache_page(page); | ||
253 | rc = 0; | 244 | rc = 0; |
254 | out: | 245 | out: |
255 | if (likely(lower_page)) | 246 | if (likely(lower_page)) |
@@ -260,6 +251,33 @@ out: | |||
260 | ClearPageUptodate(page); | 251 | ClearPageUptodate(page); |
261 | return rc; | 252 | return rc; |
262 | } | 253 | } |
254 | /** | ||
255 | * Header Extent: | ||
256 | * Octets 0-7: Unencrypted file size (big-endian) | ||
257 | * Octets 8-15: eCryptfs special marker | ||
258 | * Octets 16-19: Flags | ||
259 | * Octet 16: File format version number (between 0 and 255) | ||
260 | * Octets 17-18: Reserved | ||
261 | * Octet 19: Bit 1 (lsb): Reserved | ||
262 | * Bit 2: Encrypted? | ||
263 | * Bits 3-8: Reserved | ||
264 | * Octets 20-23: Header extent size (big-endian) | ||
265 | * Octets 24-25: Number of header extents at front of file | ||
266 | * (big-endian) | ||
267 | * Octet 26: Begin RFC 2440 authentication token packet set | ||
268 | */ | ||
269 | static void set_header_info(char *page_virt, | ||
270 | struct ecryptfs_crypt_stat *crypt_stat) | ||
271 | { | ||
272 | size_t written; | ||
273 | int save_num_header_extents_at_front = | ||
274 | crypt_stat->num_header_extents_at_front; | ||
275 | |||
276 | crypt_stat->num_header_extents_at_front = 1; | ||
277 | ecryptfs_write_header_metadata(page_virt + 20, crypt_stat, &written); | ||
278 | crypt_stat->num_header_extents_at_front = | ||
279 | save_num_header_extents_at_front; | ||
280 | } | ||
263 | 281 | ||
264 | /** | 282 | /** |
265 | * ecryptfs_readpage | 283 | * ecryptfs_readpage |
@@ -279,8 +297,8 @@ static int ecryptfs_readpage(struct file *file, struct page *page) | |||
279 | crypt_stat = &ecryptfs_inode_to_private(file->f_path.dentry->d_inode) | 297 | crypt_stat = &ecryptfs_inode_to_private(file->f_path.dentry->d_inode) |
280 | ->crypt_stat; | 298 | ->crypt_stat; |
281 | if (!crypt_stat | 299 | if (!crypt_stat |
282 | || !ECRYPTFS_CHECK_FLAG(crypt_stat->flags, ECRYPTFS_ENCRYPTED) | 300 | || !(crypt_stat->flags & ECRYPTFS_ENCRYPTED) |
283 | || ECRYPTFS_CHECK_FLAG(crypt_stat->flags, ECRYPTFS_NEW_FILE)) { | 301 | || (crypt_stat->flags & ECRYPTFS_NEW_FILE)) { |
284 | ecryptfs_printk(KERN_DEBUG, | 302 | ecryptfs_printk(KERN_DEBUG, |
285 | "Passing through unencrypted page\n"); | 303 | "Passing through unencrypted page\n"); |
286 | rc = ecryptfs_do_readpage(file, page, page->index); | 304 | rc = ecryptfs_do_readpage(file, page, page->index); |
@@ -289,10 +307,51 @@ static int ecryptfs_readpage(struct file *file, struct page *page) | |||
289 | "[%d]\n", rc); | 307 | "[%d]\n", rc); |
290 | goto out; | 308 | goto out; |
291 | } | 309 | } |
310 | } else if (crypt_stat->flags & ECRYPTFS_VIEW_AS_ENCRYPTED) { | ||
311 | if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR) { | ||
312 | int num_pages_in_header_region = | ||
313 | (crypt_stat->header_extent_size | ||
314 | / PAGE_CACHE_SIZE); | ||
315 | |||
316 | if (page->index < num_pages_in_header_region) { | ||
317 | char *page_virt; | ||
318 | |||
319 | page_virt = kmap_atomic(page, KM_USER0); | ||
320 | memset(page_virt, 0, PAGE_CACHE_SIZE); | ||
321 | if (page->index == 0) { | ||
322 | rc = ecryptfs_read_xattr_region( | ||
323 | page_virt, file->f_path.dentry); | ||
324 | set_header_info(page_virt, crypt_stat); | ||
325 | } | ||
326 | kunmap_atomic(page_virt, KM_USER0); | ||
327 | flush_dcache_page(page); | ||
328 | if (rc) { | ||
329 | printk(KERN_ERR "Error reading xattr " | ||
330 | "region\n"); | ||
331 | goto out; | ||
332 | } | ||
333 | } else { | ||
334 | rc = ecryptfs_do_readpage( | ||
335 | file, page, | ||
336 | (page->index | ||
337 | - num_pages_in_header_region)); | ||
338 | if (rc) { | ||
339 | printk(KERN_ERR "Error reading page; " | ||
340 | "rc = [%d]\n", rc); | ||
341 | goto out; | ||
342 | } | ||
343 | } | ||
344 | } else { | ||
345 | rc = ecryptfs_do_readpage(file, page, page->index); | ||
346 | if (rc) { | ||
347 | printk(KERN_ERR "Error reading page; rc = " | ||
348 | "[%d]\n", rc); | ||
349 | goto out; | ||
350 | } | ||
351 | } | ||
292 | } else { | 352 | } else { |
293 | rc = ecryptfs_decrypt_page(file, page); | 353 | rc = ecryptfs_decrypt_page(file, page); |
294 | if (rc) { | 354 | if (rc) { |
295 | |||
296 | ecryptfs_printk(KERN_ERR, "Error decrypting page; " | 355 | ecryptfs_printk(KERN_ERR, "Error decrypting page; " |
297 | "rc = [%d]\n", rc); | 356 | "rc = [%d]\n", rc); |
298 | goto out; | 357 | goto out; |
@@ -308,30 +367,27 @@ out: | |||
308 | return rc; | 367 | return rc; |
309 | } | 368 | } |
310 | 369 | ||
370 | /** | ||
371 | * Called with lower inode mutex held. | ||
372 | */ | ||
311 | static int fill_zeros_to_end_of_page(struct page *page, unsigned int to) | 373 | static int fill_zeros_to_end_of_page(struct page *page, unsigned int to) |
312 | { | 374 | { |
313 | struct inode *inode = page->mapping->host; | 375 | struct inode *inode = page->mapping->host; |
314 | int end_byte_in_page; | 376 | int end_byte_in_page; |
315 | int rc = 0; | ||
316 | char *page_virt; | 377 | char *page_virt; |
317 | 378 | ||
318 | if ((i_size_read(inode) / PAGE_CACHE_SIZE) == page->index) { | 379 | if ((i_size_read(inode) / PAGE_CACHE_SIZE) != page->index) |
319 | end_byte_in_page = i_size_read(inode) % PAGE_CACHE_SIZE; | 380 | goto out; |
320 | if (to > end_byte_in_page) | 381 | end_byte_in_page = i_size_read(inode) % PAGE_CACHE_SIZE; |
321 | end_byte_in_page = to; | 382 | if (to > end_byte_in_page) |
322 | page_virt = kmap(page); | 383 | end_byte_in_page = to; |
323 | if (!page_virt) { | 384 | page_virt = kmap_atomic(page, KM_USER0); |
324 | rc = -ENOMEM; | 385 | memset((page_virt + end_byte_in_page), 0, |
325 | ecryptfs_printk(KERN_WARNING, | 386 | (PAGE_CACHE_SIZE - end_byte_in_page)); |
326 | "Could not map page\n"); | 387 | kunmap_atomic(page_virt, KM_USER0); |
327 | goto out; | 388 | flush_dcache_page(page); |
328 | } | ||
329 | memset((page_virt + end_byte_in_page), 0, | ||
330 | (PAGE_CACHE_SIZE - end_byte_in_page)); | ||
331 | kunmap(page); | ||
332 | } | ||
333 | out: | 389 | out: |
334 | return rc; | 390 | return 0; |
335 | } | 391 | } |
336 | 392 | ||
337 | static int ecryptfs_prepare_write(struct file *file, struct page *page, | 393 | static int ecryptfs_prepare_write(struct file *file, struct page *page, |
@@ -339,7 +395,6 @@ static int ecryptfs_prepare_write(struct file *file, struct page *page, | |||
339 | { | 395 | { |
340 | int rc = 0; | 396 | int rc = 0; |
341 | 397 | ||
342 | kmap(page); | ||
343 | if (from == 0 && to == PAGE_CACHE_SIZE) | 398 | if (from == 0 && to == PAGE_CACHE_SIZE) |
344 | goto out; /* If we are writing a full page, it will be | 399 | goto out; /* If we are writing a full page, it will be |
345 | up to date. */ | 400 | up to date. */ |
@@ -349,30 +404,6 @@ out: | |||
349 | return rc; | 404 | return rc; |
350 | } | 405 | } |
351 | 406 | ||
352 | int ecryptfs_grab_and_map_lower_page(struct page **lower_page, | ||
353 | char **lower_virt, | ||
354 | struct inode *lower_inode, | ||
355 | unsigned long lower_page_index) | ||
356 | { | ||
357 | int rc = 0; | ||
358 | |||
359 | (*lower_page) = grab_cache_page(lower_inode->i_mapping, | ||
360 | lower_page_index); | ||
361 | if (!(*lower_page)) { | ||
362 | ecryptfs_printk(KERN_ERR, "grab_cache_page for " | ||
363 | "lower_page_index = [0x%.16x] failed\n", | ||
364 | lower_page_index); | ||
365 | rc = -EINVAL; | ||
366 | goto out; | ||
367 | } | ||
368 | if (lower_virt) | ||
369 | (*lower_virt) = kmap((*lower_page)); | ||
370 | else | ||
371 | kmap((*lower_page)); | ||
372 | out: | ||
373 | return rc; | ||
374 | } | ||
375 | |||
376 | int ecryptfs_writepage_and_release_lower_page(struct page *lower_page, | 407 | int ecryptfs_writepage_and_release_lower_page(struct page *lower_page, |
377 | struct inode *lower_inode, | 408 | struct inode *lower_inode, |
378 | struct writeback_control *wbc) | 409 | struct writeback_control *wbc) |
@@ -391,11 +422,8 @@ out: | |||
391 | return rc; | 422 | return rc; |
392 | } | 423 | } |
393 | 424 | ||
394 | static void ecryptfs_unmap_and_release_lower_page(struct page *lower_page) | 425 | static void ecryptfs_release_lower_page(struct page *lower_page) |
395 | { | 426 | { |
396 | kunmap(lower_page); | ||
397 | ecryptfs_printk(KERN_DEBUG, "Unlocking lower page with index = " | ||
398 | "[0x%.16x]\n", lower_page->index); | ||
399 | unlock_page(lower_page); | 427 | unlock_page(lower_page); |
400 | page_cache_release(lower_page); | 428 | page_cache_release(lower_page); |
401 | } | 429 | } |
@@ -407,10 +435,9 @@ static void ecryptfs_unmap_and_release_lower_page(struct page *lower_page) | |||
407 | * | 435 | * |
408 | * Returns zero on success; non-zero on error. | 436 | * Returns zero on success; non-zero on error. |
409 | */ | 437 | */ |
410 | int | 438 | static int ecryptfs_write_inode_size_to_header(struct file *lower_file, |
411 | ecryptfs_write_inode_size_to_header(struct file *lower_file, | 439 | struct inode *lower_inode, |
412 | struct inode *lower_inode, | 440 | struct inode *inode) |
413 | struct inode *inode) | ||
414 | { | 441 | { |
415 | int rc = 0; | 442 | int rc = 0; |
416 | struct page *header_page; | 443 | struct page *header_page; |
@@ -418,11 +445,11 @@ ecryptfs_write_inode_size_to_header(struct file *lower_file, | |||
418 | const struct address_space_operations *lower_a_ops; | 445 | const struct address_space_operations *lower_a_ops; |
419 | u64 file_size; | 446 | u64 file_size; |
420 | 447 | ||
421 | rc = ecryptfs_grab_and_map_lower_page(&header_page, &header_virt, | 448 | header_page = grab_cache_page(lower_inode->i_mapping, 0); |
422 | lower_inode, 0); | 449 | if (!header_page) { |
423 | if (rc) { | 450 | ecryptfs_printk(KERN_ERR, "grab_cache_page for " |
424 | ecryptfs_printk(KERN_ERR, "grab_cache_page for header page " | 451 | "lower_page_index 0 failed\n"); |
425 | "failed\n"); | 452 | rc = -EINVAL; |
426 | goto out; | 453 | goto out; |
427 | } | 454 | } |
428 | lower_a_ops = lower_inode->i_mapping->a_ops; | 455 | lower_a_ops = lower_inode->i_mapping->a_ops; |
@@ -430,18 +457,95 @@ ecryptfs_write_inode_size_to_header(struct file *lower_file, | |||
430 | file_size = (u64)i_size_read(inode); | 457 | file_size = (u64)i_size_read(inode); |
431 | ecryptfs_printk(KERN_DEBUG, "Writing size: [0x%.16x]\n", file_size); | 458 | ecryptfs_printk(KERN_DEBUG, "Writing size: [0x%.16x]\n", file_size); |
432 | file_size = cpu_to_be64(file_size); | 459 | file_size = cpu_to_be64(file_size); |
460 | header_virt = kmap_atomic(header_page, KM_USER0); | ||
433 | memcpy(header_virt, &file_size, sizeof(u64)); | 461 | memcpy(header_virt, &file_size, sizeof(u64)); |
462 | kunmap_atomic(header_virt, KM_USER0); | ||
463 | flush_dcache_page(header_page); | ||
434 | rc = lower_a_ops->commit_write(lower_file, header_page, 0, 8); | 464 | rc = lower_a_ops->commit_write(lower_file, header_page, 0, 8); |
435 | if (rc < 0) | 465 | if (rc < 0) |
436 | ecryptfs_printk(KERN_ERR, "Error commiting header page " | 466 | ecryptfs_printk(KERN_ERR, "Error commiting header page " |
437 | "write\n"); | 467 | "write\n"); |
438 | ecryptfs_unmap_and_release_lower_page(header_page); | 468 | ecryptfs_release_lower_page(header_page); |
439 | lower_inode->i_mtime = lower_inode->i_ctime = CURRENT_TIME; | 469 | lower_inode->i_mtime = lower_inode->i_ctime = CURRENT_TIME; |
440 | mark_inode_dirty_sync(inode); | 470 | mark_inode_dirty_sync(inode); |
441 | out: | 471 | out: |
442 | return rc; | 472 | return rc; |
443 | } | 473 | } |
444 | 474 | ||
475 | static int ecryptfs_write_inode_size_to_xattr(struct inode *lower_inode, | ||
476 | struct inode *inode, | ||
477 | struct dentry *ecryptfs_dentry, | ||
478 | int lower_i_mutex_held) | ||
479 | { | ||
480 | ssize_t size; | ||
481 | void *xattr_virt; | ||
482 | struct dentry *lower_dentry; | ||
483 | u64 file_size; | ||
484 | int rc; | ||
485 | |||
486 | xattr_virt = kmem_cache_alloc(ecryptfs_xattr_cache, GFP_KERNEL); | ||
487 | if (!xattr_virt) { | ||
488 | printk(KERN_ERR "Out of memory whilst attempting to write " | ||
489 | "inode size to xattr\n"); | ||
490 | rc = -ENOMEM; | ||
491 | goto out; | ||
492 | } | ||
493 | lower_dentry = ecryptfs_dentry_to_lower(ecryptfs_dentry); | ||
494 | if (!lower_dentry->d_inode->i_op->getxattr) { | ||
495 | printk(KERN_WARNING | ||
496 | "No support for setting xattr in lower filesystem\n"); | ||
497 | rc = -ENOSYS; | ||
498 | kmem_cache_free(ecryptfs_xattr_cache, xattr_virt); | ||
499 | goto out; | ||
500 | } | ||
501 | if (!lower_i_mutex_held) | ||
502 | mutex_lock(&lower_dentry->d_inode->i_mutex); | ||
503 | size = lower_dentry->d_inode->i_op->getxattr(lower_dentry, | ||
504 | ECRYPTFS_XATTR_NAME, | ||
505 | xattr_virt, | ||
506 | PAGE_CACHE_SIZE); | ||
507 | if (!lower_i_mutex_held) | ||
508 | mutex_unlock(&lower_dentry->d_inode->i_mutex); | ||
509 | if (size < 0) | ||
510 | size = 8; | ||
511 | file_size = (u64)i_size_read(inode); | ||
512 | file_size = cpu_to_be64(file_size); | ||
513 | memcpy(xattr_virt, &file_size, sizeof(u64)); | ||
514 | if (!lower_i_mutex_held) | ||
515 | mutex_lock(&lower_dentry->d_inode->i_mutex); | ||
516 | rc = lower_dentry->d_inode->i_op->setxattr(lower_dentry, | ||
517 | ECRYPTFS_XATTR_NAME, | ||
518 | xattr_virt, size, 0); | ||
519 | if (!lower_i_mutex_held) | ||
520 | mutex_unlock(&lower_dentry->d_inode->i_mutex); | ||
521 | if (rc) | ||
522 | printk(KERN_ERR "Error whilst attempting to write inode size " | ||
523 | "to lower file xattr; rc = [%d]\n", rc); | ||
524 | kmem_cache_free(ecryptfs_xattr_cache, xattr_virt); | ||
525 | out: | ||
526 | return rc; | ||
527 | } | ||
528 | |||
529 | int | ||
530 | ecryptfs_write_inode_size_to_metadata(struct file *lower_file, | ||
531 | struct inode *lower_inode, | ||
532 | struct inode *inode, | ||
533 | struct dentry *ecryptfs_dentry, | ||
534 | int lower_i_mutex_held) | ||
535 | { | ||
536 | struct ecryptfs_crypt_stat *crypt_stat; | ||
537 | |||
538 | crypt_stat = &ecryptfs_inode_to_private(inode)->crypt_stat; | ||
539 | if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR) | ||
540 | return ecryptfs_write_inode_size_to_xattr(lower_inode, inode, | ||
541 | ecryptfs_dentry, | ||
542 | lower_i_mutex_held); | ||
543 | else | ||
544 | return ecryptfs_write_inode_size_to_header(lower_file, | ||
545 | lower_inode, | ||
546 | inode); | ||
547 | } | ||
548 | |||
445 | int ecryptfs_get_lower_page(struct page **lower_page, struct inode *lower_inode, | 549 | int ecryptfs_get_lower_page(struct page **lower_page, struct inode *lower_inode, |
446 | struct file *lower_file, | 550 | struct file *lower_file, |
447 | unsigned long lower_page_index, int byte_offset, | 551 | unsigned long lower_page_index, int byte_offset, |
@@ -449,10 +553,10 @@ int ecryptfs_get_lower_page(struct page **lower_page, struct inode *lower_inode, | |||
449 | { | 553 | { |
450 | int rc = 0; | 554 | int rc = 0; |
451 | 555 | ||
452 | rc = ecryptfs_grab_and_map_lower_page(lower_page, NULL, lower_inode, | 556 | *lower_page = grab_cache_page(lower_inode->i_mapping, lower_page_index); |
453 | lower_page_index); | 557 | if (!(*lower_page)) { |
454 | if (rc) { | 558 | rc = -EINVAL; |
455 | ecryptfs_printk(KERN_ERR, "Error attempting to grab and map " | 559 | ecryptfs_printk(KERN_ERR, "Error attempting to grab " |
456 | "lower page with index [0x%.16x]\n", | 560 | "lower page with index [0x%.16x]\n", |
457 | lower_page_index); | 561 | lower_page_index); |
458 | goto out; | 562 | goto out; |
@@ -468,7 +572,7 @@ int ecryptfs_get_lower_page(struct page **lower_page, struct inode *lower_inode, | |||
468 | } | 572 | } |
469 | out: | 573 | out: |
470 | if (rc && (*lower_page)) { | 574 | if (rc && (*lower_page)) { |
471 | ecryptfs_unmap_and_release_lower_page(*lower_page); | 575 | ecryptfs_release_lower_page(*lower_page); |
472 | (*lower_page) = NULL; | 576 | (*lower_page) = NULL; |
473 | } | 577 | } |
474 | return rc; | 578 | return rc; |
@@ -493,7 +597,7 @@ ecryptfs_commit_lower_page(struct page *lower_page, struct inode *lower_inode, | |||
493 | "Error committing write; rc = [%d]\n", rc); | 597 | "Error committing write; rc = [%d]\n", rc); |
494 | } else | 598 | } else |
495 | rc = 0; | 599 | rc = 0; |
496 | ecryptfs_unmap_and_release_lower_page(lower_page); | 600 | ecryptfs_release_lower_page(lower_page); |
497 | return rc; | 601 | return rc; |
498 | } | 602 | } |
499 | 603 | ||
@@ -528,89 +632,7 @@ out: | |||
528 | return rc; | 632 | return rc; |
529 | } | 633 | } |
530 | 634 | ||
531 | static int | 635 | struct kmem_cache *ecryptfs_xattr_cache; |
532 | process_new_file(struct ecryptfs_crypt_stat *crypt_stat, | ||
533 | struct file *file, struct inode *inode) | ||
534 | { | ||
535 | struct page *header_page; | ||
536 | const struct address_space_operations *lower_a_ops; | ||
537 | struct inode *lower_inode; | ||
538 | struct file *lower_file; | ||
539 | char *header_virt; | ||
540 | int rc = 0; | ||
541 | int current_header_page = 0; | ||
542 | int header_pages; | ||
543 | int more_header_data_to_be_written = 1; | ||
544 | |||
545 | lower_inode = ecryptfs_inode_to_lower(inode); | ||
546 | lower_file = ecryptfs_file_to_lower(file); | ||
547 | lower_a_ops = lower_inode->i_mapping->a_ops; | ||
548 | header_pages = ((crypt_stat->header_extent_size | ||
549 | * crypt_stat->num_header_extents_at_front) | ||
550 | / PAGE_CACHE_SIZE); | ||
551 | BUG_ON(header_pages < 1); | ||
552 | while (current_header_page < header_pages) { | ||
553 | rc = ecryptfs_grab_and_map_lower_page(&header_page, | ||
554 | &header_virt, | ||
555 | lower_inode, | ||
556 | current_header_page); | ||
557 | if (rc) { | ||
558 | ecryptfs_printk(KERN_ERR, "grab_cache_page for " | ||
559 | "header page [%d] failed; rc = [%d]\n", | ||
560 | current_header_page, rc); | ||
561 | goto out; | ||
562 | } | ||
563 | rc = lower_a_ops->prepare_write(lower_file, header_page, 0, | ||
564 | PAGE_CACHE_SIZE); | ||
565 | if (rc) { | ||
566 | ecryptfs_printk(KERN_ERR, "Error preparing to write " | ||
567 | "header page out; rc = [%d]\n", rc); | ||
568 | goto out; | ||
569 | } | ||
570 | memset(header_virt, 0, PAGE_CACHE_SIZE); | ||
571 | if (more_header_data_to_be_written) { | ||
572 | rc = ecryptfs_write_headers_virt(header_virt, | ||
573 | crypt_stat, | ||
574 | file->f_dentry); | ||
575 | if (rc) { | ||
576 | ecryptfs_printk(KERN_WARNING, "Error " | ||
577 | "generating header; rc = " | ||
578 | "[%d]\n", rc); | ||
579 | rc = -EIO; | ||
580 | memset(header_virt, 0, PAGE_CACHE_SIZE); | ||
581 | ecryptfs_unmap_and_release_lower_page( | ||
582 | header_page); | ||
583 | goto out; | ||
584 | } | ||
585 | if (current_header_page == 0) | ||
586 | memset(header_virt, 0, 8); | ||
587 | more_header_data_to_be_written = 0; | ||
588 | } | ||
589 | rc = lower_a_ops->commit_write(lower_file, header_page, 0, | ||
590 | PAGE_CACHE_SIZE); | ||
591 | ecryptfs_unmap_and_release_lower_page(header_page); | ||
592 | if (rc < 0) { | ||
593 | ecryptfs_printk(KERN_ERR, | ||
594 | "Error commiting header page write; " | ||
595 | "rc = [%d]\n", rc); | ||
596 | break; | ||
597 | } | ||
598 | current_header_page++; | ||
599 | } | ||
600 | if (rc >= 0) { | ||
601 | rc = 0; | ||
602 | ecryptfs_printk(KERN_DEBUG, "lower_inode->i_blocks = " | ||
603 | "[0x%.16x]\n", lower_inode->i_blocks); | ||
604 | i_size_write(inode, 0); | ||
605 | lower_inode->i_mtime = lower_inode->i_ctime = CURRENT_TIME; | ||
606 | mark_inode_dirty_sync(inode); | ||
607 | } | ||
608 | ecryptfs_printk(KERN_DEBUG, "Clearing ECRYPTFS_NEW_FILE flag in " | ||
609 | "crypt_stat at memory location [%p]\n", crypt_stat); | ||
610 | ECRYPTFS_CLEAR_FLAG(crypt_stat->flags, ECRYPTFS_NEW_FILE); | ||
611 | out: | ||
612 | return rc; | ||
613 | } | ||
614 | 636 | ||
615 | /** | 637 | /** |
616 | * ecryptfs_commit_write | 638 | * ecryptfs_commit_write |
@@ -640,15 +662,10 @@ static int ecryptfs_commit_write(struct file *file, struct page *page, | |||
640 | mutex_lock(&lower_inode->i_mutex); | 662 | mutex_lock(&lower_inode->i_mutex); |
641 | crypt_stat = &ecryptfs_inode_to_private(file->f_path.dentry->d_inode) | 663 | crypt_stat = &ecryptfs_inode_to_private(file->f_path.dentry->d_inode) |
642 | ->crypt_stat; | 664 | ->crypt_stat; |
643 | if (ECRYPTFS_CHECK_FLAG(crypt_stat->flags, ECRYPTFS_NEW_FILE)) { | 665 | if (crypt_stat->flags & ECRYPTFS_NEW_FILE) { |
644 | ecryptfs_printk(KERN_DEBUG, "ECRYPTFS_NEW_FILE flag set in " | 666 | ecryptfs_printk(KERN_DEBUG, "ECRYPTFS_NEW_FILE flag set in " |
645 | "crypt_stat at memory location [%p]\n", crypt_stat); | 667 | "crypt_stat at memory location [%p]\n", crypt_stat); |
646 | rc = process_new_file(crypt_stat, file, inode); | 668 | crypt_stat->flags &= ~(ECRYPTFS_NEW_FILE); |
647 | if (rc) { | ||
648 | ecryptfs_printk(KERN_ERR, "Error processing new " | ||
649 | "file; rc = [%d]\n", rc); | ||
650 | goto out; | ||
651 | } | ||
652 | } else | 669 | } else |
653 | ecryptfs_printk(KERN_DEBUG, "Not a new file\n"); | 670 | ecryptfs_printk(KERN_DEBUG, "Not a new file\n"); |
654 | ecryptfs_printk(KERN_DEBUG, "Calling fill_zeros_to_end_of_page" | 671 | ecryptfs_printk(KERN_DEBUG, "Calling fill_zeros_to_end_of_page" |
@@ -670,7 +687,6 @@ static int ecryptfs_commit_write(struct file *file, struct page *page, | |||
670 | "index [0x%.16x])\n", page->index); | 687 | "index [0x%.16x])\n", page->index); |
671 | goto out; | 688 | goto out; |
672 | } | 689 | } |
673 | rc = 0; | ||
674 | inode->i_blocks = lower_inode->i_blocks; | 690 | inode->i_blocks = lower_inode->i_blocks; |
675 | pos = (page->index << PAGE_CACHE_SHIFT) + to; | 691 | pos = (page->index << PAGE_CACHE_SHIFT) + to; |
676 | if (pos > i_size_read(inode)) { | 692 | if (pos > i_size_read(inode)) { |
@@ -678,11 +694,15 @@ static int ecryptfs_commit_write(struct file *file, struct page *page, | |||
678 | ecryptfs_printk(KERN_DEBUG, "Expanded file size to " | 694 | ecryptfs_printk(KERN_DEBUG, "Expanded file size to " |
679 | "[0x%.16x]\n", i_size_read(inode)); | 695 | "[0x%.16x]\n", i_size_read(inode)); |
680 | } | 696 | } |
681 | ecryptfs_write_inode_size_to_header(lower_file, lower_inode, inode); | 697 | rc = ecryptfs_write_inode_size_to_metadata(lower_file, lower_inode, |
698 | inode, file->f_dentry, | ||
699 | ECRYPTFS_LOWER_I_MUTEX_HELD); | ||
700 | if (rc) | ||
701 | printk(KERN_ERR "Error writing inode size to metadata; " | ||
702 | "rc = [%d]\n", rc); | ||
682 | lower_inode->i_mtime = lower_inode->i_ctime = CURRENT_TIME; | 703 | lower_inode->i_mtime = lower_inode->i_ctime = CURRENT_TIME; |
683 | mark_inode_dirty_sync(inode); | 704 | mark_inode_dirty_sync(inode); |
684 | out: | 705 | out: |
685 | kunmap(page); /* mapped in prior call (prepare_write) */ | ||
686 | if (rc < 0) | 706 | if (rc < 0) |
687 | ClearPageUptodate(page); | 707 | ClearPageUptodate(page); |
688 | else | 708 | else |
@@ -707,6 +727,7 @@ int write_zeros(struct file *file, pgoff_t index, int start, int num_zeros) | |||
707 | { | 727 | { |
708 | int rc = 0; | 728 | int rc = 0; |
709 | struct page *tmp_page; | 729 | struct page *tmp_page; |
730 | char *tmp_page_virt; | ||
710 | 731 | ||
711 | tmp_page = ecryptfs_get1page(file, index); | 732 | tmp_page = ecryptfs_get1page(file, index); |
712 | if (IS_ERR(tmp_page)) { | 733 | if (IS_ERR(tmp_page)) { |
@@ -715,28 +736,27 @@ int write_zeros(struct file *file, pgoff_t index, int start, int num_zeros) | |||
715 | rc = PTR_ERR(tmp_page); | 736 | rc = PTR_ERR(tmp_page); |
716 | goto out; | 737 | goto out; |
717 | } | 738 | } |
718 | kmap(tmp_page); | ||
719 | rc = ecryptfs_prepare_write(file, tmp_page, start, start + num_zeros); | 739 | rc = ecryptfs_prepare_write(file, tmp_page, start, start + num_zeros); |
720 | if (rc) { | 740 | if (rc) { |
721 | ecryptfs_printk(KERN_ERR, "Error preparing to write zero's " | 741 | ecryptfs_printk(KERN_ERR, "Error preparing to write zero's " |
722 | "to remainder of page at index [0x%.16x]\n", | 742 | "to remainder of page at index [0x%.16x]\n", |
723 | index); | 743 | index); |
724 | kunmap(tmp_page); | ||
725 | page_cache_release(tmp_page); | 744 | page_cache_release(tmp_page); |
726 | goto out; | 745 | goto out; |
727 | } | 746 | } |
728 | memset(((char *)page_address(tmp_page) + start), 0, num_zeros); | 747 | tmp_page_virt = kmap_atomic(tmp_page, KM_USER0); |
748 | memset(((char *)tmp_page_virt + start), 0, num_zeros); | ||
749 | kunmap_atomic(tmp_page_virt, KM_USER0); | ||
750 | flush_dcache_page(tmp_page); | ||
729 | rc = ecryptfs_commit_write(file, tmp_page, start, start + num_zeros); | 751 | rc = ecryptfs_commit_write(file, tmp_page, start, start + num_zeros); |
730 | if (rc < 0) { | 752 | if (rc < 0) { |
731 | ecryptfs_printk(KERN_ERR, "Error attempting to write zero's " | 753 | ecryptfs_printk(KERN_ERR, "Error attempting to write zero's " |
732 | "to remainder of page at index [0x%.16x]\n", | 754 | "to remainder of page at index [0x%.16x]\n", |
733 | index); | 755 | index); |
734 | kunmap(tmp_page); | ||
735 | page_cache_release(tmp_page); | 756 | page_cache_release(tmp_page); |
736 | goto out; | 757 | goto out; |
737 | } | 758 | } |
738 | rc = 0; | 759 | rc = 0; |
739 | kunmap(tmp_page); | ||
740 | page_cache_release(tmp_page); | 760 | page_cache_release(tmp_page); |
741 | out: | 761 | out: |
742 | return rc; | 762 | return rc; |
diff --git a/fs/ecryptfs/netlink.c b/fs/ecryptfs/netlink.c new file mode 100644 index 000000000000..e3aa2253c850 --- /dev/null +++ b/fs/ecryptfs/netlink.c | |||
@@ -0,0 +1,255 @@ | |||
1 | /** | ||
2 | * eCryptfs: Linux filesystem encryption layer | ||
3 | * | ||
4 | * Copyright (C) 2004-2006 International Business Machines Corp. | ||
5 | * Author(s): Michael A. Halcrow <mhalcrow@us.ibm.com> | ||
6 | * Tyler Hicks <tyhicks@ou.edu> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or | ||
9 | * modify it under the terms of the GNU General Public License version | ||
10 | * 2 as published by the Free Software Foundation. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, but | ||
13 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
15 | * General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA | ||
20 | * 02111-1307, USA. | ||
21 | */ | ||
22 | |||
23 | #include <net/sock.h> | ||
24 | #include <linux/hash.h> | ||
25 | #include <linux/random.h> | ||
26 | #include "ecryptfs_kernel.h" | ||
27 | |||
28 | static struct sock *ecryptfs_nl_sock; | ||
29 | |||
30 | /** | ||
31 | * ecryptfs_send_netlink | ||
32 | * @data: The data to include as the payload | ||
33 | * @data_len: The byte count of the data | ||
34 | * @msg_ctx: The netlink context that will be used to handle the | ||
35 | * response message | ||
36 | * @msg_type: The type of netlink message to send | ||
37 | * @msg_flags: The flags to include in the netlink header | ||
38 | * @daemon_pid: The process id of the daemon to send the message to | ||
39 | * | ||
40 | * Sends the data to the specified daemon pid and uses the netlink | ||
41 | * context element to store the data needed for validation upon | ||
42 | * receiving the response. The data and the netlink context can be | ||
43 | * null if just sending a netlink header is sufficient. Returns zero | ||
44 | * upon sending the message; non-zero upon error. | ||
45 | */ | ||
46 | int ecryptfs_send_netlink(char *data, int data_len, | ||
47 | struct ecryptfs_msg_ctx *msg_ctx, u16 msg_type, | ||
48 | u16 msg_flags, pid_t daemon_pid) | ||
49 | { | ||
50 | struct sk_buff *skb; | ||
51 | struct nlmsghdr *nlh; | ||
52 | struct ecryptfs_message *msg; | ||
53 | size_t payload_len; | ||
54 | int rc; | ||
55 | |||
56 | payload_len = ((data && data_len) ? (sizeof(*msg) + data_len) : 0); | ||
57 | skb = alloc_skb(NLMSG_SPACE(payload_len), GFP_KERNEL); | ||
58 | if (!skb) { | ||
59 | rc = -ENOMEM; | ||
60 | ecryptfs_printk(KERN_ERR, "Failed to allocate socket buffer\n"); | ||
61 | goto out; | ||
62 | } | ||
63 | nlh = NLMSG_PUT(skb, daemon_pid, msg_ctx ? msg_ctx->counter : 0, | ||
64 | msg_type, payload_len); | ||
65 | nlh->nlmsg_flags = msg_flags; | ||
66 | if (msg_ctx && payload_len) { | ||
67 | msg = (struct ecryptfs_message *)NLMSG_DATA(nlh); | ||
68 | msg->index = msg_ctx->index; | ||
69 | msg->data_len = data_len; | ||
70 | memcpy(msg->data, data, data_len); | ||
71 | } | ||
72 | rc = netlink_unicast(ecryptfs_nl_sock, skb, daemon_pid, 0); | ||
73 | if (rc < 0) { | ||
74 | ecryptfs_printk(KERN_ERR, "Failed to send eCryptfs netlink " | ||
75 | "message; rc = [%d]\n", rc); | ||
76 | goto out; | ||
77 | } | ||
78 | rc = 0; | ||
79 | goto out; | ||
80 | nlmsg_failure: | ||
81 | rc = -EMSGSIZE; | ||
82 | kfree_skb(skb); | ||
83 | out: | ||
84 | return rc; | ||
85 | } | ||
86 | |||
87 | /** | ||
88 | * ecryptfs_process_nl_reponse | ||
89 | * @skb: The socket buffer containing the netlink message of state | ||
90 | * RESPONSE | ||
91 | * | ||
92 | * Processes a response message after sending a operation request to | ||
93 | * userspace. Attempts to assign the msg to a netlink context element | ||
94 | * at the index specified in the msg. The sk_buff and nlmsghdr must | ||
95 | * be validated before this function. Returns zero upon delivery to | ||
96 | * desired context element; non-zero upon delivery failure or error. | ||
97 | */ | ||
98 | static int ecryptfs_process_nl_response(struct sk_buff *skb) | ||
99 | { | ||
100 | struct nlmsghdr *nlh = (struct nlmsghdr*)skb->data; | ||
101 | struct ecryptfs_message *msg = NLMSG_DATA(nlh); | ||
102 | int rc; | ||
103 | |||
104 | if (skb->len - NLMSG_HDRLEN - sizeof(*msg) != msg->data_len) { | ||
105 | rc = -EINVAL; | ||
106 | ecryptfs_printk(KERN_ERR, "Received netlink message with " | ||
107 | "incorrectly specified data length\n"); | ||
108 | goto out; | ||
109 | } | ||
110 | rc = ecryptfs_process_response(msg, NETLINK_CREDS(skb)->uid, | ||
111 | NETLINK_CREDS(skb)->pid, nlh->nlmsg_seq); | ||
112 | if (rc) | ||
113 | printk(KERN_ERR | ||
114 | "Error processing response message; rc = [%d]\n", rc); | ||
115 | out: | ||
116 | return rc; | ||
117 | } | ||
118 | |||
119 | /** | ||
120 | * ecryptfs_process_nl_helo | ||
121 | * @skb: The socket buffer containing the nlmsghdr in HELO state | ||
122 | * | ||
123 | * Gets uid and pid of the skb and adds the values to the daemon id | ||
124 | * hash. Returns zero after adding a new daemon id to the hash list; | ||
125 | * non-zero otherwise. | ||
126 | */ | ||
127 | static int ecryptfs_process_nl_helo(struct sk_buff *skb) | ||
128 | { | ||
129 | int rc; | ||
130 | |||
131 | rc = ecryptfs_process_helo(ECRYPTFS_TRANSPORT_NETLINK, | ||
132 | NETLINK_CREDS(skb)->uid, | ||
133 | NETLINK_CREDS(skb)->pid); | ||
134 | if (rc) | ||
135 | printk(KERN_WARNING "Error processing HELO; rc = [%d]\n", rc); | ||
136 | return rc; | ||
137 | } | ||
138 | |||
139 | /** | ||
140 | * ecryptfs_process_nl_quit | ||
141 | * @skb: The socket buffer containing the nlmsghdr in QUIT state | ||
142 | * | ||
143 | * Gets uid and pid of the skb and deletes the corresponding daemon | ||
144 | * id, if it is the registered that is requesting the | ||
145 | * deletion. Returns zero after deleting the desired daemon id; | ||
146 | * non-zero otherwise. | ||
147 | */ | ||
148 | static int ecryptfs_process_nl_quit(struct sk_buff *skb) | ||
149 | { | ||
150 | int rc; | ||
151 | |||
152 | rc = ecryptfs_process_quit(NETLINK_CREDS(skb)->uid, | ||
153 | NETLINK_CREDS(skb)->pid); | ||
154 | if (rc) | ||
155 | printk(KERN_WARNING | ||
156 | "Error processing QUIT message; rc = [%d]\n", rc); | ||
157 | return rc; | ||
158 | } | ||
159 | |||
160 | /** | ||
161 | * ecryptfs_receive_nl_message | ||
162 | * | ||
163 | * Callback function called by netlink system when a message arrives. | ||
164 | * If the message looks to be valid, then an attempt is made to assign | ||
165 | * it to its desired netlink context element and wake up the process | ||
166 | * that is waiting for a response. | ||
167 | */ | ||
168 | static void ecryptfs_receive_nl_message(struct sock *sk, int len) | ||
169 | { | ||
170 | struct sk_buff *skb; | ||
171 | struct nlmsghdr *nlh; | ||
172 | int rc = 0; /* skb_recv_datagram requires this */ | ||
173 | |||
174 | receive: | ||
175 | skb = skb_recv_datagram(sk, 0, 0, &rc); | ||
176 | if (rc == -EINTR) | ||
177 | goto receive; | ||
178 | else if (rc < 0) { | ||
179 | ecryptfs_printk(KERN_ERR, "Error occurred while " | ||
180 | "receiving eCryptfs netlink message; " | ||
181 | "rc = [%d]\n", rc); | ||
182 | return; | ||
183 | } | ||
184 | nlh = (struct nlmsghdr *)skb->data; | ||
185 | if (!NLMSG_OK(nlh, skb->len)) { | ||
186 | ecryptfs_printk(KERN_ERR, "Received corrupt netlink " | ||
187 | "message\n"); | ||
188 | goto free; | ||
189 | } | ||
190 | switch (nlh->nlmsg_type) { | ||
191 | case ECRYPTFS_NLMSG_RESPONSE: | ||
192 | if (ecryptfs_process_nl_response(skb)) { | ||
193 | ecryptfs_printk(KERN_WARNING, "Failed to " | ||
194 | "deliver netlink response to " | ||
195 | "requesting operation\n"); | ||
196 | } | ||
197 | break; | ||
198 | case ECRYPTFS_NLMSG_HELO: | ||
199 | if (ecryptfs_process_nl_helo(skb)) { | ||
200 | ecryptfs_printk(KERN_WARNING, "Failed to " | ||
201 | "fulfill HELO request\n"); | ||
202 | } | ||
203 | break; | ||
204 | case ECRYPTFS_NLMSG_QUIT: | ||
205 | if (ecryptfs_process_nl_quit(skb)) { | ||
206 | ecryptfs_printk(KERN_WARNING, "Failed to " | ||
207 | "fulfill QUIT request\n"); | ||
208 | } | ||
209 | break; | ||
210 | default: | ||
211 | ecryptfs_printk(KERN_WARNING, "Dropping netlink " | ||
212 | "message of unrecognized type [%d]\n", | ||
213 | nlh->nlmsg_type); | ||
214 | break; | ||
215 | } | ||
216 | free: | ||
217 | kfree_skb(skb); | ||
218 | } | ||
219 | |||
220 | /** | ||
221 | * ecryptfs_init_netlink | ||
222 | * | ||
223 | * Initializes the daemon id hash list, netlink context array, and | ||
224 | * necessary locks. Returns zero upon success; non-zero upon error. | ||
225 | */ | ||
226 | int ecryptfs_init_netlink(void) | ||
227 | { | ||
228 | int rc; | ||
229 | |||
230 | ecryptfs_nl_sock = netlink_kernel_create(NETLINK_ECRYPTFS, 0, | ||
231 | ecryptfs_receive_nl_message, | ||
232 | THIS_MODULE); | ||
233 | if (!ecryptfs_nl_sock) { | ||
234 | rc = -EIO; | ||
235 | ecryptfs_printk(KERN_ERR, "Failed to create netlink socket\n"); | ||
236 | goto out; | ||
237 | } | ||
238 | ecryptfs_nl_sock->sk_sndtimeo = ECRYPTFS_DEFAULT_SEND_TIMEOUT; | ||
239 | rc = 0; | ||
240 | out: | ||
241 | return rc; | ||
242 | } | ||
243 | |||
244 | /** | ||
245 | * ecryptfs_release_netlink | ||
246 | * | ||
247 | * Frees all memory used by the netlink context array and releases the | ||
248 | * netlink socket. | ||
249 | */ | ||
250 | void ecryptfs_release_netlink(void) | ||
251 | { | ||
252 | if (ecryptfs_nl_sock && ecryptfs_nl_sock->sk_socket) | ||
253 | sock_release(ecryptfs_nl_sock->sk_socket); | ||
254 | ecryptfs_nl_sock = NULL; | ||
255 | } | ||
diff --git a/fs/ecryptfs/super.c b/fs/ecryptfs/super.c index eaa5daaf106e..7b3f0cc09a6f 100644 --- a/fs/ecryptfs/super.c +++ b/fs/ecryptfs/super.c | |||
@@ -168,7 +168,7 @@ out: | |||
168 | return rc; | 168 | return rc; |
169 | } | 169 | } |
170 | 170 | ||
171 | struct super_operations ecryptfs_sops = { | 171 | const struct super_operations ecryptfs_sops = { |
172 | .alloc_inode = ecryptfs_alloc_inode, | 172 | .alloc_inode = ecryptfs_alloc_inode, |
173 | .destroy_inode = ecryptfs_destroy_inode, | 173 | .destroy_inode = ecryptfs_destroy_inode, |
174 | .drop_inode = generic_delete_inode, | 174 | .drop_inode = generic_delete_inode, |