diff options
author | Michael Halcrow <mhalcrow@us.ibm.com> | 2007-06-27 17:09:44 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-06-28 14:34:53 -0400 |
commit | e10f281bca03f45bdec91e67645c394eaec2f8f6 (patch) | |
tree | e6c0d1b43843d36c36c54aedba3d6b1395435bda /fs/ecryptfs/inode.c | |
parent | 240e2df5c740d73fc08cac9989872212deb2d20e (diff) |
eCryptfs: initialize crypt_stat in setattr
Recent changes in eCryptfs have made it possible to get to ecryptfs_setattr()
with an uninitialized crypt_stat struct. This results in a wide and colorful
variety of unpleasantries. This patch properly initializes the crypt_stat
structure in ecryptfs_setattr() when it is necessary to do so.
Signed-off-by: Michael Halcrow <mhalcrow@us.ibm.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs/ecryptfs/inode.c')
-rw-r--r-- | fs/ecryptfs/inode.c | 47 |
1 files changed, 46 insertions, 1 deletions
diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c index 0981ae35ea16..83e94fedd4e9 100644 --- a/fs/ecryptfs/inode.c +++ b/fs/ecryptfs/inode.c | |||
@@ -894,9 +894,54 @@ static int ecryptfs_setattr(struct dentry *dentry, struct iattr *ia) | |||
894 | struct ecryptfs_crypt_stat *crypt_stat; | 894 | struct ecryptfs_crypt_stat *crypt_stat; |
895 | 895 | ||
896 | crypt_stat = &ecryptfs_inode_to_private(dentry->d_inode)->crypt_stat; | 896 | crypt_stat = &ecryptfs_inode_to_private(dentry->d_inode)->crypt_stat; |
897 | lower_dentry = ecryptfs_dentry_to_lower(dentry); | 897 | if (!(crypt_stat->flags & ECRYPTFS_STRUCT_INITIALIZED)) |
898 | ecryptfs_init_crypt_stat(crypt_stat); | ||
898 | inode = dentry->d_inode; | 899 | inode = dentry->d_inode; |
899 | lower_inode = ecryptfs_inode_to_lower(inode); | 900 | lower_inode = ecryptfs_inode_to_lower(inode); |
901 | lower_dentry = ecryptfs_dentry_to_lower(dentry); | ||
902 | mutex_lock(&crypt_stat->cs_mutex); | ||
903 | if (S_ISDIR(dentry->d_inode->i_mode)) | ||
904 | crypt_stat->flags &= ~(ECRYPTFS_ENCRYPTED); | ||
905 | else if (!(crypt_stat->flags & ECRYPTFS_POLICY_APPLIED) | ||
906 | || !(crypt_stat->flags & ECRYPTFS_KEY_VALID)) { | ||
907 | struct vfsmount *lower_mnt; | ||
908 | struct file *lower_file = NULL; | ||
909 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat; | ||
910 | int lower_flags; | ||
911 | |||
912 | lower_mnt = ecryptfs_dentry_to_lower_mnt(dentry); | ||
913 | lower_flags = O_RDONLY; | ||
914 | if ((rc = ecryptfs_open_lower_file(&lower_file, lower_dentry, | ||
915 | lower_mnt, lower_flags))) { | ||
916 | printk(KERN_ERR | ||
917 | "Error opening lower file; rc = [%d]\n", rc); | ||
918 | mutex_unlock(&crypt_stat->cs_mutex); | ||
919 | goto out; | ||
920 | } | ||
921 | mount_crypt_stat = &ecryptfs_superblock_to_private( | ||
922 | dentry->d_sb)->mount_crypt_stat; | ||
923 | if ((rc = ecryptfs_read_metadata(dentry, lower_file))) { | ||
924 | if (!(mount_crypt_stat->flags | ||
925 | & ECRYPTFS_PLAINTEXT_PASSTHROUGH_ENABLED)) { | ||
926 | rc = -EIO; | ||
927 | printk(KERN_WARNING "Attempt to read file that " | ||
928 | "is not in a valid eCryptfs format, " | ||
929 | "and plaintext passthrough mode is not " | ||
930 | "enabled; returning -EIO\n"); | ||
931 | |||
932 | mutex_unlock(&crypt_stat->cs_mutex); | ||
933 | fput(lower_file); | ||
934 | goto out; | ||
935 | } | ||
936 | rc = 0; | ||
937 | crypt_stat->flags &= ~(ECRYPTFS_ENCRYPTED); | ||
938 | mutex_unlock(&crypt_stat->cs_mutex); | ||
939 | fput(lower_file); | ||
940 | goto out; | ||
941 | } | ||
942 | fput(lower_file); | ||
943 | } | ||
944 | mutex_unlock(&crypt_stat->cs_mutex); | ||
900 | if (ia->ia_valid & ATTR_SIZE) { | 945 | if (ia->ia_valid & ATTR_SIZE) { |
901 | ecryptfs_printk(KERN_DEBUG, | 946 | ecryptfs_printk(KERN_DEBUG, |
902 | "ia->ia_valid = [0x%x] ATTR_SIZE" " = [0x%x]\n", | 947 | "ia->ia_valid = [0x%x] ATTR_SIZE" " = [0x%x]\n", |