diff options
author | Michael Halcrow <mhalcrow@us.ibm.com> | 2008-07-24 00:30:02 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-07-24 13:47:30 -0400 |
commit | 746f1e558bc52b9693c1a1ecdab60f8392e5ff18 (patch) | |
tree | a3253428affed93967c3ec67ba27ce8fe7d333c2 /fs/ecryptfs/main.c | |
parent | 0293902a4d66fab27d0ddcc0766e05dae68f004e (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.c | 42 |
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 | ||
684 | static void ecryptfs_free_kmem_caches(void) | 675 | static 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; |
815 | out_release_messaging: | 812 | out_release_messaging: |
816 | ecryptfs_release_messaging(ecryptfs_transport); | 813 | ecryptfs_release_messaging(ecryptfs_transport); |
814 | out_destroy_kthread: | ||
815 | ecryptfs_destroy_kthread(); | ||
817 | out_do_sysfs_unregistration: | 816 | out_do_sysfs_unregistration: |
818 | do_sysfs_unregistration(); | 817 | do_sysfs_unregistration(); |
819 | out_unregister_filesystem: | 818 | out_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(); |