diff options
author | Ingo Molnar <mingo@elte.hu> | 2008-07-26 11:48:49 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-07-26 11:48:49 -0400 |
commit | c3cc99ff5d24e2eeaf7ec2032e720681916990e3 (patch) | |
tree | c3e74171bbbd2adde9d60b9db1c440415c8d2831 /fs/ecryptfs | |
parent | 38ffbe66d59051fd9cfcfc8545f164700e2fa3bc (diff) | |
parent | 024e8ac04453b3525448c31ef39848cf675ba6db (diff) |
Merge branch 'linus' into x86/xen
Diffstat (limited to 'fs/ecryptfs')
-rw-r--r-- | fs/ecryptfs/Makefile | 2 | ||||
-rw-r--r-- | fs/ecryptfs/crypto.c | 37 | ||||
-rw-r--r-- | fs/ecryptfs/ecryptfs_kernel.h | 23 | ||||
-rw-r--r-- | fs/ecryptfs/file.c | 17 | ||||
-rw-r--r-- | fs/ecryptfs/inode.c | 31 | ||||
-rw-r--r-- | fs/ecryptfs/keystore.c | 9 | ||||
-rw-r--r-- | fs/ecryptfs/kthread.c | 203 | ||||
-rw-r--r-- | fs/ecryptfs/main.c | 79 | ||||
-rw-r--r-- | fs/ecryptfs/miscdev.c | 59 | ||||
-rw-r--r-- | fs/ecryptfs/mmap.c | 11 |
10 files changed, 323 insertions, 148 deletions
diff --git a/fs/ecryptfs/Makefile b/fs/ecryptfs/Makefile index 1e34a7fd4884..b4755a85996e 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 read_write.o crypto.o keystore.o messaging.o netlink.o miscdev.o debug.o | 7 | ecryptfs-objs := dentry.o file.o inode.o main.o super.o mmap.o read_write.o crypto.o keystore.o messaging.o netlink.o miscdev.o kthread.o debug.o |
diff --git a/fs/ecryptfs/crypto.c b/fs/ecryptfs/crypto.c index e2832bc7869a..7b99917ffadc 100644 --- a/fs/ecryptfs/crypto.c +++ b/fs/ecryptfs/crypto.c | |||
@@ -33,6 +33,7 @@ | |||
33 | #include <linux/crypto.h> | 33 | #include <linux/crypto.h> |
34 | #include <linux/file.h> | 34 | #include <linux/file.h> |
35 | #include <linux/scatterlist.h> | 35 | #include <linux/scatterlist.h> |
36 | #include <asm/unaligned.h> | ||
36 | #include "ecryptfs_kernel.h" | 37 | #include "ecryptfs_kernel.h" |
37 | 38 | ||
38 | static int | 39 | static int |
@@ -1032,10 +1033,8 @@ static int contains_ecryptfs_marker(char *data) | |||
1032 | { | 1033 | { |
1033 | u32 m_1, m_2; | 1034 | u32 m_1, m_2; |
1034 | 1035 | ||
1035 | memcpy(&m_1, data, 4); | 1036 | m_1 = get_unaligned_be32(data); |
1036 | m_1 = be32_to_cpu(m_1); | 1037 | m_2 = get_unaligned_be32(data + 4); |
1037 | memcpy(&m_2, (data + 4), 4); | ||
1038 | m_2 = be32_to_cpu(m_2); | ||
1039 | if ((m_1 ^ MAGIC_ECRYPTFS_MARKER) == m_2) | 1038 | if ((m_1 ^ MAGIC_ECRYPTFS_MARKER) == m_2) |
1040 | return 1; | 1039 | return 1; |
1041 | ecryptfs_printk(KERN_DEBUG, "m_1 = [0x%.8x]; m_2 = [0x%.8x]; " | 1040 | ecryptfs_printk(KERN_DEBUG, "m_1 = [0x%.8x]; m_2 = [0x%.8x]; " |
@@ -1073,8 +1072,7 @@ static int ecryptfs_process_flags(struct ecryptfs_crypt_stat *crypt_stat, | |||
1073 | int i; | 1072 | int i; |
1074 | u32 flags; | 1073 | u32 flags; |
1075 | 1074 | ||
1076 | memcpy(&flags, page_virt, 4); | 1075 | flags = get_unaligned_be32(page_virt); |
1077 | flags = be32_to_cpu(flags); | ||
1078 | for (i = 0; i < ((sizeof(ecryptfs_flag_map) | 1076 | for (i = 0; i < ((sizeof(ecryptfs_flag_map) |
1079 | / sizeof(struct ecryptfs_flag_map_elem))); i++) | 1077 | / sizeof(struct ecryptfs_flag_map_elem))); i++) |
1080 | if (flags & ecryptfs_flag_map[i].file_flag) { | 1078 | if (flags & ecryptfs_flag_map[i].file_flag) { |
@@ -1100,11 +1098,9 @@ static void write_ecryptfs_marker(char *page_virt, size_t *written) | |||
1100 | 1098 | ||
1101 | get_random_bytes(&m_1, (MAGIC_ECRYPTFS_MARKER_SIZE_BYTES / 2)); | 1099 | get_random_bytes(&m_1, (MAGIC_ECRYPTFS_MARKER_SIZE_BYTES / 2)); |
1102 | m_2 = (m_1 ^ MAGIC_ECRYPTFS_MARKER); | 1100 | m_2 = (m_1 ^ MAGIC_ECRYPTFS_MARKER); |
1103 | m_1 = cpu_to_be32(m_1); | 1101 | put_unaligned_be32(m_1, page_virt); |
1104 | memcpy(page_virt, &m_1, (MAGIC_ECRYPTFS_MARKER_SIZE_BYTES / 2)); | 1102 | page_virt += (MAGIC_ECRYPTFS_MARKER_SIZE_BYTES / 2); |
1105 | m_2 = cpu_to_be32(m_2); | 1103 | put_unaligned_be32(m_2, page_virt); |
1106 | memcpy(page_virt + (MAGIC_ECRYPTFS_MARKER_SIZE_BYTES / 2), &m_2, | ||
1107 | (MAGIC_ECRYPTFS_MARKER_SIZE_BYTES / 2)); | ||
1108 | (*written) = MAGIC_ECRYPTFS_MARKER_SIZE_BYTES; | 1104 | (*written) = MAGIC_ECRYPTFS_MARKER_SIZE_BYTES; |
1109 | } | 1105 | } |
1110 | 1106 | ||
@@ -1121,8 +1117,7 @@ write_ecryptfs_flags(char *page_virt, struct ecryptfs_crypt_stat *crypt_stat, | |||
1121 | flags |= ecryptfs_flag_map[i].file_flag; | 1117 | flags |= ecryptfs_flag_map[i].file_flag; |
1122 | /* Version is in top 8 bits of the 32-bit flag vector */ | 1118 | /* Version is in top 8 bits of the 32-bit flag vector */ |
1123 | flags |= ((((u8)crypt_stat->file_version) << 24) & 0xFF000000); | 1119 | flags |= ((((u8)crypt_stat->file_version) << 24) & 0xFF000000); |
1124 | flags = cpu_to_be32(flags); | 1120 | put_unaligned_be32(flags, page_virt); |
1125 | memcpy(page_virt, &flags, 4); | ||
1126 | (*written) = 4; | 1121 | (*written) = 4; |
1127 | } | 1122 | } |
1128 | 1123 | ||
@@ -1238,11 +1233,9 @@ ecryptfs_write_header_metadata(char *virt, | |||
1238 | num_header_extents_at_front = | 1233 | num_header_extents_at_front = |
1239 | (u16)(crypt_stat->num_header_bytes_at_front | 1234 | (u16)(crypt_stat->num_header_bytes_at_front |
1240 | / crypt_stat->extent_size); | 1235 | / crypt_stat->extent_size); |
1241 | header_extent_size = cpu_to_be32(header_extent_size); | 1236 | put_unaligned_be32(header_extent_size, virt); |
1242 | memcpy(virt, &header_extent_size, 4); | ||
1243 | virt += 4; | 1237 | virt += 4; |
1244 | num_header_extents_at_front = cpu_to_be16(num_header_extents_at_front); | 1238 | put_unaligned_be16(num_header_extents_at_front, virt); |
1245 | memcpy(virt, &num_header_extents_at_front, 2); | ||
1246 | (*written) = 6; | 1239 | (*written) = 6; |
1247 | } | 1240 | } |
1248 | 1241 | ||
@@ -1410,15 +1403,13 @@ static int parse_header_metadata(struct ecryptfs_crypt_stat *crypt_stat, | |||
1410 | u32 header_extent_size; | 1403 | u32 header_extent_size; |
1411 | u16 num_header_extents_at_front; | 1404 | u16 num_header_extents_at_front; |
1412 | 1405 | ||
1413 | memcpy(&header_extent_size, virt, sizeof(u32)); | 1406 | header_extent_size = get_unaligned_be32(virt); |
1414 | header_extent_size = be32_to_cpu(header_extent_size); | 1407 | virt += sizeof(__be32); |
1415 | virt += sizeof(u32); | 1408 | num_header_extents_at_front = get_unaligned_be16(virt); |
1416 | memcpy(&num_header_extents_at_front, virt, sizeof(u16)); | ||
1417 | num_header_extents_at_front = be16_to_cpu(num_header_extents_at_front); | ||
1418 | crypt_stat->num_header_bytes_at_front = | 1409 | crypt_stat->num_header_bytes_at_front = |
1419 | (((size_t)num_header_extents_at_front | 1410 | (((size_t)num_header_extents_at_front |
1420 | * (size_t)header_extent_size)); | 1411 | * (size_t)header_extent_size)); |
1421 | (*bytes_read) = (sizeof(u32) + sizeof(u16)); | 1412 | (*bytes_read) = (sizeof(__be32) + sizeof(__be16)); |
1422 | if ((validate_header_size == ECRYPTFS_VALIDATE_HEADER_SIZE) | 1413 | if ((validate_header_size == ECRYPTFS_VALIDATE_HEADER_SIZE) |
1423 | && (crypt_stat->num_header_bytes_at_front | 1414 | && (crypt_stat->num_header_bytes_at_front |
1424 | < ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE)) { | 1415 | < ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE)) { |
diff --git a/fs/ecryptfs/ecryptfs_kernel.h b/fs/ecryptfs/ecryptfs_kernel.h index c15c25745e05..b73fb752c5f8 100644 --- a/fs/ecryptfs/ecryptfs_kernel.h +++ b/fs/ecryptfs/ecryptfs_kernel.h | |||
@@ -559,10 +559,25 @@ extern struct kmem_cache *ecryptfs_key_record_cache; | |||
559 | extern struct kmem_cache *ecryptfs_key_sig_cache; | 559 | extern struct kmem_cache *ecryptfs_key_sig_cache; |
560 | extern struct kmem_cache *ecryptfs_global_auth_tok_cache; | 560 | extern struct kmem_cache *ecryptfs_global_auth_tok_cache; |
561 | extern struct kmem_cache *ecryptfs_key_tfm_cache; | 561 | extern struct kmem_cache *ecryptfs_key_tfm_cache; |
562 | extern struct kmem_cache *ecryptfs_open_req_cache; | ||
562 | 563 | ||
564 | struct ecryptfs_open_req { | ||
565 | #define ECRYPTFS_REQ_PROCESSED 0x00000001 | ||
566 | #define ECRYPTFS_REQ_DROPPED 0x00000002 | ||
567 | #define ECRYPTFS_REQ_ZOMBIE 0x00000004 | ||
568 | u32 flags; | ||
569 | struct file **lower_file; | ||
570 | struct dentry *lower_dentry; | ||
571 | struct vfsmount *lower_mnt; | ||
572 | wait_queue_head_t wait; | ||
573 | struct mutex mux; | ||
574 | struct list_head kthread_ctl_list; | ||
575 | }; | ||
576 | |||
577 | #define ECRYPTFS_INTERPOSE_FLAG_D_ADD 0x00000001 | ||
563 | int ecryptfs_interpose(struct dentry *hidden_dentry, | 578 | int ecryptfs_interpose(struct dentry *hidden_dentry, |
564 | struct dentry *this_dentry, struct super_block *sb, | 579 | struct dentry *this_dentry, struct super_block *sb, |
565 | int flag); | 580 | u32 flags); |
566 | int ecryptfs_fill_zeros(struct file *file, loff_t new_length); | 581 | int ecryptfs_fill_zeros(struct file *file, loff_t new_length); |
567 | int ecryptfs_decode_filename(struct ecryptfs_crypt_stat *crypt_stat, | 582 | int ecryptfs_decode_filename(struct ecryptfs_crypt_stat *crypt_stat, |
568 | const char *name, int length, | 583 | const char *name, int length, |
@@ -690,5 +705,11 @@ void ecryptfs_msg_ctx_alloc_to_free(struct ecryptfs_msg_ctx *msg_ctx); | |||
690 | int | 705 | int |
691 | ecryptfs_spawn_daemon(struct ecryptfs_daemon **daemon, uid_t euid, | 706 | ecryptfs_spawn_daemon(struct ecryptfs_daemon **daemon, uid_t euid, |
692 | struct user_namespace *user_ns, struct pid *pid); | 707 | struct user_namespace *user_ns, struct pid *pid); |
708 | int ecryptfs_init_kthread(void); | ||
709 | void ecryptfs_destroy_kthread(void); | ||
710 | int ecryptfs_privileged_open(struct file **lower_file, | ||
711 | struct dentry *lower_dentry, | ||
712 | struct vfsmount *lower_mnt); | ||
713 | int ecryptfs_init_persistent_file(struct dentry *ecryptfs_dentry); | ||
693 | 714 | ||
694 | #endif /* #ifndef ECRYPTFS_KERNEL_H */ | 715 | #endif /* #ifndef ECRYPTFS_KERNEL_H */ |
diff --git a/fs/ecryptfs/file.c b/fs/ecryptfs/file.c index 24749bf0668f..9244d653743e 100644 --- a/fs/ecryptfs/file.c +++ b/fs/ecryptfs/file.c | |||
@@ -192,6 +192,23 @@ static int ecryptfs_open(struct inode *inode, struct file *file) | |||
192 | | ECRYPTFS_ENCRYPTED); | 192 | | ECRYPTFS_ENCRYPTED); |
193 | } | 193 | } |
194 | mutex_unlock(&crypt_stat->cs_mutex); | 194 | mutex_unlock(&crypt_stat->cs_mutex); |
195 | if ((ecryptfs_inode_to_private(inode)->lower_file->f_flags & O_RDONLY) | ||
196 | && !(file->f_flags & O_RDONLY)) { | ||
197 | rc = -EPERM; | ||
198 | printk(KERN_WARNING "%s: Lower persistent file is RO; eCryptfs " | ||
199 | "file must hence be opened RO\n", __func__); | ||
200 | goto out; | ||
201 | } | ||
202 | if (!ecryptfs_inode_to_private(inode)->lower_file) { | ||
203 | rc = ecryptfs_init_persistent_file(ecryptfs_dentry); | ||
204 | if (rc) { | ||
205 | printk(KERN_ERR "%s: Error attempting to initialize " | ||
206 | "the persistent file for the dentry with name " | ||
207 | "[%s]; rc = [%d]\n", __func__, | ||
208 | ecryptfs_dentry->d_name.name, rc); | ||
209 | goto out; | ||
210 | } | ||
211 | } | ||
195 | ecryptfs_set_file_lower( | 212 | ecryptfs_set_file_lower( |
196 | file, ecryptfs_inode_to_private(inode)->lower_file); | 213 | file, ecryptfs_inode_to_private(inode)->lower_file); |
197 | if (S_ISDIR(ecryptfs_dentry->d_inode->i_mode)) { | 214 | if (S_ISDIR(ecryptfs_dentry->d_inode->i_mode)) { |
diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c index c92cc1c00aae..d755455e3bff 100644 --- a/fs/ecryptfs/inode.c +++ b/fs/ecryptfs/inode.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include <linux/mount.h> | 31 | #include <linux/mount.h> |
32 | #include <linux/crypto.h> | 32 | #include <linux/crypto.h> |
33 | #include <linux/fs_stack.h> | 33 | #include <linux/fs_stack.h> |
34 | #include <asm/unaligned.h> | ||
34 | #include "ecryptfs_kernel.h" | 35 | #include "ecryptfs_kernel.h" |
35 | 36 | ||
36 | static struct dentry *lock_parent(struct dentry *dentry) | 37 | static struct dentry *lock_parent(struct dentry *dentry) |
@@ -188,6 +189,16 @@ static int ecryptfs_initialize_file(struct dentry *ecryptfs_dentry) | |||
188 | "context; rc = [%d]\n", rc); | 189 | "context; rc = [%d]\n", rc); |
189 | goto out; | 190 | goto out; |
190 | } | 191 | } |
192 | if (!ecryptfs_inode_to_private(ecryptfs_dentry->d_inode)->lower_file) { | ||
193 | rc = ecryptfs_init_persistent_file(ecryptfs_dentry); | ||
194 | if (rc) { | ||
195 | printk(KERN_ERR "%s: Error attempting to initialize " | ||
196 | "the persistent file for the dentry with name " | ||
197 | "[%s]; rc = [%d]\n", __func__, | ||
198 | ecryptfs_dentry->d_name.name, rc); | ||
199 | goto out; | ||
200 | } | ||
201 | } | ||
191 | rc = ecryptfs_write_metadata(ecryptfs_dentry); | 202 | rc = ecryptfs_write_metadata(ecryptfs_dentry); |
192 | if (rc) { | 203 | if (rc) { |
193 | printk(KERN_ERR "Error writing headers; rc = [%d]\n", rc); | 204 | printk(KERN_ERR "Error writing headers; rc = [%d]\n", rc); |
@@ -307,10 +318,11 @@ static struct dentry *ecryptfs_lookup(struct inode *dir, struct dentry *dentry, | |||
307 | d_add(dentry, NULL); | 318 | d_add(dentry, NULL); |
308 | goto out; | 319 | goto out; |
309 | } | 320 | } |
310 | rc = ecryptfs_interpose(lower_dentry, dentry, dir->i_sb, 1); | 321 | rc = ecryptfs_interpose(lower_dentry, dentry, dir->i_sb, |
322 | ECRYPTFS_INTERPOSE_FLAG_D_ADD); | ||
311 | if (rc) { | 323 | if (rc) { |
312 | ecryptfs_printk(KERN_ERR, "Error interposing\n"); | 324 | ecryptfs_printk(KERN_ERR, "Error interposing\n"); |
313 | goto out_dput; | 325 | goto out; |
314 | } | 326 | } |
315 | if (S_ISDIR(lower_inode->i_mode)) { | 327 | if (S_ISDIR(lower_inode->i_mode)) { |
316 | ecryptfs_printk(KERN_DEBUG, "Is a directory; returning\n"); | 328 | ecryptfs_printk(KERN_DEBUG, "Is a directory; returning\n"); |
@@ -336,11 +348,21 @@ static struct dentry *ecryptfs_lookup(struct inode *dir, struct dentry *dentry, | |||
336 | rc = -ENOMEM; | 348 | rc = -ENOMEM; |
337 | ecryptfs_printk(KERN_ERR, | 349 | ecryptfs_printk(KERN_ERR, |
338 | "Cannot ecryptfs_kmalloc a page\n"); | 350 | "Cannot ecryptfs_kmalloc a page\n"); |
339 | goto out_dput; | 351 | goto out; |
340 | } | 352 | } |
341 | crypt_stat = &ecryptfs_inode_to_private(dentry->d_inode)->crypt_stat; | 353 | crypt_stat = &ecryptfs_inode_to_private(dentry->d_inode)->crypt_stat; |
342 | if (!(crypt_stat->flags & ECRYPTFS_POLICY_APPLIED)) | 354 | if (!(crypt_stat->flags & ECRYPTFS_POLICY_APPLIED)) |
343 | ecryptfs_set_default_sizes(crypt_stat); | 355 | ecryptfs_set_default_sizes(crypt_stat); |
356 | if (!ecryptfs_inode_to_private(dentry->d_inode)->lower_file) { | ||
357 | rc = ecryptfs_init_persistent_file(dentry); | ||
358 | if (rc) { | ||
359 | printk(KERN_ERR "%s: Error attempting to initialize " | ||
360 | "the persistent file for the dentry with name " | ||
361 | "[%s]; rc = [%d]\n", __func__, | ||
362 | dentry->d_name.name, rc); | ||
363 | goto out; | ||
364 | } | ||
365 | } | ||
344 | rc = ecryptfs_read_and_validate_header_region(page_virt, | 366 | rc = ecryptfs_read_and_validate_header_region(page_virt, |
345 | dentry->d_inode); | 367 | dentry->d_inode); |
346 | if (rc) { | 368 | if (rc) { |
@@ -364,8 +386,7 @@ static struct dentry *ecryptfs_lookup(struct inode *dir, struct dentry *dentry, | |||
364 | else | 386 | else |
365 | file_size = i_size_read(lower_dentry->d_inode); | 387 | file_size = i_size_read(lower_dentry->d_inode); |
366 | } else { | 388 | } else { |
367 | memcpy(&file_size, page_virt, sizeof(file_size)); | 389 | file_size = get_unaligned_be64(page_virt); |
368 | file_size = be64_to_cpu(file_size); | ||
369 | } | 390 | } |
370 | i_size_write(dentry->d_inode, (loff_t)file_size); | 391 | i_size_write(dentry->d_inode, (loff_t)file_size); |
371 | kmem_cache_free(ecryptfs_header_cache_2, page_virt); | 392 | kmem_cache_free(ecryptfs_header_cache_2, page_virt); |
diff --git a/fs/ecryptfs/keystore.c b/fs/ecryptfs/keystore.c index e82b457180be..f5b76a331b9c 100644 --- a/fs/ecryptfs/keystore.c +++ b/fs/ecryptfs/keystore.c | |||
@@ -44,15 +44,15 @@ static int process_request_key_err(long err_code) | |||
44 | int rc = 0; | 44 | int rc = 0; |
45 | 45 | ||
46 | switch (err_code) { | 46 | switch (err_code) { |
47 | case ENOKEY: | 47 | case -ENOKEY: |
48 | ecryptfs_printk(KERN_WARNING, "No key\n"); | 48 | ecryptfs_printk(KERN_WARNING, "No key\n"); |
49 | rc = -ENOENT; | 49 | rc = -ENOENT; |
50 | break; | 50 | break; |
51 | case EKEYEXPIRED: | 51 | case -EKEYEXPIRED: |
52 | ecryptfs_printk(KERN_WARNING, "Key expired\n"); | 52 | ecryptfs_printk(KERN_WARNING, "Key expired\n"); |
53 | rc = -ETIME; | 53 | rc = -ETIME; |
54 | break; | 54 | break; |
55 | case EKEYREVOKED: | 55 | case -EKEYREVOKED: |
56 | ecryptfs_printk(KERN_WARNING, "Key revoked\n"); | 56 | ecryptfs_printk(KERN_WARNING, "Key revoked\n"); |
57 | rc = -EINVAL; | 57 | rc = -EINVAL; |
58 | break; | 58 | break; |
@@ -963,8 +963,7 @@ int ecryptfs_keyring_auth_tok_for_sig(struct key **auth_tok_key, | |||
963 | if (!(*auth_tok_key) || IS_ERR(*auth_tok_key)) { | 963 | if (!(*auth_tok_key) || IS_ERR(*auth_tok_key)) { |
964 | printk(KERN_ERR "Could not find key with description: [%s]\n", | 964 | printk(KERN_ERR "Could not find key with description: [%s]\n", |
965 | sig); | 965 | sig); |
966 | process_request_key_err(PTR_ERR(*auth_tok_key)); | 966 | rc = process_request_key_err(PTR_ERR(*auth_tok_key)); |
967 | rc = -EINVAL; | ||
968 | goto out; | 967 | goto out; |
969 | } | 968 | } |
970 | (*auth_tok) = ecryptfs_get_key_payload_data(*auth_tok_key); | 969 | (*auth_tok) = ecryptfs_get_key_payload_data(*auth_tok_key); |
diff --git a/fs/ecryptfs/kthread.c b/fs/ecryptfs/kthread.c new file mode 100644 index 000000000000..c440c6b58b2d --- /dev/null +++ b/fs/ecryptfs/kthread.c | |||
@@ -0,0 +1,203 @@ | |||
1 | /** | ||
2 | * eCryptfs: Linux filesystem encryption layer | ||
3 | * | ||
4 | * Copyright (C) 2008 International Business Machines Corp. | ||
5 | * Author(s): Michael A. Halcrow <mahalcro@us.ibm.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or | ||
8 | * modify it under the terms of the GNU General Public License as | ||
9 | * published by the Free Software Foundation; either version 2 of the | ||
10 | * License, or (at your option) any later version. | ||
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 <linux/kthread.h> | ||
24 | #include <linux/freezer.h> | ||
25 | #include <linux/wait.h> | ||
26 | #include <linux/mount.h> | ||
27 | #include "ecryptfs_kernel.h" | ||
28 | |||
29 | struct kmem_cache *ecryptfs_open_req_cache; | ||
30 | |||
31 | static struct ecryptfs_kthread_ctl { | ||
32 | #define ECRYPTFS_KTHREAD_ZOMBIE 0x00000001 | ||
33 | u32 flags; | ||
34 | struct mutex mux; | ||
35 | struct list_head req_list; | ||
36 | wait_queue_head_t wait; | ||
37 | } ecryptfs_kthread_ctl; | ||
38 | |||
39 | static struct task_struct *ecryptfs_kthread; | ||
40 | |||
41 | /** | ||
42 | * ecryptfs_threadfn | ||
43 | * @ignored: ignored | ||
44 | * | ||
45 | * The eCryptfs kernel thread that has the responsibility of getting | ||
46 | * the lower persistent file with RW permissions. | ||
47 | * | ||
48 | * Returns zero on success; non-zero otherwise | ||
49 | */ | ||
50 | static int ecryptfs_threadfn(void *ignored) | ||
51 | { | ||
52 | set_freezable(); | ||
53 | while (1) { | ||
54 | struct ecryptfs_open_req *req; | ||
55 | |||
56 | wait_event_freezable( | ||
57 | ecryptfs_kthread_ctl.wait, | ||
58 | (!list_empty(&ecryptfs_kthread_ctl.req_list) | ||
59 | || kthread_should_stop())); | ||
60 | mutex_lock(&ecryptfs_kthread_ctl.mux); | ||
61 | if (ecryptfs_kthread_ctl.flags & ECRYPTFS_KTHREAD_ZOMBIE) { | ||
62 | mutex_unlock(&ecryptfs_kthread_ctl.mux); | ||
63 | goto out; | ||
64 | } | ||
65 | while (!list_empty(&ecryptfs_kthread_ctl.req_list)) { | ||
66 | req = list_first_entry(&ecryptfs_kthread_ctl.req_list, | ||
67 | struct ecryptfs_open_req, | ||
68 | kthread_ctl_list); | ||
69 | mutex_lock(&req->mux); | ||
70 | list_del(&req->kthread_ctl_list); | ||
71 | if (!(req->flags & ECRYPTFS_REQ_ZOMBIE)) { | ||
72 | dget(req->lower_dentry); | ||
73 | mntget(req->lower_mnt); | ||
74 | (*req->lower_file) = dentry_open( | ||
75 | req->lower_dentry, req->lower_mnt, | ||
76 | (O_RDWR | O_LARGEFILE)); | ||
77 | req->flags |= ECRYPTFS_REQ_PROCESSED; | ||
78 | } | ||
79 | wake_up(&req->wait); | ||
80 | mutex_unlock(&req->mux); | ||
81 | } | ||
82 | mutex_unlock(&ecryptfs_kthread_ctl.mux); | ||
83 | } | ||
84 | out: | ||
85 | return 0; | ||
86 | } | ||
87 | |||
88 | int ecryptfs_init_kthread(void) | ||
89 | { | ||
90 | int rc = 0; | ||
91 | |||
92 | mutex_init(&ecryptfs_kthread_ctl.mux); | ||
93 | init_waitqueue_head(&ecryptfs_kthread_ctl.wait); | ||
94 | INIT_LIST_HEAD(&ecryptfs_kthread_ctl.req_list); | ||
95 | ecryptfs_kthread = kthread_run(&ecryptfs_threadfn, NULL, | ||
96 | "ecryptfs-kthread"); | ||
97 | if (IS_ERR(ecryptfs_kthread)) { | ||
98 | rc = PTR_ERR(ecryptfs_kthread); | ||
99 | printk(KERN_ERR "%s: Failed to create kernel thread; rc = [%d]" | ||
100 | "\n", __func__, rc); | ||
101 | } | ||
102 | return rc; | ||
103 | } | ||
104 | |||
105 | void ecryptfs_destroy_kthread(void) | ||
106 | { | ||
107 | struct ecryptfs_open_req *req; | ||
108 | |||
109 | mutex_lock(&ecryptfs_kthread_ctl.mux); | ||
110 | ecryptfs_kthread_ctl.flags |= ECRYPTFS_KTHREAD_ZOMBIE; | ||
111 | list_for_each_entry(req, &ecryptfs_kthread_ctl.req_list, | ||
112 | kthread_ctl_list) { | ||
113 | mutex_lock(&req->mux); | ||
114 | req->flags |= ECRYPTFS_REQ_ZOMBIE; | ||
115 | wake_up(&req->wait); | ||
116 | mutex_unlock(&req->mux); | ||
117 | } | ||
118 | mutex_unlock(&ecryptfs_kthread_ctl.mux); | ||
119 | kthread_stop(ecryptfs_kthread); | ||
120 | wake_up(&ecryptfs_kthread_ctl.wait); | ||
121 | } | ||
122 | |||
123 | /** | ||
124 | * ecryptfs_privileged_open | ||
125 | * @lower_file: Result of dentry_open by root on lower dentry | ||
126 | * @lower_dentry: Lower dentry for file to open | ||
127 | * @lower_mnt: Lower vfsmount for file to open | ||
128 | * | ||
129 | * This function gets a r/w file opened againt the lower dentry. | ||
130 | * | ||
131 | * Returns zero on success; non-zero otherwise | ||
132 | */ | ||
133 | int ecryptfs_privileged_open(struct file **lower_file, | ||
134 | struct dentry *lower_dentry, | ||
135 | struct vfsmount *lower_mnt) | ||
136 | { | ||
137 | struct ecryptfs_open_req *req; | ||
138 | int rc = 0; | ||
139 | |||
140 | /* Corresponding dput() and mntput() are done when the | ||
141 | * persistent file is fput() when the eCryptfs inode is | ||
142 | * destroyed. */ | ||
143 | dget(lower_dentry); | ||
144 | mntget(lower_mnt); | ||
145 | (*lower_file) = dentry_open(lower_dentry, lower_mnt, | ||
146 | (O_RDWR | O_LARGEFILE)); | ||
147 | if (!IS_ERR(*lower_file)) | ||
148 | goto out; | ||
149 | req = kmem_cache_alloc(ecryptfs_open_req_cache, GFP_KERNEL); | ||
150 | if (!req) { | ||
151 | rc = -ENOMEM; | ||
152 | goto out; | ||
153 | } | ||
154 | mutex_init(&req->mux); | ||
155 | req->lower_file = lower_file; | ||
156 | req->lower_dentry = lower_dentry; | ||
157 | req->lower_mnt = lower_mnt; | ||
158 | init_waitqueue_head(&req->wait); | ||
159 | req->flags = 0; | ||
160 | mutex_lock(&ecryptfs_kthread_ctl.mux); | ||
161 | if (ecryptfs_kthread_ctl.flags & ECRYPTFS_KTHREAD_ZOMBIE) { | ||
162 | rc = -EIO; | ||
163 | mutex_unlock(&ecryptfs_kthread_ctl.mux); | ||
164 | printk(KERN_ERR "%s: We are in the middle of shutting down; " | ||
165 | "aborting privileged request to open lower file\n", | ||
166 | __func__); | ||
167 | goto out_free; | ||
168 | } | ||
169 | list_add_tail(&req->kthread_ctl_list, &ecryptfs_kthread_ctl.req_list); | ||
170 | mutex_unlock(&ecryptfs_kthread_ctl.mux); | ||
171 | wake_up(&ecryptfs_kthread_ctl.wait); | ||
172 | wait_event(req->wait, (req->flags != 0)); | ||
173 | mutex_lock(&req->mux); | ||
174 | BUG_ON(req->flags == 0); | ||
175 | if (req->flags & ECRYPTFS_REQ_DROPPED | ||
176 | || req->flags & ECRYPTFS_REQ_ZOMBIE) { | ||
177 | rc = -EIO; | ||
178 | printk(KERN_WARNING "%s: Privileged open request dropped\n", | ||
179 | __func__); | ||
180 | goto out_unlock; | ||
181 | } | ||
182 | if (IS_ERR(*req->lower_file)) { | ||
183 | rc = PTR_ERR(*req->lower_file); | ||
184 | dget(lower_dentry); | ||
185 | mntget(lower_mnt); | ||
186 | (*lower_file) = dentry_open(lower_dentry, lower_mnt, | ||
187 | (O_RDONLY | O_LARGEFILE)); | ||
188 | if (IS_ERR(*lower_file)) { | ||
189 | rc = PTR_ERR(*req->lower_file); | ||
190 | (*lower_file) = NULL; | ||
191 | printk(KERN_WARNING "%s: Error attempting privileged " | ||
192 | "open of lower file with either RW or RO " | ||
193 | "perms; rc = [%d]. Giving up.\n", | ||
194 | __func__, rc); | ||
195 | } | ||
196 | } | ||
197 | out_unlock: | ||
198 | mutex_unlock(&req->mux); | ||
199 | out_free: | ||
200 | kmem_cache_free(ecryptfs_open_req_cache, req); | ||
201 | out: | ||
202 | return rc; | ||
203 | } | ||
diff --git a/fs/ecryptfs/main.c b/fs/ecryptfs/main.c index d603631601eb..6f403cfba14f 100644 --- a/fs/ecryptfs/main.c +++ b/fs/ecryptfs/main.c | |||
@@ -117,7 +117,7 @@ void __ecryptfs_printk(const char *fmt, ...) | |||
117 | * | 117 | * |
118 | * Returns zero on success; non-zero otherwise | 118 | * Returns zero on success; non-zero otherwise |
119 | */ | 119 | */ |
120 | static int ecryptfs_init_persistent_file(struct dentry *ecryptfs_dentry) | 120 | int ecryptfs_init_persistent_file(struct dentry *ecryptfs_dentry) |
121 | { | 121 | { |
122 | struct ecryptfs_inode_info *inode_info = | 122 | struct ecryptfs_inode_info *inode_info = |
123 | ecryptfs_inode_to_private(ecryptfs_dentry->d_inode); | 123 | ecryptfs_inode_to_private(ecryptfs_dentry->d_inode); |
@@ -130,26 +130,12 @@ static int ecryptfs_init_persistent_file(struct dentry *ecryptfs_dentry) | |||
130 | ecryptfs_dentry_to_lower_mnt(ecryptfs_dentry); | 130 | ecryptfs_dentry_to_lower_mnt(ecryptfs_dentry); |
131 | 131 | ||
132 | lower_dentry = ecryptfs_dentry_to_lower(ecryptfs_dentry); | 132 | lower_dentry = ecryptfs_dentry_to_lower(ecryptfs_dentry); |
133 | /* Corresponding dput() and mntput() are done when the | 133 | rc = ecryptfs_privileged_open(&inode_info->lower_file, |
134 | * persistent file is fput() when the eCryptfs inode | 134 | lower_dentry, lower_mnt); |
135 | * is destroyed. */ | 135 | if (rc || IS_ERR(inode_info->lower_file)) { |
136 | dget(lower_dentry); | ||
137 | mntget(lower_mnt); | ||
138 | inode_info->lower_file = dentry_open(lower_dentry, | ||
139 | lower_mnt, | ||
140 | (O_RDWR | O_LARGEFILE)); | ||
141 | if (IS_ERR(inode_info->lower_file)) { | ||
142 | dget(lower_dentry); | ||
143 | mntget(lower_mnt); | ||
144 | inode_info->lower_file = dentry_open(lower_dentry, | ||
145 | lower_mnt, | ||
146 | (O_RDONLY | ||
147 | | O_LARGEFILE)); | ||
148 | } | ||
149 | if (IS_ERR(inode_info->lower_file)) { | ||
150 | printk(KERN_ERR "Error opening lower persistent file " | 136 | printk(KERN_ERR "Error opening lower persistent file " |
151 | "for lower_dentry [0x%p] and lower_mnt [0x%p]\n", | 137 | "for lower_dentry [0x%p] and lower_mnt [0x%p]; " |
152 | lower_dentry, lower_mnt); | 138 | "rc = [%d]\n", lower_dentry, lower_mnt, rc); |
153 | rc = PTR_ERR(inode_info->lower_file); | 139 | rc = PTR_ERR(inode_info->lower_file); |
154 | inode_info->lower_file = NULL; | 140 | inode_info->lower_file = NULL; |
155 | } | 141 | } |
@@ -163,14 +149,14 @@ static int ecryptfs_init_persistent_file(struct dentry *ecryptfs_dentry) | |||
163 | * @lower_dentry: Existing dentry in the lower filesystem | 149 | * @lower_dentry: Existing dentry in the lower filesystem |
164 | * @dentry: ecryptfs' dentry | 150 | * @dentry: ecryptfs' dentry |
165 | * @sb: ecryptfs's super_block | 151 | * @sb: ecryptfs's super_block |
166 | * @flag: If set to true, then d_add is called, else d_instantiate is called | 152 | * @flags: flags to govern behavior of interpose procedure |
167 | * | 153 | * |
168 | * Interposes upper and lower dentries. | 154 | * Interposes upper and lower dentries. |
169 | * | 155 | * |
170 | * Returns zero on success; non-zero otherwise | 156 | * Returns zero on success; non-zero otherwise |
171 | */ | 157 | */ |
172 | int ecryptfs_interpose(struct dentry *lower_dentry, struct dentry *dentry, | 158 | int ecryptfs_interpose(struct dentry *lower_dentry, struct dentry *dentry, |
173 | struct super_block *sb, int flag) | 159 | struct super_block *sb, u32 flags) |
174 | { | 160 | { |
175 | struct inode *lower_inode; | 161 | struct inode *lower_inode; |
176 | struct inode *inode; | 162 | struct inode *inode; |
@@ -207,7 +193,7 @@ int ecryptfs_interpose(struct dentry *lower_dentry, struct dentry *dentry, | |||
207 | init_special_inode(inode, lower_inode->i_mode, | 193 | init_special_inode(inode, lower_inode->i_mode, |
208 | lower_inode->i_rdev); | 194 | lower_inode->i_rdev); |
209 | dentry->d_op = &ecryptfs_dops; | 195 | dentry->d_op = &ecryptfs_dops; |
210 | if (flag) | 196 | if (flags & ECRYPTFS_INTERPOSE_FLAG_D_ADD) |
211 | d_add(dentry, inode); | 197 | d_add(dentry, inode); |
212 | else | 198 | else |
213 | d_instantiate(dentry, inode); | 199 | d_instantiate(dentry, inode); |
@@ -215,13 +201,6 @@ int ecryptfs_interpose(struct dentry *lower_dentry, struct dentry *dentry, | |||
215 | /* This size will be overwritten for real files w/ headers and | 201 | /* This size will be overwritten for real files w/ headers and |
216 | * other metadata */ | 202 | * other metadata */ |
217 | fsstack_copy_inode_size(inode, lower_inode); | 203 | fsstack_copy_inode_size(inode, lower_inode); |
218 | rc = ecryptfs_init_persistent_file(dentry); | ||
219 | if (rc) { | ||
220 | printk(KERN_ERR "%s: Error attempting to initialize the " | ||
221 | "persistent file for the dentry with name [%s]; " | ||
222 | "rc = [%d]\n", __func__, dentry->d_name.name, rc); | ||
223 | goto out; | ||
224 | } | ||
225 | out: | 204 | out: |
226 | return rc; | 205 | return rc; |
227 | } | 206 | } |
@@ -262,10 +241,11 @@ static int ecryptfs_init_global_auth_toks( | |||
262 | "session keyring for sig specified in mount " | 241 | "session keyring for sig specified in mount " |
263 | "option: [%s]\n", global_auth_tok->sig); | 242 | "option: [%s]\n", global_auth_tok->sig); |
264 | global_auth_tok->flags |= ECRYPTFS_AUTH_TOK_INVALID; | 243 | global_auth_tok->flags |= ECRYPTFS_AUTH_TOK_INVALID; |
265 | rc = 0; | 244 | goto out; |
266 | } else | 245 | } else |
267 | global_auth_tok->flags &= ~ECRYPTFS_AUTH_TOK_INVALID; | 246 | global_auth_tok->flags &= ~ECRYPTFS_AUTH_TOK_INVALID; |
268 | } | 247 | } |
248 | out: | ||
269 | return rc; | 249 | return rc; |
270 | } | 250 | } |
271 | 251 | ||
@@ -314,7 +294,6 @@ static int ecryptfs_parse_options(struct super_block *sb, char *options) | |||
314 | char *cipher_name_dst; | 294 | char *cipher_name_dst; |
315 | char *cipher_name_src; | 295 | char *cipher_name_src; |
316 | char *cipher_key_bytes_src; | 296 | char *cipher_key_bytes_src; |
317 | int cipher_name_len; | ||
318 | 297 | ||
319 | if (!options) { | 298 | if (!options) { |
320 | rc = -EINVAL; | 299 | rc = -EINVAL; |
@@ -395,17 +374,12 @@ static int ecryptfs_parse_options(struct super_block *sb, char *options) | |||
395 | goto out; | 374 | goto out; |
396 | } | 375 | } |
397 | if (!cipher_name_set) { | 376 | if (!cipher_name_set) { |
398 | cipher_name_len = strlen(ECRYPTFS_DEFAULT_CIPHER); | 377 | int cipher_name_len = strlen(ECRYPTFS_DEFAULT_CIPHER); |
399 | if (unlikely(cipher_name_len | 378 | |
400 | >= ECRYPTFS_MAX_CIPHER_NAME_SIZE)) { | 379 | BUG_ON(cipher_name_len >= ECRYPTFS_MAX_CIPHER_NAME_SIZE); |
401 | rc = -EINVAL; | 380 | |
402 | BUG(); | 381 | strcpy(mount_crypt_stat->global_default_cipher_name, |
403 | goto out; | 382 | ECRYPTFS_DEFAULT_CIPHER); |
404 | } | ||
405 | memcpy(mount_crypt_stat->global_default_cipher_name, | ||
406 | ECRYPTFS_DEFAULT_CIPHER, cipher_name_len); | ||
407 | mount_crypt_stat->global_default_cipher_name[cipher_name_len] | ||
408 | = '\0'; | ||
409 | } | 383 | } |
410 | if (!cipher_key_bytes_set) { | 384 | if (!cipher_key_bytes_set) { |
411 | mount_crypt_stat->global_default_cipher_key_size = 0; | 385 | mount_crypt_stat->global_default_cipher_key_size = 0; |
@@ -430,7 +404,6 @@ static int ecryptfs_parse_options(struct super_block *sb, char *options) | |||
430 | printk(KERN_WARNING "One or more global auth toks could not " | 404 | printk(KERN_WARNING "One or more global auth toks could not " |
431 | "properly register; rc = [%d]\n", rc); | 405 | "properly register; rc = [%d]\n", rc); |
432 | } | 406 | } |
433 | rc = 0; | ||
434 | out: | 407 | out: |
435 | return rc; | 408 | return rc; |
436 | } | 409 | } |
@@ -679,6 +652,11 @@ static struct ecryptfs_cache_info { | |||
679 | .name = "ecryptfs_key_tfm_cache", | 652 | .name = "ecryptfs_key_tfm_cache", |
680 | .size = sizeof(struct ecryptfs_key_tfm), | 653 | .size = sizeof(struct ecryptfs_key_tfm), |
681 | }, | 654 | }, |
655 | { | ||
656 | .cache = &ecryptfs_open_req_cache, | ||
657 | .name = "ecryptfs_open_req_cache", | ||
658 | .size = sizeof(struct ecryptfs_open_req), | ||
659 | }, | ||
682 | }; | 660 | }; |
683 | 661 | ||
684 | static void ecryptfs_free_kmem_caches(void) | 662 | static void ecryptfs_free_kmem_caches(void) |
@@ -795,11 +773,17 @@ static int __init ecryptfs_init(void) | |||
795 | printk(KERN_ERR "sysfs registration failed\n"); | 773 | printk(KERN_ERR "sysfs registration failed\n"); |
796 | goto out_unregister_filesystem; | 774 | goto out_unregister_filesystem; |
797 | } | 775 | } |
776 | rc = ecryptfs_init_kthread(); | ||
777 | if (rc) { | ||
778 | printk(KERN_ERR "%s: kthread initialization failed; " | ||
779 | "rc = [%d]\n", __func__, rc); | ||
780 | goto out_do_sysfs_unregistration; | ||
781 | } | ||
798 | rc = ecryptfs_init_messaging(ecryptfs_transport); | 782 | rc = ecryptfs_init_messaging(ecryptfs_transport); |
799 | if (rc) { | 783 | if (rc) { |
800 | ecryptfs_printk(KERN_ERR, "Failure occured while attempting to " | 784 | printk(KERN_ERR "Failure occured while attempting to " |
801 | "initialize the eCryptfs netlink socket\n"); | 785 | "initialize the eCryptfs netlink socket\n"); |
802 | goto out_do_sysfs_unregistration; | 786 | goto out_destroy_kthread; |
803 | } | 787 | } |
804 | rc = ecryptfs_init_crypto(); | 788 | rc = ecryptfs_init_crypto(); |
805 | if (rc) { | 789 | if (rc) { |
@@ -814,6 +798,8 @@ static int __init ecryptfs_init(void) | |||
814 | goto out; | 798 | goto out; |
815 | out_release_messaging: | 799 | out_release_messaging: |
816 | ecryptfs_release_messaging(ecryptfs_transport); | 800 | ecryptfs_release_messaging(ecryptfs_transport); |
801 | out_destroy_kthread: | ||
802 | ecryptfs_destroy_kthread(); | ||
817 | out_do_sysfs_unregistration: | 803 | out_do_sysfs_unregistration: |
818 | do_sysfs_unregistration(); | 804 | do_sysfs_unregistration(); |
819 | out_unregister_filesystem: | 805 | out_unregister_filesystem: |
@@ -833,6 +819,7 @@ static void __exit ecryptfs_exit(void) | |||
833 | printk(KERN_ERR "Failure whilst attempting to destroy crypto; " | 819 | printk(KERN_ERR "Failure whilst attempting to destroy crypto; " |
834 | "rc = [%d]\n", rc); | 820 | "rc = [%d]\n", rc); |
835 | ecryptfs_release_messaging(ecryptfs_transport); | 821 | ecryptfs_release_messaging(ecryptfs_transport); |
822 | ecryptfs_destroy_kthread(); | ||
836 | do_sysfs_unregistration(); | 823 | do_sysfs_unregistration(); |
837 | unregister_filesystem(&ecryptfs_fs_type); | 824 | unregister_filesystem(&ecryptfs_fs_type); |
838 | ecryptfs_free_kmem_caches(); | 825 | ecryptfs_free_kmem_caches(); |
diff --git a/fs/ecryptfs/miscdev.c b/fs/ecryptfs/miscdev.c index 09a4522f65e6..b484792a0996 100644 --- a/fs/ecryptfs/miscdev.c +++ b/fs/ecryptfs/miscdev.c | |||
@@ -358,46 +358,6 @@ out_unlock_daemon: | |||
358 | } | 358 | } |
359 | 359 | ||
360 | /** | 360 | /** |
361 | * ecryptfs_miscdev_helo | ||
362 | * @euid: effective user id of miscdevess sending helo packet | ||
363 | * @user_ns: The namespace in which @euid applies | ||
364 | * @pid: miscdevess id of miscdevess sending helo packet | ||
365 | * | ||
366 | * Returns zero on success; non-zero otherwise | ||
367 | */ | ||
368 | static int ecryptfs_miscdev_helo(uid_t euid, struct user_namespace *user_ns, | ||
369 | struct pid *pid) | ||
370 | { | ||
371 | int rc; | ||
372 | |||
373 | rc = ecryptfs_process_helo(ECRYPTFS_TRANSPORT_MISCDEV, euid, user_ns, | ||
374 | pid); | ||
375 | if (rc) | ||
376 | printk(KERN_WARNING "Error processing HELO; rc = [%d]\n", rc); | ||
377 | return rc; | ||
378 | } | ||
379 | |||
380 | /** | ||
381 | * ecryptfs_miscdev_quit | ||
382 | * @euid: effective user id of miscdevess sending quit packet | ||
383 | * @user_ns: The namespace in which @euid applies | ||
384 | * @pid: miscdevess id of miscdevess sending quit packet | ||
385 | * | ||
386 | * Returns zero on success; non-zero otherwise | ||
387 | */ | ||
388 | static int ecryptfs_miscdev_quit(uid_t euid, struct user_namespace *user_ns, | ||
389 | struct pid *pid) | ||
390 | { | ||
391 | int rc; | ||
392 | |||
393 | rc = ecryptfs_process_quit(euid, user_ns, pid); | ||
394 | if (rc) | ||
395 | printk(KERN_WARNING | ||
396 | "Error processing QUIT message; rc = [%d]\n", rc); | ||
397 | return rc; | ||
398 | } | ||
399 | |||
400 | /** | ||
401 | * ecryptfs_miscdev_response - miscdevess response to message previously sent to daemon | 361 | * ecryptfs_miscdev_response - miscdevess response to message previously sent to daemon |
402 | * @data: Bytes comprising struct ecryptfs_message | 362 | * @data: Bytes comprising struct ecryptfs_message |
403 | * @data_size: sizeof(struct ecryptfs_message) + data len | 363 | * @data_size: sizeof(struct ecryptfs_message) + data len |
@@ -512,26 +472,7 @@ ecryptfs_miscdev_write(struct file *file, const char __user *buf, | |||
512 | __func__, rc); | 472 | __func__, rc); |
513 | break; | 473 | break; |
514 | case ECRYPTFS_MSG_HELO: | 474 | case ECRYPTFS_MSG_HELO: |
515 | rc = ecryptfs_miscdev_helo(current->euid, | ||
516 | current->nsproxy->user_ns, | ||
517 | task_pid(current)); | ||
518 | if (rc) { | ||
519 | printk(KERN_ERR "%s: Error attempting to process " | ||
520 | "helo from pid [0x%p]; rc = [%d]\n", __func__, | ||
521 | task_pid(current), rc); | ||
522 | goto out_free; | ||
523 | } | ||
524 | break; | ||
525 | case ECRYPTFS_MSG_QUIT: | 475 | case ECRYPTFS_MSG_QUIT: |
526 | rc = ecryptfs_miscdev_quit(current->euid, | ||
527 | current->nsproxy->user_ns, | ||
528 | task_pid(current)); | ||
529 | if (rc) { | ||
530 | printk(KERN_ERR "%s: Error attempting to process " | ||
531 | "quit from pid [0x%p]; rc = [%d]\n", __func__, | ||
532 | task_pid(current), rc); | ||
533 | goto out_free; | ||
534 | } | ||
535 | break; | 476 | break; |
536 | default: | 477 | default: |
537 | ecryptfs_printk(KERN_WARNING, "Dropping miscdev " | 478 | ecryptfs_printk(KERN_WARNING, "Dropping miscdev " |
diff --git a/fs/ecryptfs/mmap.c b/fs/ecryptfs/mmap.c index 2b6fe1e6e8ba..245c2dc02d5c 100644 --- a/fs/ecryptfs/mmap.c +++ b/fs/ecryptfs/mmap.c | |||
@@ -32,6 +32,7 @@ | |||
32 | #include <linux/file.h> | 32 | #include <linux/file.h> |
33 | #include <linux/crypto.h> | 33 | #include <linux/crypto.h> |
34 | #include <linux/scatterlist.h> | 34 | #include <linux/scatterlist.h> |
35 | #include <asm/unaligned.h> | ||
35 | #include "ecryptfs_kernel.h" | 36 | #include "ecryptfs_kernel.h" |
36 | 37 | ||
37 | /** | 38 | /** |
@@ -372,7 +373,6 @@ out: | |||
372 | */ | 373 | */ |
373 | static int ecryptfs_write_inode_size_to_header(struct inode *ecryptfs_inode) | 374 | static int ecryptfs_write_inode_size_to_header(struct inode *ecryptfs_inode) |
374 | { | 375 | { |
375 | u64 file_size; | ||
376 | char *file_size_virt; | 376 | char *file_size_virt; |
377 | int rc; | 377 | int rc; |
378 | 378 | ||
@@ -381,9 +381,7 @@ static int ecryptfs_write_inode_size_to_header(struct inode *ecryptfs_inode) | |||
381 | rc = -ENOMEM; | 381 | rc = -ENOMEM; |
382 | goto out; | 382 | goto out; |
383 | } | 383 | } |
384 | file_size = (u64)i_size_read(ecryptfs_inode); | 384 | put_unaligned_be64(i_size_read(ecryptfs_inode), file_size_virt); |
385 | file_size = cpu_to_be64(file_size); | ||
386 | memcpy(file_size_virt, &file_size, sizeof(u64)); | ||
387 | rc = ecryptfs_write_lower(ecryptfs_inode, file_size_virt, 0, | 385 | rc = ecryptfs_write_lower(ecryptfs_inode, file_size_virt, 0, |
388 | sizeof(u64)); | 386 | sizeof(u64)); |
389 | kfree(file_size_virt); | 387 | kfree(file_size_virt); |
@@ -403,7 +401,6 @@ static int ecryptfs_write_inode_size_to_xattr(struct inode *ecryptfs_inode) | |||
403 | struct dentry *lower_dentry = | 401 | struct dentry *lower_dentry = |
404 | ecryptfs_inode_to_private(ecryptfs_inode)->lower_file->f_dentry; | 402 | ecryptfs_inode_to_private(ecryptfs_inode)->lower_file->f_dentry; |
405 | struct inode *lower_inode = lower_dentry->d_inode; | 403 | struct inode *lower_inode = lower_dentry->d_inode; |
406 | u64 file_size; | ||
407 | int rc; | 404 | int rc; |
408 | 405 | ||
409 | if (!lower_inode->i_op->getxattr || !lower_inode->i_op->setxattr) { | 406 | if (!lower_inode->i_op->getxattr || !lower_inode->i_op->setxattr) { |
@@ -424,9 +421,7 @@ static int ecryptfs_write_inode_size_to_xattr(struct inode *ecryptfs_inode) | |||
424 | xattr_virt, PAGE_CACHE_SIZE); | 421 | xattr_virt, PAGE_CACHE_SIZE); |
425 | if (size < 0) | 422 | if (size < 0) |
426 | size = 8; | 423 | size = 8; |
427 | file_size = (u64)i_size_read(ecryptfs_inode); | 424 | put_unaligned_be64(i_size_read(ecryptfs_inode), xattr_virt); |
428 | file_size = cpu_to_be64(file_size); | ||
429 | memcpy(xattr_virt, &file_size, sizeof(u64)); | ||
430 | rc = lower_inode->i_op->setxattr(lower_dentry, ECRYPTFS_XATTR_NAME, | 425 | rc = lower_inode->i_op->setxattr(lower_dentry, ECRYPTFS_XATTR_NAME, |
431 | xattr_virt, size, 0); | 426 | xattr_virt, size, 0); |
432 | mutex_unlock(&lower_inode->i_mutex); | 427 | mutex_unlock(&lower_inode->i_mutex); |