diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-08-02 13:56:34 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-08-02 13:56:34 -0400 |
commit | 410fc4ce8a373a3c35c73ac2c7c29f2bac6400bf (patch) | |
tree | 8a9e2e29f13a3ba93689f4afb951d64ffc10c9d5 /fs/ecryptfs | |
parent | 630103ea2c286de3e7ea9ae6b1035d91ef051413 (diff) | |
parent | 5f5b331d5c21228a6519dcb793fc1629646c51a6 (diff) |
Merge tag 'ecryptfs-3.6-rc1-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/tyhicks/ecryptfs
Pull ecryptfs fixes from Tyler Hicks:
- Fixes a bug when the lower filesystem mount options include 'acl',
but the eCryptfs mount options do not
- Cleanups in the messaging code
- Better handling of empty files in the lower filesystem to improve
usability. Failed file creations are now cleaned up and empty lower
files are converted into eCryptfs during open().
- The write-through cache changes are being reverted due to bugs that
are not easy to fix. Stability outweighs the performance
enhancements here.
- Improvement to the mount code to catch unsupported ciphers specified
in the mount options
* tag 'ecryptfs-3.6-rc1-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/tyhicks/ecryptfs:
eCryptfs: check for eCryptfs cipher support at mount
eCryptfs: Revert to a writethrough cache model
eCryptfs: Initialize empty lower files when opening them
eCryptfs: Unlink lower inode when ecryptfs_create() fails
eCryptfs: Make all miscdev functions use daemon ptr in file private_data
eCryptfs: Remove unused messaging declarations and function
eCryptfs: Copy up POSIX ACL and read-only flags from lower mount
Diffstat (limited to 'fs/ecryptfs')
-rw-r--r-- | fs/ecryptfs/ecryptfs_kernel.h | 24 | ||||
-rw-r--r-- | fs/ecryptfs/file.c | 90 | ||||
-rw-r--r-- | fs/ecryptfs/inode.c | 65 | ||||
-rw-r--r-- | fs/ecryptfs/main.c | 22 | ||||
-rw-r--r-- | fs/ecryptfs/messaging.c | 136 | ||||
-rw-r--r-- | fs/ecryptfs/miscdev.c | 98 | ||||
-rw-r--r-- | fs/ecryptfs/mmap.c | 39 |
7 files changed, 158 insertions, 316 deletions
diff --git a/fs/ecryptfs/ecryptfs_kernel.h b/fs/ecryptfs/ecryptfs_kernel.h index 989e034f02b..cfb4b9fed52 100644 --- a/fs/ecryptfs/ecryptfs_kernel.h +++ b/fs/ecryptfs/ecryptfs_kernel.h | |||
@@ -385,8 +385,6 @@ struct ecryptfs_msg_ctx { | |||
385 | struct mutex mux; | 385 | struct mutex mux; |
386 | }; | 386 | }; |
387 | 387 | ||
388 | struct ecryptfs_daemon; | ||
389 | |||
390 | struct ecryptfs_daemon { | 388 | struct ecryptfs_daemon { |
391 | #define ECRYPTFS_DAEMON_IN_READ 0x00000001 | 389 | #define ECRYPTFS_DAEMON_IN_READ 0x00000001 |
392 | #define ECRYPTFS_DAEMON_IN_POLL 0x00000002 | 390 | #define ECRYPTFS_DAEMON_IN_POLL 0x00000002 |
@@ -394,10 +392,7 @@ struct ecryptfs_daemon { | |||
394 | #define ECRYPTFS_DAEMON_MISCDEV_OPEN 0x00000008 | 392 | #define ECRYPTFS_DAEMON_MISCDEV_OPEN 0x00000008 |
395 | u32 flags; | 393 | u32 flags; |
396 | u32 num_queued_msg_ctx; | 394 | u32 num_queued_msg_ctx; |
397 | struct pid *pid; | 395 | struct file *file; |
398 | uid_t euid; | ||
399 | struct user_namespace *user_ns; | ||
400 | struct task_struct *task; | ||
401 | struct mutex mux; | 396 | struct mutex mux; |
402 | struct list_head msg_ctx_out_queue; | 397 | struct list_head msg_ctx_out_queue; |
403 | wait_queue_head_t wait; | 398 | wait_queue_head_t wait; |
@@ -554,6 +549,8 @@ extern struct kmem_cache *ecryptfs_key_tfm_cache; | |||
554 | struct inode *ecryptfs_get_inode(struct inode *lower_inode, | 549 | struct inode *ecryptfs_get_inode(struct inode *lower_inode, |
555 | struct super_block *sb); | 550 | struct super_block *sb); |
556 | void ecryptfs_i_size_init(const char *page_virt, struct inode *inode); | 551 | void ecryptfs_i_size_init(const char *page_virt, struct inode *inode); |
552 | int ecryptfs_initialize_file(struct dentry *ecryptfs_dentry, | ||
553 | struct inode *ecryptfs_inode); | ||
557 | int ecryptfs_decode_and_decrypt_filename(char **decrypted_name, | 554 | int ecryptfs_decode_and_decrypt_filename(char **decrypted_name, |
558 | size_t *decrypted_name_size, | 555 | size_t *decrypted_name_size, |
559 | struct dentry *ecryptfs_dentry, | 556 | struct dentry *ecryptfs_dentry, |
@@ -607,13 +604,8 @@ int | |||
607 | ecryptfs_setxattr(struct dentry *dentry, const char *name, const void *value, | 604 | ecryptfs_setxattr(struct dentry *dentry, const char *name, const void *value, |
608 | size_t size, int flags); | 605 | size_t size, int flags); |
609 | int ecryptfs_read_xattr_region(char *page_virt, struct inode *ecryptfs_inode); | 606 | int ecryptfs_read_xattr_region(char *page_virt, struct inode *ecryptfs_inode); |
610 | int ecryptfs_process_helo(uid_t euid, struct user_namespace *user_ns, | 607 | int ecryptfs_process_response(struct ecryptfs_daemon *daemon, |
611 | struct pid *pid); | 608 | struct ecryptfs_message *msg, u32 seq); |
612 | int ecryptfs_process_quit(uid_t euid, struct user_namespace *user_ns, | ||
613 | struct pid *pid); | ||
614 | int ecryptfs_process_response(struct ecryptfs_message *msg, uid_t euid, | ||
615 | struct user_namespace *user_ns, struct pid *pid, | ||
616 | u32 seq); | ||
617 | int ecryptfs_send_message(char *data, int data_len, | 609 | int ecryptfs_send_message(char *data, int data_len, |
618 | struct ecryptfs_msg_ctx **msg_ctx); | 610 | struct ecryptfs_msg_ctx **msg_ctx); |
619 | int ecryptfs_wait_for_response(struct ecryptfs_msg_ctx *msg_ctx, | 611 | int ecryptfs_wait_for_response(struct ecryptfs_msg_ctx *msg_ctx, |
@@ -658,8 +650,7 @@ int ecryptfs_read_lower_page_segment(struct page *page_for_ecryptfs, | |||
658 | struct inode *ecryptfs_inode); | 650 | struct inode *ecryptfs_inode); |
659 | struct page *ecryptfs_get_locked_page(struct inode *inode, loff_t index); | 651 | struct page *ecryptfs_get_locked_page(struct inode *inode, loff_t index); |
660 | int ecryptfs_exorcise_daemon(struct ecryptfs_daemon *daemon); | 652 | int ecryptfs_exorcise_daemon(struct ecryptfs_daemon *daemon); |
661 | int ecryptfs_find_daemon_by_euid(struct ecryptfs_daemon **daemon, uid_t euid, | 653 | int ecryptfs_find_daemon_by_euid(struct ecryptfs_daemon **daemon); |
662 | struct user_namespace *user_ns); | ||
663 | int ecryptfs_parse_packet_length(unsigned char *data, size_t *size, | 654 | int ecryptfs_parse_packet_length(unsigned char *data, size_t *size, |
664 | size_t *length_size); | 655 | size_t *length_size); |
665 | int ecryptfs_write_packet_length(char *dest, size_t size, | 656 | int ecryptfs_write_packet_length(char *dest, size_t size, |
@@ -671,8 +662,7 @@ int ecryptfs_send_miscdev(char *data, size_t data_size, | |||
671 | u16 msg_flags, struct ecryptfs_daemon *daemon); | 662 | u16 msg_flags, struct ecryptfs_daemon *daemon); |
672 | void ecryptfs_msg_ctx_alloc_to_free(struct ecryptfs_msg_ctx *msg_ctx); | 663 | void ecryptfs_msg_ctx_alloc_to_free(struct ecryptfs_msg_ctx *msg_ctx); |
673 | int | 664 | int |
674 | ecryptfs_spawn_daemon(struct ecryptfs_daemon **daemon, uid_t euid, | 665 | ecryptfs_spawn_daemon(struct ecryptfs_daemon **daemon, struct file *file); |
675 | struct user_namespace *user_ns, struct pid *pid); | ||
676 | int ecryptfs_init_kthread(void); | 666 | int ecryptfs_init_kthread(void); |
677 | void ecryptfs_destroy_kthread(void); | 667 | void ecryptfs_destroy_kthread(void); |
678 | int ecryptfs_privileged_open(struct file **lower_file, | 668 | int ecryptfs_privileged_open(struct file **lower_file, |
diff --git a/fs/ecryptfs/file.c b/fs/ecryptfs/file.c index 2b17f2f9b12..44ce5c6a541 100644 --- a/fs/ecryptfs/file.c +++ b/fs/ecryptfs/file.c | |||
@@ -138,29 +138,50 @@ out: | |||
138 | return rc; | 138 | return rc; |
139 | } | 139 | } |
140 | 140 | ||
141 | static void ecryptfs_vma_close(struct vm_area_struct *vma) | 141 | struct kmem_cache *ecryptfs_file_info_cache; |
142 | { | ||
143 | filemap_write_and_wait(vma->vm_file->f_mapping); | ||
144 | } | ||
145 | |||
146 | static const struct vm_operations_struct ecryptfs_file_vm_ops = { | ||
147 | .close = ecryptfs_vma_close, | ||
148 | .fault = filemap_fault, | ||
149 | }; | ||
150 | 142 | ||
151 | static int ecryptfs_file_mmap(struct file *file, struct vm_area_struct *vma) | 143 | static int read_or_initialize_metadata(struct dentry *dentry) |
152 | { | 144 | { |
145 | struct inode *inode = dentry->d_inode; | ||
146 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat; | ||
147 | struct ecryptfs_crypt_stat *crypt_stat; | ||
153 | int rc; | 148 | int rc; |
154 | 149 | ||
155 | rc = generic_file_mmap(file, vma); | 150 | crypt_stat = &ecryptfs_inode_to_private(inode)->crypt_stat; |
151 | mount_crypt_stat = &ecryptfs_superblock_to_private( | ||
152 | inode->i_sb)->mount_crypt_stat; | ||
153 | mutex_lock(&crypt_stat->cs_mutex); | ||
154 | |||
155 | if (crypt_stat->flags & ECRYPTFS_POLICY_APPLIED && | ||
156 | crypt_stat->flags & ECRYPTFS_KEY_VALID) { | ||
157 | rc = 0; | ||
158 | goto out; | ||
159 | } | ||
160 | |||
161 | rc = ecryptfs_read_metadata(dentry); | ||
156 | if (!rc) | 162 | if (!rc) |
157 | vma->vm_ops = &ecryptfs_file_vm_ops; | 163 | goto out; |
164 | |||
165 | if (mount_crypt_stat->flags & ECRYPTFS_PLAINTEXT_PASSTHROUGH_ENABLED) { | ||
166 | crypt_stat->flags &= ~(ECRYPTFS_I_SIZE_INITIALIZED | ||
167 | | ECRYPTFS_ENCRYPTED); | ||
168 | rc = 0; | ||
169 | goto out; | ||
170 | } | ||
158 | 171 | ||
172 | if (!(mount_crypt_stat->flags & ECRYPTFS_XATTR_METADATA_ENABLED) && | ||
173 | !i_size_read(ecryptfs_inode_to_lower(inode))) { | ||
174 | rc = ecryptfs_initialize_file(dentry, inode); | ||
175 | if (!rc) | ||
176 | goto out; | ||
177 | } | ||
178 | |||
179 | rc = -EIO; | ||
180 | out: | ||
181 | mutex_unlock(&crypt_stat->cs_mutex); | ||
159 | return rc; | 182 | return rc; |
160 | } | 183 | } |
161 | 184 | ||
162 | struct kmem_cache *ecryptfs_file_info_cache; | ||
163 | |||
164 | /** | 185 | /** |
165 | * ecryptfs_open | 186 | * ecryptfs_open |
166 | * @inode: inode speciying file to open | 187 | * @inode: inode speciying file to open |
@@ -236,32 +257,9 @@ static int ecryptfs_open(struct inode *inode, struct file *file) | |||
236 | rc = 0; | 257 | rc = 0; |
237 | goto out; | 258 | goto out; |
238 | } | 259 | } |
239 | mutex_lock(&crypt_stat->cs_mutex); | 260 | rc = read_or_initialize_metadata(ecryptfs_dentry); |
240 | if (!(crypt_stat->flags & ECRYPTFS_POLICY_APPLIED) | 261 | if (rc) |
241 | || !(crypt_stat->flags & ECRYPTFS_KEY_VALID)) { | 262 | goto out_put; |
242 | rc = ecryptfs_read_metadata(ecryptfs_dentry); | ||
243 | if (rc) { | ||
244 | ecryptfs_printk(KERN_DEBUG, | ||
245 | "Valid headers not found\n"); | ||
246 | if (!(mount_crypt_stat->flags | ||
247 | & ECRYPTFS_PLAINTEXT_PASSTHROUGH_ENABLED)) { | ||
248 | rc = -EIO; | ||
249 | printk(KERN_WARNING "Either the lower file " | ||
250 | "is not in a valid eCryptfs format, " | ||
251 | "or the key could not be retrieved. " | ||
252 | "Plaintext passthrough mode is not " | ||
253 | "enabled; returning -EIO\n"); | ||
254 | mutex_unlock(&crypt_stat->cs_mutex); | ||
255 | goto out_put; | ||
256 | } | ||
257 | rc = 0; | ||
258 | crypt_stat->flags &= ~(ECRYPTFS_I_SIZE_INITIALIZED | ||
259 | | ECRYPTFS_ENCRYPTED); | ||
260 | mutex_unlock(&crypt_stat->cs_mutex); | ||
261 | goto out; | ||
262 | } | ||
263 | } | ||
264 | mutex_unlock(&crypt_stat->cs_mutex); | ||
265 | ecryptfs_printk(KERN_DEBUG, "inode w/ addr = [0x%p], i_ino = " | 263 | ecryptfs_printk(KERN_DEBUG, "inode w/ addr = [0x%p], i_ino = " |
266 | "[0x%.16lx] size: [0x%.16llx]\n", inode, inode->i_ino, | 264 | "[0x%.16lx] size: [0x%.16llx]\n", inode, inode->i_ino, |
267 | (unsigned long long)i_size_read(inode)); | 265 | (unsigned long long)i_size_read(inode)); |
@@ -292,15 +290,7 @@ static int ecryptfs_release(struct inode *inode, struct file *file) | |||
292 | static int | 290 | static int |
293 | ecryptfs_fsync(struct file *file, loff_t start, loff_t end, int datasync) | 291 | ecryptfs_fsync(struct file *file, loff_t start, loff_t end, int datasync) |
294 | { | 292 | { |
295 | int rc = 0; | 293 | return vfs_fsync(ecryptfs_file_to_lower(file), datasync); |
296 | |||
297 | rc = generic_file_fsync(file, start, end, datasync); | ||
298 | if (rc) | ||
299 | goto out; | ||
300 | rc = vfs_fsync_range(ecryptfs_file_to_lower(file), start, end, | ||
301 | datasync); | ||
302 | out: | ||
303 | return rc; | ||
304 | } | 294 | } |
305 | 295 | ||
306 | static int ecryptfs_fasync(int fd, struct file *file, int flag) | 296 | static int ecryptfs_fasync(int fd, struct file *file, int flag) |
@@ -369,7 +359,7 @@ const struct file_operations ecryptfs_main_fops = { | |||
369 | #ifdef CONFIG_COMPAT | 359 | #ifdef CONFIG_COMPAT |
370 | .compat_ioctl = ecryptfs_compat_ioctl, | 360 | .compat_ioctl = ecryptfs_compat_ioctl, |
371 | #endif | 361 | #endif |
372 | .mmap = ecryptfs_file_mmap, | 362 | .mmap = generic_file_mmap, |
373 | .open = ecryptfs_open, | 363 | .open = ecryptfs_open, |
374 | .flush = ecryptfs_flush, | 364 | .flush = ecryptfs_flush, |
375 | .release = ecryptfs_release, | 365 | .release = ecryptfs_release, |
diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c index c3ca12c33ca..534b129ea67 100644 --- a/fs/ecryptfs/inode.c +++ b/fs/ecryptfs/inode.c | |||
@@ -143,6 +143,31 @@ static int ecryptfs_interpose(struct dentry *lower_dentry, | |||
143 | return 0; | 143 | return 0; |
144 | } | 144 | } |
145 | 145 | ||
146 | static int ecryptfs_do_unlink(struct inode *dir, struct dentry *dentry, | ||
147 | struct inode *inode) | ||
148 | { | ||
149 | struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry); | ||
150 | struct inode *lower_dir_inode = ecryptfs_inode_to_lower(dir); | ||
151 | struct dentry *lower_dir_dentry; | ||
152 | int rc; | ||
153 | |||
154 | dget(lower_dentry); | ||
155 | lower_dir_dentry = lock_parent(lower_dentry); | ||
156 | rc = vfs_unlink(lower_dir_inode, lower_dentry); | ||
157 | if (rc) { | ||
158 | printk(KERN_ERR "Error in vfs_unlink; rc = [%d]\n", rc); | ||
159 | goto out_unlock; | ||
160 | } | ||
161 | fsstack_copy_attr_times(dir, lower_dir_inode); | ||
162 | set_nlink(inode, ecryptfs_inode_to_lower(inode)->i_nlink); | ||
163 | inode->i_ctime = dir->i_ctime; | ||
164 | d_drop(dentry); | ||
165 | out_unlock: | ||
166 | unlock_dir(lower_dir_dentry); | ||
167 | dput(lower_dentry); | ||
168 | return rc; | ||
169 | } | ||
170 | |||
146 | /** | 171 | /** |
147 | * ecryptfs_do_create | 172 | * ecryptfs_do_create |
148 | * @directory_inode: inode of the new file's dentry's parent in ecryptfs | 173 | * @directory_inode: inode of the new file's dentry's parent in ecryptfs |
@@ -182,8 +207,10 @@ ecryptfs_do_create(struct inode *directory_inode, | |||
182 | } | 207 | } |
183 | inode = __ecryptfs_get_inode(lower_dentry->d_inode, | 208 | inode = __ecryptfs_get_inode(lower_dentry->d_inode, |
184 | directory_inode->i_sb); | 209 | directory_inode->i_sb); |
185 | if (IS_ERR(inode)) | 210 | if (IS_ERR(inode)) { |
211 | vfs_unlink(lower_dir_dentry->d_inode, lower_dentry); | ||
186 | goto out_lock; | 212 | goto out_lock; |
213 | } | ||
187 | fsstack_copy_attr_times(directory_inode, lower_dir_dentry->d_inode); | 214 | fsstack_copy_attr_times(directory_inode, lower_dir_dentry->d_inode); |
188 | fsstack_copy_inode_size(directory_inode, lower_dir_dentry->d_inode); | 215 | fsstack_copy_inode_size(directory_inode, lower_dir_dentry->d_inode); |
189 | out_lock: | 216 | out_lock: |
@@ -200,8 +227,8 @@ out: | |||
200 | * | 227 | * |
201 | * Returns zero on success | 228 | * Returns zero on success |
202 | */ | 229 | */ |
203 | static int ecryptfs_initialize_file(struct dentry *ecryptfs_dentry, | 230 | int ecryptfs_initialize_file(struct dentry *ecryptfs_dentry, |
204 | struct inode *ecryptfs_inode) | 231 | struct inode *ecryptfs_inode) |
205 | { | 232 | { |
206 | struct ecryptfs_crypt_stat *crypt_stat = | 233 | struct ecryptfs_crypt_stat *crypt_stat = |
207 | &ecryptfs_inode_to_private(ecryptfs_inode)->crypt_stat; | 234 | &ecryptfs_inode_to_private(ecryptfs_inode)->crypt_stat; |
@@ -264,7 +291,9 @@ ecryptfs_create(struct inode *directory_inode, struct dentry *ecryptfs_dentry, | |||
264 | * that this on disk file is prepared to be an ecryptfs file */ | 291 | * that this on disk file is prepared to be an ecryptfs file */ |
265 | rc = ecryptfs_initialize_file(ecryptfs_dentry, ecryptfs_inode); | 292 | rc = ecryptfs_initialize_file(ecryptfs_dentry, ecryptfs_inode); |
266 | if (rc) { | 293 | if (rc) { |
267 | drop_nlink(ecryptfs_inode); | 294 | ecryptfs_do_unlink(directory_inode, ecryptfs_dentry, |
295 | ecryptfs_inode); | ||
296 | make_bad_inode(ecryptfs_inode); | ||
268 | unlock_new_inode(ecryptfs_inode); | 297 | unlock_new_inode(ecryptfs_inode); |
269 | iput(ecryptfs_inode); | 298 | iput(ecryptfs_inode); |
270 | goto out; | 299 | goto out; |
@@ -466,27 +495,7 @@ out_lock: | |||
466 | 495 | ||
467 | static int ecryptfs_unlink(struct inode *dir, struct dentry *dentry) | 496 | static int ecryptfs_unlink(struct inode *dir, struct dentry *dentry) |
468 | { | 497 | { |
469 | int rc = 0; | 498 | return ecryptfs_do_unlink(dir, dentry, dentry->d_inode); |
470 | struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry); | ||
471 | struct inode *lower_dir_inode = ecryptfs_inode_to_lower(dir); | ||
472 | struct dentry *lower_dir_dentry; | ||
473 | |||
474 | dget(lower_dentry); | ||
475 | lower_dir_dentry = lock_parent(lower_dentry); | ||
476 | rc = vfs_unlink(lower_dir_inode, lower_dentry); | ||
477 | if (rc) { | ||
478 | printk(KERN_ERR "Error in vfs_unlink; rc = [%d]\n", rc); | ||
479 | goto out_unlock; | ||
480 | } | ||
481 | fsstack_copy_attr_times(dir, lower_dir_inode); | ||
482 | set_nlink(dentry->d_inode, | ||
483 | ecryptfs_inode_to_lower(dentry->d_inode)->i_nlink); | ||
484 | dentry->d_inode->i_ctime = dir->i_ctime; | ||
485 | d_drop(dentry); | ||
486 | out_unlock: | ||
487 | unlock_dir(lower_dir_dentry); | ||
488 | dput(lower_dentry); | ||
489 | return rc; | ||
490 | } | 499 | } |
491 | 500 | ||
492 | static int ecryptfs_symlink(struct inode *dir, struct dentry *dentry, | 501 | static int ecryptfs_symlink(struct inode *dir, struct dentry *dentry, |
@@ -961,12 +970,6 @@ static int ecryptfs_setattr(struct dentry *dentry, struct iattr *ia) | |||
961 | goto out; | 970 | goto out; |
962 | } | 971 | } |
963 | 972 | ||
964 | if (S_ISREG(inode->i_mode)) { | ||
965 | rc = filemap_write_and_wait(inode->i_mapping); | ||
966 | if (rc) | ||
967 | goto out; | ||
968 | fsstack_copy_attr_all(inode, lower_inode); | ||
969 | } | ||
970 | memcpy(&lower_ia, ia, sizeof(lower_ia)); | 973 | memcpy(&lower_ia, ia, sizeof(lower_ia)); |
971 | if (ia->ia_valid & ATTR_FILE) | 974 | if (ia->ia_valid & ATTR_FILE) |
972 | lower_ia.ia_file = ecryptfs_file_to_lower(ia->ia_file); | 975 | lower_ia.ia_file = ecryptfs_file_to_lower(ia->ia_file); |
diff --git a/fs/ecryptfs/main.c b/fs/ecryptfs/main.c index 1c0b3b6b75c..2768138eefe 100644 --- a/fs/ecryptfs/main.c +++ b/fs/ecryptfs/main.c | |||
@@ -279,6 +279,7 @@ static int ecryptfs_parse_options(struct ecryptfs_sb_info *sbi, char *options, | |||
279 | char *fnek_src; | 279 | char *fnek_src; |
280 | char *cipher_key_bytes_src; | 280 | char *cipher_key_bytes_src; |
281 | char *fn_cipher_key_bytes_src; | 281 | char *fn_cipher_key_bytes_src; |
282 | u8 cipher_code; | ||
282 | 283 | ||
283 | *check_ruid = 0; | 284 | *check_ruid = 0; |
284 | 285 | ||
@@ -420,6 +421,18 @@ static int ecryptfs_parse_options(struct ecryptfs_sb_info *sbi, char *options, | |||
420 | && !fn_cipher_key_bytes_set) | 421 | && !fn_cipher_key_bytes_set) |
421 | mount_crypt_stat->global_default_fn_cipher_key_bytes = | 422 | mount_crypt_stat->global_default_fn_cipher_key_bytes = |
422 | mount_crypt_stat->global_default_cipher_key_size; | 423 | mount_crypt_stat->global_default_cipher_key_size; |
424 | |||
425 | cipher_code = ecryptfs_code_for_cipher_string( | ||
426 | mount_crypt_stat->global_default_cipher_name, | ||
427 | mount_crypt_stat->global_default_cipher_key_size); | ||
428 | if (!cipher_code) { | ||
429 | ecryptfs_printk(KERN_ERR, | ||
430 | "eCryptfs doesn't support cipher: %s", | ||
431 | mount_crypt_stat->global_default_cipher_name); | ||
432 | rc = -EINVAL; | ||
433 | goto out; | ||
434 | } | ||
435 | |||
423 | mutex_lock(&key_tfm_list_mutex); | 436 | mutex_lock(&key_tfm_list_mutex); |
424 | if (!ecryptfs_tfm_exists(mount_crypt_stat->global_default_cipher_name, | 437 | if (!ecryptfs_tfm_exists(mount_crypt_stat->global_default_cipher_name, |
425 | NULL)) { | 438 | NULL)) { |
@@ -540,6 +553,15 @@ static struct dentry *ecryptfs_mount(struct file_system_type *fs_type, int flags | |||
540 | } | 553 | } |
541 | 554 | ||
542 | ecryptfs_set_superblock_lower(s, path.dentry->d_sb); | 555 | ecryptfs_set_superblock_lower(s, path.dentry->d_sb); |
556 | |||
557 | /** | ||
558 | * Set the POSIX ACL flag based on whether they're enabled in the lower | ||
559 | * mount. Force a read-only eCryptfs mount if the lower mount is ro. | ||
560 | * Allow a ro eCryptfs mount even when the lower mount is rw. | ||
561 | */ | ||
562 | s->s_flags = flags & ~MS_POSIXACL; | ||
563 | s->s_flags |= path.dentry->d_sb->s_flags & (MS_RDONLY | MS_POSIXACL); | ||
564 | |||
543 | s->s_maxbytes = path.dentry->d_sb->s_maxbytes; | 565 | s->s_maxbytes = path.dentry->d_sb->s_maxbytes; |
544 | s->s_blocksize = path.dentry->d_sb->s_blocksize; | 566 | s->s_blocksize = path.dentry->d_sb->s_blocksize; |
545 | s->s_magic = ECRYPTFS_SUPER_MAGIC; | 567 | s->s_magic = ECRYPTFS_SUPER_MAGIC; |
diff --git a/fs/ecryptfs/messaging.c b/fs/ecryptfs/messaging.c index a750f957b14..b29bb8bfa8d 100644 --- a/fs/ecryptfs/messaging.c +++ b/fs/ecryptfs/messaging.c | |||
@@ -32,8 +32,8 @@ static struct mutex ecryptfs_msg_ctx_lists_mux; | |||
32 | static struct hlist_head *ecryptfs_daemon_hash; | 32 | static struct hlist_head *ecryptfs_daemon_hash; |
33 | struct mutex ecryptfs_daemon_hash_mux; | 33 | struct mutex ecryptfs_daemon_hash_mux; |
34 | static int ecryptfs_hash_bits; | 34 | static int ecryptfs_hash_bits; |
35 | #define ecryptfs_uid_hash(uid) \ | 35 | #define ecryptfs_current_euid_hash(uid) \ |
36 | hash_long((unsigned long)uid, ecryptfs_hash_bits) | 36 | hash_long((unsigned long)current_euid(), ecryptfs_hash_bits) |
37 | 37 | ||
38 | static u32 ecryptfs_msg_counter; | 38 | static u32 ecryptfs_msg_counter; |
39 | static struct ecryptfs_msg_ctx *ecryptfs_msg_ctx_arr; | 39 | static struct ecryptfs_msg_ctx *ecryptfs_msg_ctx_arr; |
@@ -105,26 +105,24 @@ void ecryptfs_msg_ctx_alloc_to_free(struct ecryptfs_msg_ctx *msg_ctx) | |||
105 | 105 | ||
106 | /** | 106 | /** |
107 | * ecryptfs_find_daemon_by_euid | 107 | * ecryptfs_find_daemon_by_euid |
108 | * @euid: The effective user id which maps to the desired daemon id | ||
109 | * @user_ns: The namespace in which @euid applies | ||
110 | * @daemon: If return value is zero, points to the desired daemon pointer | 108 | * @daemon: If return value is zero, points to the desired daemon pointer |
111 | * | 109 | * |
112 | * Must be called with ecryptfs_daemon_hash_mux held. | 110 | * Must be called with ecryptfs_daemon_hash_mux held. |
113 | * | 111 | * |
114 | * Search the hash list for the given user id. | 112 | * Search the hash list for the current effective user id. |
115 | * | 113 | * |
116 | * Returns zero if the user id exists in the list; non-zero otherwise. | 114 | * Returns zero if the user id exists in the list; non-zero otherwise. |
117 | */ | 115 | */ |
118 | int ecryptfs_find_daemon_by_euid(struct ecryptfs_daemon **daemon, uid_t euid, | 116 | int ecryptfs_find_daemon_by_euid(struct ecryptfs_daemon **daemon) |
119 | struct user_namespace *user_ns) | ||
120 | { | 117 | { |
121 | struct hlist_node *elem; | 118 | struct hlist_node *elem; |
122 | int rc; | 119 | int rc; |
123 | 120 | ||
124 | hlist_for_each_entry(*daemon, elem, | 121 | hlist_for_each_entry(*daemon, elem, |
125 | &ecryptfs_daemon_hash[ecryptfs_uid_hash(euid)], | 122 | &ecryptfs_daemon_hash[ecryptfs_current_euid_hash()], |
126 | euid_chain) { | 123 | euid_chain) { |
127 | if ((*daemon)->euid == euid && (*daemon)->user_ns == user_ns) { | 124 | if ((*daemon)->file->f_cred->euid == current_euid() && |
125 | (*daemon)->file->f_cred->user_ns == current_user_ns()) { | ||
128 | rc = 0; | 126 | rc = 0; |
129 | goto out; | 127 | goto out; |
130 | } | 128 | } |
@@ -137,9 +135,7 @@ out: | |||
137 | /** | 135 | /** |
138 | * ecryptfs_spawn_daemon - Create and initialize a new daemon struct | 136 | * ecryptfs_spawn_daemon - Create and initialize a new daemon struct |
139 | * @daemon: Pointer to set to newly allocated daemon struct | 137 | * @daemon: Pointer to set to newly allocated daemon struct |
140 | * @euid: Effective user id for the daemon | 138 | * @file: File used when opening /dev/ecryptfs |
141 | * @user_ns: The namespace in which @euid applies | ||
142 | * @pid: Process id for the daemon | ||
143 | * | 139 | * |
144 | * Must be called ceremoniously while in possession of | 140 | * Must be called ceremoniously while in possession of |
145 | * ecryptfs_sacred_daemon_hash_mux | 141 | * ecryptfs_sacred_daemon_hash_mux |
@@ -147,8 +143,7 @@ out: | |||
147 | * Returns zero on success; non-zero otherwise | 143 | * Returns zero on success; non-zero otherwise |
148 | */ | 144 | */ |
149 | int | 145 | int |
150 | ecryptfs_spawn_daemon(struct ecryptfs_daemon **daemon, uid_t euid, | 146 | ecryptfs_spawn_daemon(struct ecryptfs_daemon **daemon, struct file *file) |
151 | struct user_namespace *user_ns, struct pid *pid) | ||
152 | { | 147 | { |
153 | int rc = 0; | 148 | int rc = 0; |
154 | 149 | ||
@@ -159,16 +154,13 @@ ecryptfs_spawn_daemon(struct ecryptfs_daemon **daemon, uid_t euid, | |||
159 | "GFP_KERNEL memory\n", __func__, sizeof(**daemon)); | 154 | "GFP_KERNEL memory\n", __func__, sizeof(**daemon)); |
160 | goto out; | 155 | goto out; |
161 | } | 156 | } |
162 | (*daemon)->euid = euid; | 157 | (*daemon)->file = file; |
163 | (*daemon)->user_ns = get_user_ns(user_ns); | ||
164 | (*daemon)->pid = get_pid(pid); | ||
165 | (*daemon)->task = current; | ||
166 | mutex_init(&(*daemon)->mux); | 158 | mutex_init(&(*daemon)->mux); |
167 | INIT_LIST_HEAD(&(*daemon)->msg_ctx_out_queue); | 159 | INIT_LIST_HEAD(&(*daemon)->msg_ctx_out_queue); |
168 | init_waitqueue_head(&(*daemon)->wait); | 160 | init_waitqueue_head(&(*daemon)->wait); |
169 | (*daemon)->num_queued_msg_ctx = 0; | 161 | (*daemon)->num_queued_msg_ctx = 0; |
170 | hlist_add_head(&(*daemon)->euid_chain, | 162 | hlist_add_head(&(*daemon)->euid_chain, |
171 | &ecryptfs_daemon_hash[ecryptfs_uid_hash(euid)]); | 163 | &ecryptfs_daemon_hash[ecryptfs_current_euid_hash()]); |
172 | out: | 164 | out: |
173 | return rc; | 165 | return rc; |
174 | } | 166 | } |
@@ -188,9 +180,6 @@ int ecryptfs_exorcise_daemon(struct ecryptfs_daemon *daemon) | |||
188 | if ((daemon->flags & ECRYPTFS_DAEMON_IN_READ) | 180 | if ((daemon->flags & ECRYPTFS_DAEMON_IN_READ) |
189 | || (daemon->flags & ECRYPTFS_DAEMON_IN_POLL)) { | 181 | || (daemon->flags & ECRYPTFS_DAEMON_IN_POLL)) { |
190 | rc = -EBUSY; | 182 | rc = -EBUSY; |
191 | printk(KERN_WARNING "%s: Attempt to destroy daemon with pid " | ||
192 | "[0x%p], but it is in the midst of a read or a poll\n", | ||
193 | __func__, daemon->pid); | ||
194 | mutex_unlock(&daemon->mux); | 183 | mutex_unlock(&daemon->mux); |
195 | goto out; | 184 | goto out; |
196 | } | 185 | } |
@@ -203,12 +192,6 @@ int ecryptfs_exorcise_daemon(struct ecryptfs_daemon *daemon) | |||
203 | ecryptfs_msg_ctx_alloc_to_free(msg_ctx); | 192 | ecryptfs_msg_ctx_alloc_to_free(msg_ctx); |
204 | } | 193 | } |
205 | hlist_del(&daemon->euid_chain); | 194 | hlist_del(&daemon->euid_chain); |
206 | if (daemon->task) | ||
207 | wake_up_process(daemon->task); | ||
208 | if (daemon->pid) | ||
209 | put_pid(daemon->pid); | ||
210 | if (daemon->user_ns) | ||
211 | put_user_ns(daemon->user_ns); | ||
212 | mutex_unlock(&daemon->mux); | 195 | mutex_unlock(&daemon->mux); |
213 | kzfree(daemon); | 196 | kzfree(daemon); |
214 | out: | 197 | out: |
@@ -216,42 +199,9 @@ out: | |||
216 | } | 199 | } |
217 | 200 | ||
218 | /** | 201 | /** |
219 | * ecryptfs_process_quit | ||
220 | * @euid: The user ID owner of the message | ||
221 | * @user_ns: The namespace in which @euid applies | ||
222 | * @pid: The process ID for the userspace program that sent the | ||
223 | * message | ||
224 | * | ||
225 | * Deletes the corresponding daemon for the given euid and pid, if | ||
226 | * it is the registered that is requesting the deletion. Returns zero | ||
227 | * after deleting the desired daemon; non-zero otherwise. | ||
228 | */ | ||
229 | int ecryptfs_process_quit(uid_t euid, struct user_namespace *user_ns, | ||
230 | struct pid *pid) | ||
231 | { | ||
232 | struct ecryptfs_daemon *daemon; | ||
233 | int rc; | ||
234 | |||
235 | mutex_lock(&ecryptfs_daemon_hash_mux); | ||
236 | rc = ecryptfs_find_daemon_by_euid(&daemon, euid, user_ns); | ||
237 | if (rc || !daemon) { | ||
238 | rc = -EINVAL; | ||
239 | printk(KERN_ERR "Received request from user [%d] to " | ||
240 | "unregister unrecognized daemon [0x%p]\n", euid, pid); | ||
241 | goto out_unlock; | ||
242 | } | ||
243 | rc = ecryptfs_exorcise_daemon(daemon); | ||
244 | out_unlock: | ||
245 | mutex_unlock(&ecryptfs_daemon_hash_mux); | ||
246 | return rc; | ||
247 | } | ||
248 | |||
249 | /** | ||
250 | * ecryptfs_process_reponse | 202 | * ecryptfs_process_reponse |
251 | * @msg: The ecryptfs message received; the caller should sanity check | 203 | * @msg: The ecryptfs message received; the caller should sanity check |
252 | * msg->data_len and free the memory | 204 | * msg->data_len and free the memory |
253 | * @pid: The process ID of the userspace application that sent the | ||
254 | * message | ||
255 | * @seq: The sequence number of the message; must match the sequence | 205 | * @seq: The sequence number of the message; must match the sequence |
256 | * number for the existing message context waiting for this | 206 | * number for the existing message context waiting for this |
257 | * response | 207 | * response |
@@ -270,16 +220,11 @@ out_unlock: | |||
270 | * | 220 | * |
271 | * Returns zero on success; non-zero otherwise | 221 | * Returns zero on success; non-zero otherwise |
272 | */ | 222 | */ |
273 | int ecryptfs_process_response(struct ecryptfs_message *msg, uid_t euid, | 223 | int ecryptfs_process_response(struct ecryptfs_daemon *daemon, |
274 | struct user_namespace *user_ns, struct pid *pid, | 224 | struct ecryptfs_message *msg, u32 seq) |
275 | u32 seq) | ||
276 | { | 225 | { |
277 | struct ecryptfs_daemon *uninitialized_var(daemon); | ||
278 | struct ecryptfs_msg_ctx *msg_ctx; | 226 | struct ecryptfs_msg_ctx *msg_ctx; |
279 | size_t msg_size; | 227 | size_t msg_size; |
280 | struct nsproxy *nsproxy; | ||
281 | struct user_namespace *tsk_user_ns; | ||
282 | uid_t ctx_euid; | ||
283 | int rc; | 228 | int rc; |
284 | 229 | ||
285 | if (msg->index >= ecryptfs_message_buf_len) { | 230 | if (msg->index >= ecryptfs_message_buf_len) { |
@@ -292,51 +237,6 @@ int ecryptfs_process_response(struct ecryptfs_message *msg, uid_t euid, | |||
292 | } | 237 | } |
293 | msg_ctx = &ecryptfs_msg_ctx_arr[msg->index]; | 238 | msg_ctx = &ecryptfs_msg_ctx_arr[msg->index]; |
294 | mutex_lock(&msg_ctx->mux); | 239 | mutex_lock(&msg_ctx->mux); |
295 | mutex_lock(&ecryptfs_daemon_hash_mux); | ||
296 | rcu_read_lock(); | ||
297 | nsproxy = task_nsproxy(msg_ctx->task); | ||
298 | if (nsproxy == NULL) { | ||
299 | rc = -EBADMSG; | ||
300 | printk(KERN_ERR "%s: Receiving process is a zombie. Dropping " | ||
301 | "message.\n", __func__); | ||
302 | rcu_read_unlock(); | ||
303 | mutex_unlock(&ecryptfs_daemon_hash_mux); | ||
304 | goto wake_up; | ||
305 | } | ||
306 | tsk_user_ns = __task_cred(msg_ctx->task)->user_ns; | ||
307 | ctx_euid = task_euid(msg_ctx->task); | ||
308 | rc = ecryptfs_find_daemon_by_euid(&daemon, ctx_euid, tsk_user_ns); | ||
309 | rcu_read_unlock(); | ||
310 | mutex_unlock(&ecryptfs_daemon_hash_mux); | ||
311 | if (rc) { | ||
312 | rc = -EBADMSG; | ||
313 | printk(KERN_WARNING "%s: User [%d] received a " | ||
314 | "message response from process [0x%p] but does " | ||
315 | "not have a registered daemon\n", __func__, | ||
316 | ctx_euid, pid); | ||
317 | goto wake_up; | ||
318 | } | ||
319 | if (ctx_euid != euid) { | ||
320 | rc = -EBADMSG; | ||
321 | printk(KERN_WARNING "%s: Received message from user " | ||
322 | "[%d]; expected message from user [%d]\n", __func__, | ||
323 | euid, ctx_euid); | ||
324 | goto unlock; | ||
325 | } | ||
326 | if (tsk_user_ns != user_ns) { | ||
327 | rc = -EBADMSG; | ||
328 | printk(KERN_WARNING "%s: Received message from user_ns " | ||
329 | "[0x%p]; expected message from user_ns [0x%p]\n", | ||
330 | __func__, user_ns, tsk_user_ns); | ||
331 | goto unlock; | ||
332 | } | ||
333 | if (daemon->pid != pid) { | ||
334 | rc = -EBADMSG; | ||
335 | printk(KERN_ERR "%s: User [%d] sent a message response " | ||
336 | "from an unrecognized process [0x%p]\n", | ||
337 | __func__, ctx_euid, pid); | ||
338 | goto unlock; | ||
339 | } | ||
340 | if (msg_ctx->state != ECRYPTFS_MSG_CTX_STATE_PENDING) { | 240 | if (msg_ctx->state != ECRYPTFS_MSG_CTX_STATE_PENDING) { |
341 | rc = -EINVAL; | 241 | rc = -EINVAL; |
342 | printk(KERN_WARNING "%s: Desired context element is not " | 242 | printk(KERN_WARNING "%s: Desired context element is not " |
@@ -359,9 +259,8 @@ int ecryptfs_process_response(struct ecryptfs_message *msg, uid_t euid, | |||
359 | } | 259 | } |
360 | memcpy(msg_ctx->msg, msg, msg_size); | 260 | memcpy(msg_ctx->msg, msg, msg_size); |
361 | msg_ctx->state = ECRYPTFS_MSG_CTX_STATE_DONE; | 261 | msg_ctx->state = ECRYPTFS_MSG_CTX_STATE_DONE; |
362 | rc = 0; | ||
363 | wake_up: | ||
364 | wake_up_process(msg_ctx->task); | 262 | wake_up_process(msg_ctx->task); |
263 | rc = 0; | ||
365 | unlock: | 264 | unlock: |
366 | mutex_unlock(&msg_ctx->mux); | 265 | mutex_unlock(&msg_ctx->mux); |
367 | out: | 266 | out: |
@@ -383,14 +282,11 @@ ecryptfs_send_message_locked(char *data, int data_len, u8 msg_type, | |||
383 | struct ecryptfs_msg_ctx **msg_ctx) | 282 | struct ecryptfs_msg_ctx **msg_ctx) |
384 | { | 283 | { |
385 | struct ecryptfs_daemon *daemon; | 284 | struct ecryptfs_daemon *daemon; |
386 | uid_t euid = current_euid(); | ||
387 | int rc; | 285 | int rc; |
388 | 286 | ||
389 | rc = ecryptfs_find_daemon_by_euid(&daemon, euid, current_user_ns()); | 287 | rc = ecryptfs_find_daemon_by_euid(&daemon); |
390 | if (rc || !daemon) { | 288 | if (rc || !daemon) { |
391 | rc = -ENOTCONN; | 289 | rc = -ENOTCONN; |
392 | printk(KERN_ERR "%s: User [%d] does not have a daemon " | ||
393 | "registered\n", __func__, euid); | ||
394 | goto out; | 290 | goto out; |
395 | } | 291 | } |
396 | mutex_lock(&ecryptfs_msg_ctx_lists_mux); | 292 | mutex_lock(&ecryptfs_msg_ctx_lists_mux); |
diff --git a/fs/ecryptfs/miscdev.c b/fs/ecryptfs/miscdev.c index c0038f6566d..412e6eda25f 100644 --- a/fs/ecryptfs/miscdev.c +++ b/fs/ecryptfs/miscdev.c | |||
@@ -33,7 +33,7 @@ static atomic_t ecryptfs_num_miscdev_opens; | |||
33 | 33 | ||
34 | /** | 34 | /** |
35 | * ecryptfs_miscdev_poll | 35 | * ecryptfs_miscdev_poll |
36 | * @file: dev file (ignored) | 36 | * @file: dev file |
37 | * @pt: dev poll table (ignored) | 37 | * @pt: dev poll table (ignored) |
38 | * | 38 | * |
39 | * Returns the poll mask | 39 | * Returns the poll mask |
@@ -41,20 +41,10 @@ static atomic_t ecryptfs_num_miscdev_opens; | |||
41 | static unsigned int | 41 | static unsigned int |
42 | ecryptfs_miscdev_poll(struct file *file, poll_table *pt) | 42 | ecryptfs_miscdev_poll(struct file *file, poll_table *pt) |
43 | { | 43 | { |
44 | struct ecryptfs_daemon *daemon; | 44 | struct ecryptfs_daemon *daemon = file->private_data; |
45 | unsigned int mask = 0; | 45 | unsigned int mask = 0; |
46 | uid_t euid = current_euid(); | ||
47 | int rc; | ||
48 | 46 | ||
49 | mutex_lock(&ecryptfs_daemon_hash_mux); | ||
50 | /* TODO: Just use file->private_data? */ | ||
51 | rc = ecryptfs_find_daemon_by_euid(&daemon, euid, current_user_ns()); | ||
52 | if (rc || !daemon) { | ||
53 | mutex_unlock(&ecryptfs_daemon_hash_mux); | ||
54 | return -EINVAL; | ||
55 | } | ||
56 | mutex_lock(&daemon->mux); | 47 | mutex_lock(&daemon->mux); |
57 | mutex_unlock(&ecryptfs_daemon_hash_mux); | ||
58 | if (daemon->flags & ECRYPTFS_DAEMON_ZOMBIE) { | 48 | if (daemon->flags & ECRYPTFS_DAEMON_ZOMBIE) { |
59 | printk(KERN_WARNING "%s: Attempt to poll on zombified " | 49 | printk(KERN_WARNING "%s: Attempt to poll on zombified " |
60 | "daemon\n", __func__); | 50 | "daemon\n", __func__); |
@@ -79,7 +69,7 @@ out_unlock_daemon: | |||
79 | /** | 69 | /** |
80 | * ecryptfs_miscdev_open | 70 | * ecryptfs_miscdev_open |
81 | * @inode: inode of miscdev handle (ignored) | 71 | * @inode: inode of miscdev handle (ignored) |
82 | * @file: file for miscdev handle (ignored) | 72 | * @file: file for miscdev handle |
83 | * | 73 | * |
84 | * Returns zero on success; non-zero otherwise | 74 | * Returns zero on success; non-zero otherwise |
85 | */ | 75 | */ |
@@ -87,7 +77,6 @@ static int | |||
87 | ecryptfs_miscdev_open(struct inode *inode, struct file *file) | 77 | ecryptfs_miscdev_open(struct inode *inode, struct file *file) |
88 | { | 78 | { |
89 | struct ecryptfs_daemon *daemon = NULL; | 79 | struct ecryptfs_daemon *daemon = NULL; |
90 | uid_t euid = current_euid(); | ||
91 | int rc; | 80 | int rc; |
92 | 81 | ||
93 | mutex_lock(&ecryptfs_daemon_hash_mux); | 82 | mutex_lock(&ecryptfs_daemon_hash_mux); |
@@ -98,30 +87,20 @@ ecryptfs_miscdev_open(struct inode *inode, struct file *file) | |||
98 | "count; rc = [%d]\n", __func__, rc); | 87 | "count; rc = [%d]\n", __func__, rc); |
99 | goto out_unlock_daemon_list; | 88 | goto out_unlock_daemon_list; |
100 | } | 89 | } |
101 | rc = ecryptfs_find_daemon_by_euid(&daemon, euid, current_user_ns()); | 90 | rc = ecryptfs_find_daemon_by_euid(&daemon); |
102 | if (rc || !daemon) { | 91 | if (!rc) { |
103 | rc = ecryptfs_spawn_daemon(&daemon, euid, current_user_ns(), | ||
104 | task_pid(current)); | ||
105 | if (rc) { | ||
106 | printk(KERN_ERR "%s: Error attempting to spawn daemon; " | ||
107 | "rc = [%d]\n", __func__, rc); | ||
108 | goto out_module_put_unlock_daemon_list; | ||
109 | } | ||
110 | } | ||
111 | mutex_lock(&daemon->mux); | ||
112 | if (daemon->pid != task_pid(current)) { | ||
113 | rc = -EINVAL; | 92 | rc = -EINVAL; |
114 | printk(KERN_ERR "%s: pid [0x%p] has registered with euid [%d], " | 93 | goto out_unlock_daemon_list; |
115 | "but pid [0x%p] has attempted to open the handle " | 94 | } |
116 | "instead\n", __func__, daemon->pid, daemon->euid, | 95 | rc = ecryptfs_spawn_daemon(&daemon, file); |
117 | task_pid(current)); | 96 | if (rc) { |
118 | goto out_unlock_daemon; | 97 | printk(KERN_ERR "%s: Error attempting to spawn daemon; " |
98 | "rc = [%d]\n", __func__, rc); | ||
99 | goto out_module_put_unlock_daemon_list; | ||
119 | } | 100 | } |
101 | mutex_lock(&daemon->mux); | ||
120 | if (daemon->flags & ECRYPTFS_DAEMON_MISCDEV_OPEN) { | 102 | if (daemon->flags & ECRYPTFS_DAEMON_MISCDEV_OPEN) { |
121 | rc = -EBUSY; | 103 | rc = -EBUSY; |
122 | printk(KERN_ERR "%s: Miscellaneous device handle may only be " | ||
123 | "opened once per daemon; pid [0x%p] already has this " | ||
124 | "handle open\n", __func__, daemon->pid); | ||
125 | goto out_unlock_daemon; | 104 | goto out_unlock_daemon; |
126 | } | 105 | } |
127 | daemon->flags |= ECRYPTFS_DAEMON_MISCDEV_OPEN; | 106 | daemon->flags |= ECRYPTFS_DAEMON_MISCDEV_OPEN; |
@@ -140,7 +119,7 @@ out_unlock_daemon_list: | |||
140 | /** | 119 | /** |
141 | * ecryptfs_miscdev_release | 120 | * ecryptfs_miscdev_release |
142 | * @inode: inode of fs/ecryptfs/euid handle (ignored) | 121 | * @inode: inode of fs/ecryptfs/euid handle (ignored) |
143 | * @file: file for fs/ecryptfs/euid handle (ignored) | 122 | * @file: file for fs/ecryptfs/euid handle |
144 | * | 123 | * |
145 | * This keeps the daemon registered until the daemon sends another | 124 | * This keeps the daemon registered until the daemon sends another |
146 | * ioctl to fs/ecryptfs/ctl or until the kernel module unregisters. | 125 | * ioctl to fs/ecryptfs/ctl or until the kernel module unregisters. |
@@ -150,20 +129,18 @@ out_unlock_daemon_list: | |||
150 | static int | 129 | static int |
151 | ecryptfs_miscdev_release(struct inode *inode, struct file *file) | 130 | ecryptfs_miscdev_release(struct inode *inode, struct file *file) |
152 | { | 131 | { |
153 | struct ecryptfs_daemon *daemon = NULL; | 132 | struct ecryptfs_daemon *daemon = file->private_data; |
154 | uid_t euid = current_euid(); | ||
155 | int rc; | 133 | int rc; |
156 | 134 | ||
157 | mutex_lock(&ecryptfs_daemon_hash_mux); | ||
158 | rc = ecryptfs_find_daemon_by_euid(&daemon, euid, current_user_ns()); | ||
159 | if (rc || !daemon) | ||
160 | daemon = file->private_data; | ||
161 | mutex_lock(&daemon->mux); | 135 | mutex_lock(&daemon->mux); |
162 | BUG_ON(!(daemon->flags & ECRYPTFS_DAEMON_MISCDEV_OPEN)); | 136 | BUG_ON(!(daemon->flags & ECRYPTFS_DAEMON_MISCDEV_OPEN)); |
163 | daemon->flags &= ~ECRYPTFS_DAEMON_MISCDEV_OPEN; | 137 | daemon->flags &= ~ECRYPTFS_DAEMON_MISCDEV_OPEN; |
164 | atomic_dec(&ecryptfs_num_miscdev_opens); | 138 | atomic_dec(&ecryptfs_num_miscdev_opens); |
165 | mutex_unlock(&daemon->mux); | 139 | mutex_unlock(&daemon->mux); |
140 | |||
141 | mutex_lock(&ecryptfs_daemon_hash_mux); | ||
166 | rc = ecryptfs_exorcise_daemon(daemon); | 142 | rc = ecryptfs_exorcise_daemon(daemon); |
143 | mutex_unlock(&ecryptfs_daemon_hash_mux); | ||
167 | if (rc) { | 144 | if (rc) { |
168 | printk(KERN_CRIT "%s: Fatal error whilst attempting to " | 145 | printk(KERN_CRIT "%s: Fatal error whilst attempting to " |
169 | "shut down daemon; rc = [%d]. Please report this " | 146 | "shut down daemon; rc = [%d]. Please report this " |
@@ -171,7 +148,6 @@ ecryptfs_miscdev_release(struct inode *inode, struct file *file) | |||
171 | BUG(); | 148 | BUG(); |
172 | } | 149 | } |
173 | module_put(THIS_MODULE); | 150 | module_put(THIS_MODULE); |
174 | mutex_unlock(&ecryptfs_daemon_hash_mux); | ||
175 | return rc; | 151 | return rc; |
176 | } | 152 | } |
177 | 153 | ||
@@ -248,7 +224,7 @@ int ecryptfs_send_miscdev(char *data, size_t data_size, | |||
248 | 224 | ||
249 | /** | 225 | /** |
250 | * ecryptfs_miscdev_read - format and send message from queue | 226 | * ecryptfs_miscdev_read - format and send message from queue |
251 | * @file: fs/ecryptfs/euid miscdevfs handle (ignored) | 227 | * @file: miscdevfs handle |
252 | * @buf: User buffer into which to copy the next message on the daemon queue | 228 | * @buf: User buffer into which to copy the next message on the daemon queue |
253 | * @count: Amount of space available in @buf | 229 | * @count: Amount of space available in @buf |
254 | * @ppos: Offset in file (ignored) | 230 | * @ppos: Offset in file (ignored) |
@@ -262,43 +238,27 @@ static ssize_t | |||
262 | ecryptfs_miscdev_read(struct file *file, char __user *buf, size_t count, | 238 | ecryptfs_miscdev_read(struct file *file, char __user *buf, size_t count, |
263 | loff_t *ppos) | 239 | loff_t *ppos) |
264 | { | 240 | { |
265 | struct ecryptfs_daemon *daemon; | 241 | struct ecryptfs_daemon *daemon = file->private_data; |
266 | struct ecryptfs_msg_ctx *msg_ctx; | 242 | struct ecryptfs_msg_ctx *msg_ctx; |
267 | size_t packet_length_size; | 243 | size_t packet_length_size; |
268 | char packet_length[ECRYPTFS_MAX_PKT_LEN_SIZE]; | 244 | char packet_length[ECRYPTFS_MAX_PKT_LEN_SIZE]; |
269 | size_t i; | 245 | size_t i; |
270 | size_t total_length; | 246 | size_t total_length; |
271 | uid_t euid = current_euid(); | ||
272 | int rc; | 247 | int rc; |
273 | 248 | ||
274 | mutex_lock(&ecryptfs_daemon_hash_mux); | ||
275 | /* TODO: Just use file->private_data? */ | ||
276 | rc = ecryptfs_find_daemon_by_euid(&daemon, euid, current_user_ns()); | ||
277 | if (rc || !daemon) { | ||
278 | mutex_unlock(&ecryptfs_daemon_hash_mux); | ||
279 | return -EINVAL; | ||
280 | } | ||
281 | mutex_lock(&daemon->mux); | 249 | mutex_lock(&daemon->mux); |
282 | if (task_pid(current) != daemon->pid) { | ||
283 | mutex_unlock(&daemon->mux); | ||
284 | mutex_unlock(&ecryptfs_daemon_hash_mux); | ||
285 | return -EPERM; | ||
286 | } | ||
287 | if (daemon->flags & ECRYPTFS_DAEMON_ZOMBIE) { | 250 | if (daemon->flags & ECRYPTFS_DAEMON_ZOMBIE) { |
288 | rc = 0; | 251 | rc = 0; |
289 | mutex_unlock(&ecryptfs_daemon_hash_mux); | ||
290 | printk(KERN_WARNING "%s: Attempt to read from zombified " | 252 | printk(KERN_WARNING "%s: Attempt to read from zombified " |
291 | "daemon\n", __func__); | 253 | "daemon\n", __func__); |
292 | goto out_unlock_daemon; | 254 | goto out_unlock_daemon; |
293 | } | 255 | } |
294 | if (daemon->flags & ECRYPTFS_DAEMON_IN_READ) { | 256 | if (daemon->flags & ECRYPTFS_DAEMON_IN_READ) { |
295 | rc = 0; | 257 | rc = 0; |
296 | mutex_unlock(&ecryptfs_daemon_hash_mux); | ||
297 | goto out_unlock_daemon; | 258 | goto out_unlock_daemon; |
298 | } | 259 | } |
299 | /* This daemon will not go away so long as this flag is set */ | 260 | /* This daemon will not go away so long as this flag is set */ |
300 | daemon->flags |= ECRYPTFS_DAEMON_IN_READ; | 261 | daemon->flags |= ECRYPTFS_DAEMON_IN_READ; |
301 | mutex_unlock(&ecryptfs_daemon_hash_mux); | ||
302 | check_list: | 262 | check_list: |
303 | if (list_empty(&daemon->msg_ctx_out_queue)) { | 263 | if (list_empty(&daemon->msg_ctx_out_queue)) { |
304 | mutex_unlock(&daemon->mux); | 264 | mutex_unlock(&daemon->mux); |
@@ -382,16 +342,12 @@ out_unlock_daemon: | |||
382 | * ecryptfs_miscdev_response - miscdevess response to message previously sent to daemon | 342 | * ecryptfs_miscdev_response - miscdevess response to message previously sent to daemon |
383 | * @data: Bytes comprising struct ecryptfs_message | 343 | * @data: Bytes comprising struct ecryptfs_message |
384 | * @data_size: sizeof(struct ecryptfs_message) + data len | 344 | * @data_size: sizeof(struct ecryptfs_message) + data len |
385 | * @euid: Effective user id of miscdevess sending the miscdev response | ||
386 | * @user_ns: The namespace in which @euid applies | ||
387 | * @pid: Miscdevess id of miscdevess sending the miscdev response | ||
388 | * @seq: Sequence number for miscdev response packet | 345 | * @seq: Sequence number for miscdev response packet |
389 | * | 346 | * |
390 | * Returns zero on success; non-zero otherwise | 347 | * Returns zero on success; non-zero otherwise |
391 | */ | 348 | */ |
392 | static int ecryptfs_miscdev_response(char *data, size_t data_size, | 349 | static int ecryptfs_miscdev_response(struct ecryptfs_daemon *daemon, char *data, |
393 | uid_t euid, struct user_namespace *user_ns, | 350 | size_t data_size, u32 seq) |
394 | struct pid *pid, u32 seq) | ||
395 | { | 351 | { |
396 | struct ecryptfs_message *msg = (struct ecryptfs_message *)data; | 352 | struct ecryptfs_message *msg = (struct ecryptfs_message *)data; |
397 | int rc; | 353 | int rc; |
@@ -403,7 +359,7 @@ static int ecryptfs_miscdev_response(char *data, size_t data_size, | |||
403 | rc = -EINVAL; | 359 | rc = -EINVAL; |
404 | goto out; | 360 | goto out; |
405 | } | 361 | } |
406 | rc = ecryptfs_process_response(msg, euid, user_ns, pid, seq); | 362 | rc = ecryptfs_process_response(daemon, msg, seq); |
407 | if (rc) | 363 | if (rc) |
408 | printk(KERN_ERR | 364 | printk(KERN_ERR |
409 | "Error processing response message; rc = [%d]\n", rc); | 365 | "Error processing response message; rc = [%d]\n", rc); |
@@ -413,7 +369,7 @@ out: | |||
413 | 369 | ||
414 | /** | 370 | /** |
415 | * ecryptfs_miscdev_write - handle write to daemon miscdev handle | 371 | * ecryptfs_miscdev_write - handle write to daemon miscdev handle |
416 | * @file: File for misc dev handle (ignored) | 372 | * @file: File for misc dev handle |
417 | * @buf: Buffer containing user data | 373 | * @buf: Buffer containing user data |
418 | * @count: Amount of data in @buf | 374 | * @count: Amount of data in @buf |
419 | * @ppos: Pointer to offset in file (ignored) | 375 | * @ppos: Pointer to offset in file (ignored) |
@@ -428,7 +384,6 @@ ecryptfs_miscdev_write(struct file *file, const char __user *buf, | |||
428 | u32 seq; | 384 | u32 seq; |
429 | size_t packet_size, packet_size_length; | 385 | size_t packet_size, packet_size_length; |
430 | char *data; | 386 | char *data; |
431 | uid_t euid = current_euid(); | ||
432 | unsigned char packet_size_peek[ECRYPTFS_MAX_PKT_LEN_SIZE]; | 387 | unsigned char packet_size_peek[ECRYPTFS_MAX_PKT_LEN_SIZE]; |
433 | ssize_t rc; | 388 | ssize_t rc; |
434 | 389 | ||
@@ -488,10 +443,9 @@ memdup: | |||
488 | } | 443 | } |
489 | memcpy(&counter_nbo, &data[PKT_CTR_OFFSET], PKT_CTR_SIZE); | 444 | memcpy(&counter_nbo, &data[PKT_CTR_OFFSET], PKT_CTR_SIZE); |
490 | seq = be32_to_cpu(counter_nbo); | 445 | seq = be32_to_cpu(counter_nbo); |
491 | rc = ecryptfs_miscdev_response( | 446 | rc = ecryptfs_miscdev_response(file->private_data, |
492 | &data[PKT_LEN_OFFSET + packet_size_length], | 447 | &data[PKT_LEN_OFFSET + packet_size_length], |
493 | packet_size, euid, current_user_ns(), | 448 | packet_size, seq); |
494 | task_pid(current), seq); | ||
495 | if (rc) { | 449 | if (rc) { |
496 | printk(KERN_WARNING "%s: Failed to deliver miscdev " | 450 | printk(KERN_WARNING "%s: Failed to deliver miscdev " |
497 | "response to requesting operation; rc = [%zd]\n", | 451 | "response to requesting operation; rc = [%zd]\n", |
diff --git a/fs/ecryptfs/mmap.c b/fs/ecryptfs/mmap.c index a46b3a8fee1..bd1d57f98f7 100644 --- a/fs/ecryptfs/mmap.c +++ b/fs/ecryptfs/mmap.c | |||
@@ -66,18 +66,6 @@ static int ecryptfs_writepage(struct page *page, struct writeback_control *wbc) | |||
66 | { | 66 | { |
67 | int rc; | 67 | int rc; |
68 | 68 | ||
69 | /* | ||
70 | * Refuse to write the page out if we are called from reclaim context | ||
71 | * since our writepage() path may potentially allocate memory when | ||
72 | * calling into the lower fs vfs_write() which may in turn invoke | ||
73 | * us again. | ||
74 | */ | ||
75 | if (current->flags & PF_MEMALLOC) { | ||
76 | redirty_page_for_writepage(wbc, page); | ||
77 | rc = 0; | ||
78 | goto out; | ||
79 | } | ||
80 | |||
81 | rc = ecryptfs_encrypt_page(page); | 69 | rc = ecryptfs_encrypt_page(page); |
82 | if (rc) { | 70 | if (rc) { |
83 | ecryptfs_printk(KERN_WARNING, "Error encrypting " | 71 | ecryptfs_printk(KERN_WARNING, "Error encrypting " |
@@ -498,7 +486,6 @@ static int ecryptfs_write_end(struct file *file, | |||
498 | struct ecryptfs_crypt_stat *crypt_stat = | 486 | struct ecryptfs_crypt_stat *crypt_stat = |
499 | &ecryptfs_inode_to_private(ecryptfs_inode)->crypt_stat; | 487 | &ecryptfs_inode_to_private(ecryptfs_inode)->crypt_stat; |
500 | int rc; | 488 | int rc; |
501 | int need_unlock_page = 1; | ||
502 | 489 | ||
503 | ecryptfs_printk(KERN_DEBUG, "Calling fill_zeros_to_end_of_page" | 490 | ecryptfs_printk(KERN_DEBUG, "Calling fill_zeros_to_end_of_page" |
504 | "(page w/ index = [0x%.16lx], to = [%d])\n", index, to); | 491 | "(page w/ index = [0x%.16lx], to = [%d])\n", index, to); |
@@ -519,26 +506,26 @@ static int ecryptfs_write_end(struct file *file, | |||
519 | "zeros in page with index = [0x%.16lx]\n", index); | 506 | "zeros in page with index = [0x%.16lx]\n", index); |
520 | goto out; | 507 | goto out; |
521 | } | 508 | } |
522 | set_page_dirty(page); | 509 | rc = ecryptfs_encrypt_page(page); |
523 | unlock_page(page); | 510 | if (rc) { |
524 | need_unlock_page = 0; | 511 | ecryptfs_printk(KERN_WARNING, "Error encrypting page (upper " |
512 | "index [0x%.16lx])\n", index); | ||
513 | goto out; | ||
514 | } | ||
525 | if (pos + copied > i_size_read(ecryptfs_inode)) { | 515 | if (pos + copied > i_size_read(ecryptfs_inode)) { |
526 | i_size_write(ecryptfs_inode, pos + copied); | 516 | i_size_write(ecryptfs_inode, pos + copied); |
527 | ecryptfs_printk(KERN_DEBUG, "Expanded file size to " | 517 | ecryptfs_printk(KERN_DEBUG, "Expanded file size to " |
528 | "[0x%.16llx]\n", | 518 | "[0x%.16llx]\n", |
529 | (unsigned long long)i_size_read(ecryptfs_inode)); | 519 | (unsigned long long)i_size_read(ecryptfs_inode)); |
530 | balance_dirty_pages_ratelimited(mapping); | ||
531 | rc = ecryptfs_write_inode_size_to_metadata(ecryptfs_inode); | ||
532 | if (rc) { | ||
533 | printk(KERN_ERR "Error writing inode size to metadata; " | ||
534 | "rc = [%d]\n", rc); | ||
535 | goto out; | ||
536 | } | ||
537 | } | 520 | } |
538 | rc = copied; | 521 | rc = ecryptfs_write_inode_size_to_metadata(ecryptfs_inode); |
522 | if (rc) | ||
523 | printk(KERN_ERR "Error writing inode size to metadata; " | ||
524 | "rc = [%d]\n", rc); | ||
525 | else | ||
526 | rc = copied; | ||
539 | out: | 527 | out: |
540 | if (need_unlock_page) | 528 | unlock_page(page); |
541 | unlock_page(page); | ||
542 | page_cache_release(page); | 529 | page_cache_release(page); |
543 | return rc; | 530 | return rc; |
544 | } | 531 | } |