diff options
author | Tyler Hicks <tyhicks@linux.vnet.ibm.com> | 2009-04-13 16:29:27 -0400 |
---|---|---|
committer | Tyler Hicks <tyhicks@linux.vnet.ibm.com> | 2009-04-22 04:54:13 -0400 |
commit | 13a791b4e63eb0537a7f804a340d6527485983b4 (patch) | |
tree | ad3c74093e8efe0da14644a0dc16ac0c61b2e6e5 /fs/ecryptfs/read_write.c | |
parent | 3a5203ab3c0c31e0f1434c69e893bfb85c6e6657 (diff) |
eCryptfs: Fix data corruption when using ecryptfs_passthrough
ecryptfs_passthrough is a mount option that allows eCryptfs to allow
data to be written to non-eCryptfs files in the lower filesystem. The
passthrough option was causing data corruption due to it not always
being treated as a non-eCryptfs file.
The first 8 bytes of an eCryptfs file contains the decrypted file size.
This value was being written to the non-eCryptfs files, too. Also,
extra 0x00 characters were being written to make the file size a
multiple of PAGE_CACHE_SIZE.
Signed-off-by: Tyler Hicks <tyhicks@linux.vnet.ibm.com>
Diffstat (limited to 'fs/ecryptfs/read_write.c')
-rw-r--r-- | fs/ecryptfs/read_write.c | 32 |
1 files changed, 21 insertions, 11 deletions
diff --git a/fs/ecryptfs/read_write.c b/fs/ecryptfs/read_write.c index 75c2ea9fee35..a137c6ea2fee 100644 --- a/fs/ecryptfs/read_write.c +++ b/fs/ecryptfs/read_write.c | |||
@@ -117,13 +117,15 @@ int ecryptfs_write(struct file *ecryptfs_file, char *data, loff_t offset, | |||
117 | size_t size) | 117 | size_t size) |
118 | { | 118 | { |
119 | struct page *ecryptfs_page; | 119 | struct page *ecryptfs_page; |
120 | struct ecryptfs_crypt_stat *crypt_stat; | ||
121 | struct inode *ecryptfs_inode = ecryptfs_file->f_dentry->d_inode; | ||
120 | char *ecryptfs_page_virt; | 122 | char *ecryptfs_page_virt; |
121 | loff_t ecryptfs_file_size = | 123 | loff_t ecryptfs_file_size = i_size_read(ecryptfs_inode); |
122 | i_size_read(ecryptfs_file->f_dentry->d_inode); | ||
123 | loff_t data_offset = 0; | 124 | loff_t data_offset = 0; |
124 | loff_t pos; | 125 | loff_t pos; |
125 | int rc = 0; | 126 | int rc = 0; |
126 | 127 | ||
128 | crypt_stat = &ecryptfs_inode_to_private(ecryptfs_inode)->crypt_stat; | ||
127 | /* | 129 | /* |
128 | * if we are writing beyond current size, then start pos | 130 | * if we are writing beyond current size, then start pos |
129 | * at the current size - we'll fill in zeros from there. | 131 | * at the current size - we'll fill in zeros from there. |
@@ -184,7 +186,13 @@ int ecryptfs_write(struct file *ecryptfs_file, char *data, loff_t offset, | |||
184 | flush_dcache_page(ecryptfs_page); | 186 | flush_dcache_page(ecryptfs_page); |
185 | SetPageUptodate(ecryptfs_page); | 187 | SetPageUptodate(ecryptfs_page); |
186 | unlock_page(ecryptfs_page); | 188 | unlock_page(ecryptfs_page); |
187 | rc = ecryptfs_encrypt_page(ecryptfs_page); | 189 | if (crypt_stat->flags & ECRYPTFS_ENCRYPTED) |
190 | rc = ecryptfs_encrypt_page(ecryptfs_page); | ||
191 | else | ||
192 | rc = ecryptfs_write_lower_page_segment(ecryptfs_inode, | ||
193 | ecryptfs_page, | ||
194 | start_offset_in_page, | ||
195 | data_offset); | ||
188 | page_cache_release(ecryptfs_page); | 196 | page_cache_release(ecryptfs_page); |
189 | if (rc) { | 197 | if (rc) { |
190 | printk(KERN_ERR "%s: Error encrypting " | 198 | printk(KERN_ERR "%s: Error encrypting " |
@@ -194,14 +202,16 @@ int ecryptfs_write(struct file *ecryptfs_file, char *data, loff_t offset, | |||
194 | pos += num_bytes; | 202 | pos += num_bytes; |
195 | } | 203 | } |
196 | if ((offset + size) > ecryptfs_file_size) { | 204 | if ((offset + size) > ecryptfs_file_size) { |
197 | i_size_write(ecryptfs_file->f_dentry->d_inode, (offset + size)); | 205 | i_size_write(ecryptfs_inode, (offset + size)); |
198 | rc = ecryptfs_write_inode_size_to_metadata( | 206 | if (crypt_stat->flags & ECRYPTFS_ENCRYPTED) { |
199 | ecryptfs_file->f_dentry->d_inode); | 207 | rc = ecryptfs_write_inode_size_to_metadata( |
200 | if (rc) { | 208 | ecryptfs_inode); |
201 | printk(KERN_ERR "Problem with " | 209 | if (rc) { |
202 | "ecryptfs_write_inode_size_to_metadata; " | 210 | printk(KERN_ERR "Problem with " |
203 | "rc = [%d]\n", rc); | 211 | "ecryptfs_write_inode_size_to_metadata; " |
204 | goto out; | 212 | "rc = [%d]\n", rc); |
213 | goto out; | ||
214 | } | ||
205 | } | 215 | } |
206 | } | 216 | } |
207 | out: | 217 | out: |