aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ecryptfs/main.c
diff options
context:
space:
mode:
authorMichael Halcrow <mhalcrow@us.ibm.com>2008-07-24 00:30:02 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-07-24 13:47:30 -0400
commit746f1e558bc52b9693c1a1ecdab60f8392e5ff18 (patch)
treea3253428affed93967c3ec67ba27ce8fe7d333c2 /fs/ecryptfs/main.c
parent0293902a4d66fab27d0ddcc0766e05dae68f004e (diff)
eCryptfs: Privileged kthread for lower file opens
eCryptfs would really like to have read-write access to all files in the lower filesystem. Right now, the persistent lower file may be opened read-only if the attempt to open it read-write fails. One way to keep from having to do that is to have a privileged kthread that can open the lower persistent file on behalf of the user opening the eCryptfs file; this patch implements this functionality. This patch will properly allow a less-privileged user to open the eCryptfs file, followed by a more-privileged user opening the eCryptfs file, with the first user only being able to read and the second user being able to both read and write. eCryptfs currently does this wrong; it will wind up calling vfs_write() on a file that was opened read-only. This is fixed in this patch. Signed-off-by: Michael Halcrow <mhalcrow@us.ibm.com> Cc: Dave Kleikamp <shaggy@austin.ibm.com> Cc: Serge Hallyn <serue@us.ibm.com> Cc: Eric Sandeen <sandeen@redhat.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs/ecryptfs/main.c')
-rw-r--r--fs/ecryptfs/main.c42
1 files changed, 21 insertions, 21 deletions
diff --git a/fs/ecryptfs/main.c b/fs/ecryptfs/main.c
index d603631601eb..f36ab2feea28 100644
--- a/fs/ecryptfs/main.c
+++ b/fs/ecryptfs/main.c
@@ -130,26 +130,12 @@ static int ecryptfs_init_persistent_file(struct dentry *ecryptfs_dentry)
130 ecryptfs_dentry_to_lower_mnt(ecryptfs_dentry); 130 ecryptfs_dentry_to_lower_mnt(ecryptfs_dentry);
131 131
132 lower_dentry = ecryptfs_dentry_to_lower(ecryptfs_dentry); 132 lower_dentry = ecryptfs_dentry_to_lower(ecryptfs_dentry);
133 /* Corresponding dput() and mntput() are done when the 133 rc = ecryptfs_privileged_open(&inode_info->lower_file,
134 * persistent file is fput() when the eCryptfs inode 134 lower_dentry, lower_mnt);
135 * is destroyed. */ 135 if (rc || IS_ERR(inode_info->lower_file)) {
136 dget(lower_dentry);
137 mntget(lower_mnt);
138 inode_info->lower_file = dentry_open(lower_dentry,
139 lower_mnt,
140 (O_RDWR | O_LARGEFILE));
141 if (IS_ERR(inode_info->lower_file)) {
142 dget(lower_dentry);
143 mntget(lower_mnt);
144 inode_info->lower_file = dentry_open(lower_dentry,
145 lower_mnt,
146 (O_RDONLY
147 | O_LARGEFILE));
148 }
149 if (IS_ERR(inode_info->lower_file)) {
150 printk(KERN_ERR "Error opening lower persistent file " 136 printk(KERN_ERR "Error opening lower persistent file "
151 "for lower_dentry [0x%p] and lower_mnt [0x%p]\n", 137 "for lower_dentry [0x%p] and lower_mnt [0x%p]; "
152 lower_dentry, lower_mnt); 138 "rc = [%d]\n", lower_dentry, lower_mnt, rc);
153 rc = PTR_ERR(inode_info->lower_file); 139 rc = PTR_ERR(inode_info->lower_file);
154 inode_info->lower_file = NULL; 140 inode_info->lower_file = NULL;
155 } 141 }
@@ -679,6 +665,11 @@ static struct ecryptfs_cache_info {
679 .name = "ecryptfs_key_tfm_cache", 665 .name = "ecryptfs_key_tfm_cache",
680 .size = sizeof(struct ecryptfs_key_tfm), 666 .size = sizeof(struct ecryptfs_key_tfm),
681 }, 667 },
668 {
669 .cache = &ecryptfs_open_req_cache,
670 .name = "ecryptfs_open_req_cache",
671 .size = sizeof(struct ecryptfs_open_req),
672 },
682}; 673};
683 674
684static void ecryptfs_free_kmem_caches(void) 675static void ecryptfs_free_kmem_caches(void)
@@ -795,11 +786,17 @@ static int __init ecryptfs_init(void)
795 printk(KERN_ERR "sysfs registration failed\n"); 786 printk(KERN_ERR "sysfs registration failed\n");
796 goto out_unregister_filesystem; 787 goto out_unregister_filesystem;
797 } 788 }
789 rc = ecryptfs_init_kthread();
790 if (rc) {
791 printk(KERN_ERR "%s: kthread initialization failed; "
792 "rc = [%d]\n", __func__, rc);
793 goto out_do_sysfs_unregistration;
794 }
798 rc = ecryptfs_init_messaging(ecryptfs_transport); 795 rc = ecryptfs_init_messaging(ecryptfs_transport);
799 if (rc) { 796 if (rc) {
800 ecryptfs_printk(KERN_ERR, "Failure occured while attempting to " 797 printk(KERN_ERR "Failure occured while attempting to "
801 "initialize the eCryptfs netlink socket\n"); 798 "initialize the eCryptfs netlink socket\n");
802 goto out_do_sysfs_unregistration; 799 goto out_destroy_kthread;
803 } 800 }
804 rc = ecryptfs_init_crypto(); 801 rc = ecryptfs_init_crypto();
805 if (rc) { 802 if (rc) {
@@ -814,6 +811,8 @@ static int __init ecryptfs_init(void)
814 goto out; 811 goto out;
815out_release_messaging: 812out_release_messaging:
816 ecryptfs_release_messaging(ecryptfs_transport); 813 ecryptfs_release_messaging(ecryptfs_transport);
814out_destroy_kthread:
815 ecryptfs_destroy_kthread();
817out_do_sysfs_unregistration: 816out_do_sysfs_unregistration:
818 do_sysfs_unregistration(); 817 do_sysfs_unregistration();
819out_unregister_filesystem: 818out_unregister_filesystem:
@@ -833,6 +832,7 @@ static void __exit ecryptfs_exit(void)
833 printk(KERN_ERR "Failure whilst attempting to destroy crypto; " 832 printk(KERN_ERR "Failure whilst attempting to destroy crypto; "
834 "rc = [%d]\n", rc); 833 "rc = [%d]\n", rc);
835 ecryptfs_release_messaging(ecryptfs_transport); 834 ecryptfs_release_messaging(ecryptfs_transport);
835 ecryptfs_destroy_kthread();
836 do_sysfs_unregistration(); 836 do_sysfs_unregistration();
837 unregister_filesystem(&ecryptfs_fs_type); 837 unregister_filesystem(&ecryptfs_fs_type);
838 ecryptfs_free_kmem_caches(); 838 ecryptfs_free_kmem_caches();