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 989e034f02bd..cfb4b9fed520 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 2b17f2f9b121..44ce5c6a541d 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 c3ca12c33ca2..534b129ea676 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 1c0b3b6b75c6..2768138eefee 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 a750f957b145..b29bb8bfa8d9 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 c0038f6566d4..412e6eda25f8 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 a46b3a8fee1e..bd1d57f98f74 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 | } |
