diff options
Diffstat (limited to 'fs/ecryptfs')
-rw-r--r-- | fs/ecryptfs/crypto.c | 23 | ||||
-rw-r--r-- | fs/ecryptfs/ecryptfs_kernel.h | 37 | ||||
-rw-r--r-- | fs/ecryptfs/file.c | 34 | ||||
-rw-r--r-- | fs/ecryptfs/inode.c | 84 | ||||
-rw-r--r-- | fs/ecryptfs/keystore.c | 272 | ||||
-rw-r--r-- | fs/ecryptfs/kthread.c | 6 | ||||
-rw-r--r-- | fs/ecryptfs/main.c | 82 | ||||
-rw-r--r-- | fs/ecryptfs/mmap.c | 61 | ||||
-rw-r--r-- | fs/ecryptfs/read_write.c | 12 | ||||
-rw-r--r-- | fs/ecryptfs/super.c | 17 |
10 files changed, 362 insertions, 266 deletions
diff --git a/fs/ecryptfs/crypto.c b/fs/ecryptfs/crypto.c index bfd8b680e648..b8d5c8091024 100644 --- a/fs/ecryptfs/crypto.c +++ b/fs/ecryptfs/crypto.c | |||
@@ -266,7 +266,6 @@ void ecryptfs_destroy_mount_crypt_stat( | |||
266 | &mount_crypt_stat->global_auth_tok_list, | 266 | &mount_crypt_stat->global_auth_tok_list, |
267 | mount_crypt_stat_list) { | 267 | mount_crypt_stat_list) { |
268 | list_del(&auth_tok->mount_crypt_stat_list); | 268 | list_del(&auth_tok->mount_crypt_stat_list); |
269 | mount_crypt_stat->num_global_auth_toks--; | ||
270 | if (auth_tok->global_auth_tok_key | 269 | if (auth_tok->global_auth_tok_key |
271 | && !(auth_tok->flags & ECRYPTFS_AUTH_TOK_INVALID)) | 270 | && !(auth_tok->flags & ECRYPTFS_AUTH_TOK_INVALID)) |
272 | key_put(auth_tok->global_auth_tok_key); | 271 | key_put(auth_tok->global_auth_tok_key); |
@@ -1389,6 +1388,7 @@ int ecryptfs_write_metadata(struct dentry *ecryptfs_dentry) | |||
1389 | rc = -ENOMEM; | 1388 | rc = -ENOMEM; |
1390 | goto out; | 1389 | goto out; |
1391 | } | 1390 | } |
1391 | /* Zeroed page ensures the in-header unencrypted i_size is set to 0 */ | ||
1392 | rc = ecryptfs_write_headers_virt(virt, virt_len, &size, crypt_stat, | 1392 | rc = ecryptfs_write_headers_virt(virt, virt_len, &size, crypt_stat, |
1393 | ecryptfs_dentry); | 1393 | ecryptfs_dentry); |
1394 | if (unlikely(rc)) { | 1394 | if (unlikely(rc)) { |
@@ -1452,6 +1452,25 @@ static void set_default_header_data(struct ecryptfs_crypt_stat *crypt_stat) | |||
1452 | crypt_stat->metadata_size = ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE; | 1452 | crypt_stat->metadata_size = ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE; |
1453 | } | 1453 | } |
1454 | 1454 | ||
1455 | void ecryptfs_i_size_init(const char *page_virt, struct inode *inode) | ||
1456 | { | ||
1457 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat; | ||
1458 | struct ecryptfs_crypt_stat *crypt_stat; | ||
1459 | u64 file_size; | ||
1460 | |||
1461 | crypt_stat = &ecryptfs_inode_to_private(inode)->crypt_stat; | ||
1462 | mount_crypt_stat = | ||
1463 | &ecryptfs_superblock_to_private(inode->i_sb)->mount_crypt_stat; | ||
1464 | if (mount_crypt_stat->flags & ECRYPTFS_ENCRYPTED_VIEW_ENABLED) { | ||
1465 | file_size = i_size_read(ecryptfs_inode_to_lower(inode)); | ||
1466 | if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR) | ||
1467 | file_size += crypt_stat->metadata_size; | ||
1468 | } else | ||
1469 | file_size = get_unaligned_be64(page_virt); | ||
1470 | i_size_write(inode, (loff_t)file_size); | ||
1471 | crypt_stat->flags |= ECRYPTFS_I_SIZE_INITIALIZED; | ||
1472 | } | ||
1473 | |||
1455 | /** | 1474 | /** |
1456 | * ecryptfs_read_headers_virt | 1475 | * ecryptfs_read_headers_virt |
1457 | * @page_virt: The virtual address into which to read the headers | 1476 | * @page_virt: The virtual address into which to read the headers |
@@ -1482,6 +1501,8 @@ static int ecryptfs_read_headers_virt(char *page_virt, | |||
1482 | rc = -EINVAL; | 1501 | rc = -EINVAL; |
1483 | goto out; | 1502 | goto out; |
1484 | } | 1503 | } |
1504 | if (!(crypt_stat->flags & ECRYPTFS_I_SIZE_INITIALIZED)) | ||
1505 | ecryptfs_i_size_init(page_virt, ecryptfs_dentry->d_inode); | ||
1485 | offset += MAGIC_ECRYPTFS_MARKER_SIZE_BYTES; | 1506 | offset += MAGIC_ECRYPTFS_MARKER_SIZE_BYTES; |
1486 | rc = ecryptfs_process_flags(crypt_stat, (page_virt + offset), | 1507 | rc = ecryptfs_process_flags(crypt_stat, (page_virt + offset), |
1487 | &bytes_read); | 1508 | &bytes_read); |
diff --git a/fs/ecryptfs/ecryptfs_kernel.h b/fs/ecryptfs/ecryptfs_kernel.h index e00753496e3e..e70282775e2c 100644 --- a/fs/ecryptfs/ecryptfs_kernel.h +++ b/fs/ecryptfs/ecryptfs_kernel.h | |||
@@ -233,7 +233,7 @@ ecryptfs_get_key_payload_data(struct key *key) | |||
233 | 233 | ||
234 | struct ecryptfs_key_sig { | 234 | struct ecryptfs_key_sig { |
235 | struct list_head crypt_stat_list; | 235 | struct list_head crypt_stat_list; |
236 | char keysig[ECRYPTFS_SIG_SIZE_HEX]; | 236 | char keysig[ECRYPTFS_SIG_SIZE_HEX + 1]; |
237 | }; | 237 | }; |
238 | 238 | ||
239 | struct ecryptfs_filename { | 239 | struct ecryptfs_filename { |
@@ -257,19 +257,19 @@ struct ecryptfs_filename { | |||
257 | struct ecryptfs_crypt_stat { | 257 | struct ecryptfs_crypt_stat { |
258 | #define ECRYPTFS_STRUCT_INITIALIZED 0x00000001 | 258 | #define ECRYPTFS_STRUCT_INITIALIZED 0x00000001 |
259 | #define ECRYPTFS_POLICY_APPLIED 0x00000002 | 259 | #define ECRYPTFS_POLICY_APPLIED 0x00000002 |
260 | #define ECRYPTFS_NEW_FILE 0x00000004 | 260 | #define ECRYPTFS_ENCRYPTED 0x00000004 |
261 | #define ECRYPTFS_ENCRYPTED 0x00000008 | 261 | #define ECRYPTFS_SECURITY_WARNING 0x00000008 |
262 | #define ECRYPTFS_SECURITY_WARNING 0x00000010 | 262 | #define ECRYPTFS_ENABLE_HMAC 0x00000010 |
263 | #define ECRYPTFS_ENABLE_HMAC 0x00000020 | 263 | #define ECRYPTFS_ENCRYPT_IV_PAGES 0x00000020 |
264 | #define ECRYPTFS_ENCRYPT_IV_PAGES 0x00000040 | 264 | #define ECRYPTFS_KEY_VALID 0x00000040 |
265 | #define ECRYPTFS_KEY_VALID 0x00000080 | 265 | #define ECRYPTFS_METADATA_IN_XATTR 0x00000080 |
266 | #define ECRYPTFS_METADATA_IN_XATTR 0x00000100 | 266 | #define ECRYPTFS_VIEW_AS_ENCRYPTED 0x00000100 |
267 | #define ECRYPTFS_VIEW_AS_ENCRYPTED 0x00000200 | 267 | #define ECRYPTFS_KEY_SET 0x00000200 |
268 | #define ECRYPTFS_KEY_SET 0x00000400 | 268 | #define ECRYPTFS_ENCRYPT_FILENAMES 0x00000400 |
269 | #define ECRYPTFS_ENCRYPT_FILENAMES 0x00000800 | 269 | #define ECRYPTFS_ENCFN_USE_MOUNT_FNEK 0x00000800 |
270 | #define ECRYPTFS_ENCFN_USE_MOUNT_FNEK 0x00001000 | 270 | #define ECRYPTFS_ENCFN_USE_FEK 0x00001000 |
271 | #define ECRYPTFS_ENCFN_USE_FEK 0x00002000 | 271 | #define ECRYPTFS_UNLINK_SIGS 0x00002000 |
272 | #define ECRYPTFS_UNLINK_SIGS 0x00004000 | 272 | #define ECRYPTFS_I_SIZE_INITIALIZED 0x00004000 |
273 | u32 flags; | 273 | u32 flags; |
274 | unsigned int file_version; | 274 | unsigned int file_version; |
275 | size_t iv_bytes; | 275 | size_t iv_bytes; |
@@ -296,8 +296,9 @@ struct ecryptfs_crypt_stat { | |||
296 | struct ecryptfs_inode_info { | 296 | struct ecryptfs_inode_info { |
297 | struct inode vfs_inode; | 297 | struct inode vfs_inode; |
298 | struct inode *wii_inode; | 298 | struct inode *wii_inode; |
299 | struct file *lower_file; | ||
300 | struct mutex lower_file_mutex; | 299 | struct mutex lower_file_mutex; |
300 | atomic_t lower_file_count; | ||
301 | struct file *lower_file; | ||
301 | struct ecryptfs_crypt_stat crypt_stat; | 302 | struct ecryptfs_crypt_stat crypt_stat; |
302 | }; | 303 | }; |
303 | 304 | ||
@@ -333,7 +334,6 @@ struct ecryptfs_global_auth_tok { | |||
333 | u32 flags; | 334 | u32 flags; |
334 | struct list_head mount_crypt_stat_list; | 335 | struct list_head mount_crypt_stat_list; |
335 | struct key *global_auth_tok_key; | 336 | struct key *global_auth_tok_key; |
336 | struct ecryptfs_auth_tok *global_auth_tok; | ||
337 | unsigned char sig[ECRYPTFS_SIG_SIZE_HEX + 1]; | 337 | unsigned char sig[ECRYPTFS_SIG_SIZE_HEX + 1]; |
338 | }; | 338 | }; |
339 | 339 | ||
@@ -380,7 +380,6 @@ struct ecryptfs_mount_crypt_stat { | |||
380 | u32 flags; | 380 | u32 flags; |
381 | struct list_head global_auth_tok_list; | 381 | struct list_head global_auth_tok_list; |
382 | struct mutex global_auth_tok_list_mutex; | 382 | struct mutex global_auth_tok_list_mutex; |
383 | size_t num_global_auth_toks; | ||
384 | size_t global_default_cipher_key_size; | 383 | size_t global_default_cipher_key_size; |
385 | size_t global_default_fn_cipher_key_bytes; | 384 | size_t global_default_fn_cipher_key_bytes; |
386 | unsigned char global_default_cipher_name[ECRYPTFS_MAX_CIPHER_NAME_SIZE | 385 | unsigned char global_default_cipher_name[ECRYPTFS_MAX_CIPHER_NAME_SIZE |
@@ -630,6 +629,7 @@ struct ecryptfs_open_req { | |||
630 | int ecryptfs_interpose(struct dentry *hidden_dentry, | 629 | int ecryptfs_interpose(struct dentry *hidden_dentry, |
631 | struct dentry *this_dentry, struct super_block *sb, | 630 | struct dentry *this_dentry, struct super_block *sb, |
632 | u32 flags); | 631 | u32 flags); |
632 | void ecryptfs_i_size_init(const char *page_virt, struct inode *inode); | ||
633 | int ecryptfs_lookup_and_interpose_lower(struct dentry *ecryptfs_dentry, | 633 | int ecryptfs_lookup_and_interpose_lower(struct dentry *ecryptfs_dentry, |
634 | struct dentry *lower_dentry, | 634 | struct dentry *lower_dentry, |
635 | struct inode *ecryptfs_dir_inode); | 635 | struct inode *ecryptfs_dir_inode); |
@@ -761,7 +761,8 @@ int ecryptfs_privileged_open(struct file **lower_file, | |||
761 | struct dentry *lower_dentry, | 761 | struct dentry *lower_dentry, |
762 | struct vfsmount *lower_mnt, | 762 | struct vfsmount *lower_mnt, |
763 | const struct cred *cred); | 763 | const struct cred *cred); |
764 | int ecryptfs_init_persistent_file(struct dentry *ecryptfs_dentry); | 764 | int ecryptfs_get_lower_file(struct dentry *ecryptfs_dentry); |
765 | void ecryptfs_put_lower_file(struct inode *inode); | ||
765 | int | 766 | int |
766 | ecryptfs_write_tag_70_packet(char *dest, size_t *remaining_bytes, | 767 | ecryptfs_write_tag_70_packet(char *dest, size_t *remaining_bytes, |
767 | size_t *packet_size, | 768 | size_t *packet_size, |
diff --git a/fs/ecryptfs/file.c b/fs/ecryptfs/file.c index 7d1050e254f9..566e5472f78c 100644 --- a/fs/ecryptfs/file.c +++ b/fs/ecryptfs/file.c | |||
@@ -191,10 +191,10 @@ static int ecryptfs_open(struct inode *inode, struct file *file) | |||
191 | | ECRYPTFS_ENCRYPTED); | 191 | | ECRYPTFS_ENCRYPTED); |
192 | } | 192 | } |
193 | mutex_unlock(&crypt_stat->cs_mutex); | 193 | mutex_unlock(&crypt_stat->cs_mutex); |
194 | rc = ecryptfs_init_persistent_file(ecryptfs_dentry); | 194 | rc = ecryptfs_get_lower_file(ecryptfs_dentry); |
195 | if (rc) { | 195 | if (rc) { |
196 | printk(KERN_ERR "%s: Error attempting to initialize " | 196 | printk(KERN_ERR "%s: Error attempting to initialize " |
197 | "the persistent file for the dentry with name " | 197 | "the lower file for the dentry with name " |
198 | "[%s]; rc = [%d]\n", __func__, | 198 | "[%s]; rc = [%d]\n", __func__, |
199 | ecryptfs_dentry->d_name.name, rc); | 199 | ecryptfs_dentry->d_name.name, rc); |
200 | goto out_free; | 200 | goto out_free; |
@@ -202,9 +202,9 @@ static int ecryptfs_open(struct inode *inode, struct file *file) | |||
202 | if ((ecryptfs_inode_to_private(inode)->lower_file->f_flags & O_ACCMODE) | 202 | if ((ecryptfs_inode_to_private(inode)->lower_file->f_flags & O_ACCMODE) |
203 | == O_RDONLY && (file->f_flags & O_ACCMODE) != O_RDONLY) { | 203 | == O_RDONLY && (file->f_flags & O_ACCMODE) != O_RDONLY) { |
204 | rc = -EPERM; | 204 | rc = -EPERM; |
205 | printk(KERN_WARNING "%s: Lower persistent file is RO; eCryptfs " | 205 | printk(KERN_WARNING "%s: Lower file is RO; eCryptfs " |
206 | "file must hence be opened RO\n", __func__); | 206 | "file must hence be opened RO\n", __func__); |
207 | goto out_free; | 207 | goto out_put; |
208 | } | 208 | } |
209 | ecryptfs_set_file_lower( | 209 | ecryptfs_set_file_lower( |
210 | file, ecryptfs_inode_to_private(inode)->lower_file); | 210 | file, ecryptfs_inode_to_private(inode)->lower_file); |
@@ -232,10 +232,11 @@ static int ecryptfs_open(struct inode *inode, struct file *file) | |||
232 | "Plaintext passthrough mode is not " | 232 | "Plaintext passthrough mode is not " |
233 | "enabled; returning -EIO\n"); | 233 | "enabled; returning -EIO\n"); |
234 | mutex_unlock(&crypt_stat->cs_mutex); | 234 | mutex_unlock(&crypt_stat->cs_mutex); |
235 | goto out_free; | 235 | goto out_put; |
236 | } | 236 | } |
237 | rc = 0; | 237 | rc = 0; |
238 | crypt_stat->flags &= ~(ECRYPTFS_ENCRYPTED); | 238 | crypt_stat->flags &= ~(ECRYPTFS_I_SIZE_INITIALIZED |
239 | | ECRYPTFS_ENCRYPTED); | ||
239 | mutex_unlock(&crypt_stat->cs_mutex); | 240 | mutex_unlock(&crypt_stat->cs_mutex); |
240 | goto out; | 241 | goto out; |
241 | } | 242 | } |
@@ -245,6 +246,8 @@ static int ecryptfs_open(struct inode *inode, struct file *file) | |||
245 | "[0x%.16lx] size: [0x%.16llx]\n", inode, inode->i_ino, | 246 | "[0x%.16lx] size: [0x%.16llx]\n", inode, inode->i_ino, |
246 | (unsigned long long)i_size_read(inode)); | 247 | (unsigned long long)i_size_read(inode)); |
247 | goto out; | 248 | goto out; |
249 | out_put: | ||
250 | ecryptfs_put_lower_file(inode); | ||
248 | out_free: | 251 | out_free: |
249 | kmem_cache_free(ecryptfs_file_info_cache, | 252 | kmem_cache_free(ecryptfs_file_info_cache, |
250 | ecryptfs_file_to_private(file)); | 253 | ecryptfs_file_to_private(file)); |
@@ -254,17 +257,13 @@ out: | |||
254 | 257 | ||
255 | static int ecryptfs_flush(struct file *file, fl_owner_t td) | 258 | static int ecryptfs_flush(struct file *file, fl_owner_t td) |
256 | { | 259 | { |
257 | int rc = 0; | 260 | return file->f_mode & FMODE_WRITE |
258 | struct file *lower_file = NULL; | 261 | ? filemap_write_and_wait(file->f_mapping) : 0; |
259 | |||
260 | lower_file = ecryptfs_file_to_lower(file); | ||
261 | if (lower_file->f_op && lower_file->f_op->flush) | ||
262 | rc = lower_file->f_op->flush(lower_file, td); | ||
263 | return rc; | ||
264 | } | 262 | } |
265 | 263 | ||
266 | static int ecryptfs_release(struct inode *inode, struct file *file) | 264 | static int ecryptfs_release(struct inode *inode, struct file *file) |
267 | { | 265 | { |
266 | ecryptfs_put_lower_file(inode); | ||
268 | kmem_cache_free(ecryptfs_file_info_cache, | 267 | kmem_cache_free(ecryptfs_file_info_cache, |
269 | ecryptfs_file_to_private(file)); | 268 | ecryptfs_file_to_private(file)); |
270 | return 0; | 269 | return 0; |
@@ -273,7 +272,14 @@ static int ecryptfs_release(struct inode *inode, struct file *file) | |||
273 | static int | 272 | static int |
274 | ecryptfs_fsync(struct file *file, int datasync) | 273 | ecryptfs_fsync(struct file *file, int datasync) |
275 | { | 274 | { |
276 | return vfs_fsync(ecryptfs_file_to_lower(file), datasync); | 275 | int rc = 0; |
276 | |||
277 | rc = generic_file_fsync(file, datasync); | ||
278 | if (rc) | ||
279 | goto out; | ||
280 | rc = vfs_fsync(ecryptfs_file_to_lower(file), datasync); | ||
281 | out: | ||
282 | return rc; | ||
277 | } | 283 | } |
278 | 284 | ||
279 | static int ecryptfs_fasync(int fd, struct file *file, int flag) | 285 | static int ecryptfs_fasync(int fd, struct file *file, int flag) |
diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c index b592938a84bc..4d4cc6a90cd5 100644 --- a/fs/ecryptfs/inode.c +++ b/fs/ecryptfs/inode.c | |||
@@ -143,26 +143,6 @@ out: | |||
143 | } | 143 | } |
144 | 144 | ||
145 | /** | 145 | /** |
146 | * grow_file | ||
147 | * @ecryptfs_dentry: the eCryptfs dentry | ||
148 | * | ||
149 | * This is the code which will grow the file to its correct size. | ||
150 | */ | ||
151 | static int grow_file(struct dentry *ecryptfs_dentry) | ||
152 | { | ||
153 | struct inode *ecryptfs_inode = ecryptfs_dentry->d_inode; | ||
154 | char zero_virt[] = { 0x00 }; | ||
155 | int rc = 0; | ||
156 | |||
157 | rc = ecryptfs_write(ecryptfs_inode, zero_virt, 0, 1); | ||
158 | i_size_write(ecryptfs_inode, 0); | ||
159 | rc = ecryptfs_write_inode_size_to_metadata(ecryptfs_inode); | ||
160 | ecryptfs_inode_to_private(ecryptfs_inode)->crypt_stat.flags |= | ||
161 | ECRYPTFS_NEW_FILE; | ||
162 | return rc; | ||
163 | } | ||
164 | |||
165 | /** | ||
166 | * ecryptfs_initialize_file | 146 | * ecryptfs_initialize_file |
167 | * | 147 | * |
168 | * Cause the file to be changed from a basic empty file to an ecryptfs | 148 | * Cause the file to be changed from a basic empty file to an ecryptfs |
@@ -181,7 +161,6 @@ static int ecryptfs_initialize_file(struct dentry *ecryptfs_dentry) | |||
181 | crypt_stat->flags &= ~(ECRYPTFS_ENCRYPTED); | 161 | crypt_stat->flags &= ~(ECRYPTFS_ENCRYPTED); |
182 | goto out; | 162 | goto out; |
183 | } | 163 | } |
184 | crypt_stat->flags |= ECRYPTFS_NEW_FILE; | ||
185 | ecryptfs_printk(KERN_DEBUG, "Initializing crypto context\n"); | 164 | ecryptfs_printk(KERN_DEBUG, "Initializing crypto context\n"); |
186 | rc = ecryptfs_new_file_context(ecryptfs_dentry); | 165 | rc = ecryptfs_new_file_context(ecryptfs_dentry); |
187 | if (rc) { | 166 | if (rc) { |
@@ -189,22 +168,18 @@ static int ecryptfs_initialize_file(struct dentry *ecryptfs_dentry) | |||
189 | "context; rc = [%d]\n", rc); | 168 | "context; rc = [%d]\n", rc); |
190 | goto out; | 169 | goto out; |
191 | } | 170 | } |
192 | rc = ecryptfs_init_persistent_file(ecryptfs_dentry); | 171 | rc = ecryptfs_get_lower_file(ecryptfs_dentry); |
193 | if (rc) { | 172 | if (rc) { |
194 | printk(KERN_ERR "%s: Error attempting to initialize " | 173 | printk(KERN_ERR "%s: Error attempting to initialize " |
195 | "the persistent file for the dentry with name " | 174 | "the lower file for the dentry with name " |
196 | "[%s]; rc = [%d]\n", __func__, | 175 | "[%s]; rc = [%d]\n", __func__, |
197 | ecryptfs_dentry->d_name.name, rc); | 176 | ecryptfs_dentry->d_name.name, rc); |
198 | goto out; | 177 | goto out; |
199 | } | 178 | } |
200 | rc = ecryptfs_write_metadata(ecryptfs_dentry); | 179 | rc = ecryptfs_write_metadata(ecryptfs_dentry); |
201 | if (rc) { | ||
202 | printk(KERN_ERR "Error writing headers; rc = [%d]\n", rc); | ||
203 | goto out; | ||
204 | } | ||
205 | rc = grow_file(ecryptfs_dentry); | ||
206 | if (rc) | 180 | if (rc) |
207 | printk(KERN_ERR "Error growing file; rc = [%d]\n", rc); | 181 | printk(KERN_ERR "Error writing headers; rc = [%d]\n", rc); |
182 | ecryptfs_put_lower_file(ecryptfs_dentry->d_inode); | ||
208 | out: | 183 | out: |
209 | return rc; | 184 | return rc; |
210 | } | 185 | } |
@@ -250,11 +225,9 @@ int ecryptfs_lookup_and_interpose_lower(struct dentry *ecryptfs_dentry, | |||
250 | struct dentry *lower_dir_dentry; | 225 | struct dentry *lower_dir_dentry; |
251 | struct vfsmount *lower_mnt; | 226 | struct vfsmount *lower_mnt; |
252 | struct inode *lower_inode; | 227 | struct inode *lower_inode; |
253 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat; | ||
254 | struct ecryptfs_crypt_stat *crypt_stat; | 228 | struct ecryptfs_crypt_stat *crypt_stat; |
255 | char *page_virt = NULL; | 229 | char *page_virt = NULL; |
256 | u64 file_size; | 230 | int put_lower = 0, rc = 0; |
257 | int rc = 0; | ||
258 | 231 | ||
259 | lower_dir_dentry = lower_dentry->d_parent; | 232 | lower_dir_dentry = lower_dentry->d_parent; |
260 | lower_mnt = mntget(ecryptfs_dentry_to_lower_mnt( | 233 | lower_mnt = mntget(ecryptfs_dentry_to_lower_mnt( |
@@ -301,14 +274,15 @@ int ecryptfs_lookup_and_interpose_lower(struct dentry *ecryptfs_dentry, | |||
301 | rc = -ENOMEM; | 274 | rc = -ENOMEM; |
302 | goto out; | 275 | goto out; |
303 | } | 276 | } |
304 | rc = ecryptfs_init_persistent_file(ecryptfs_dentry); | 277 | rc = ecryptfs_get_lower_file(ecryptfs_dentry); |
305 | if (rc) { | 278 | if (rc) { |
306 | printk(KERN_ERR "%s: Error attempting to initialize " | 279 | printk(KERN_ERR "%s: Error attempting to initialize " |
307 | "the persistent file for the dentry with name " | 280 | "the lower file for the dentry with name " |
308 | "[%s]; rc = [%d]\n", __func__, | 281 | "[%s]; rc = [%d]\n", __func__, |
309 | ecryptfs_dentry->d_name.name, rc); | 282 | ecryptfs_dentry->d_name.name, rc); |
310 | goto out_free_kmem; | 283 | goto out_free_kmem; |
311 | } | 284 | } |
285 | put_lower = 1; | ||
312 | crypt_stat = &ecryptfs_inode_to_private( | 286 | crypt_stat = &ecryptfs_inode_to_private( |
313 | ecryptfs_dentry->d_inode)->crypt_stat; | 287 | ecryptfs_dentry->d_inode)->crypt_stat; |
314 | /* TODO: lock for crypt_stat comparison */ | 288 | /* TODO: lock for crypt_stat comparison */ |
@@ -326,18 +300,7 @@ int ecryptfs_lookup_and_interpose_lower(struct dentry *ecryptfs_dentry, | |||
326 | } | 300 | } |
327 | crypt_stat->flags |= ECRYPTFS_METADATA_IN_XATTR; | 301 | crypt_stat->flags |= ECRYPTFS_METADATA_IN_XATTR; |
328 | } | 302 | } |
329 | mount_crypt_stat = &ecryptfs_superblock_to_private( | 303 | ecryptfs_i_size_init(page_virt, ecryptfs_dentry->d_inode); |
330 | ecryptfs_dentry->d_sb)->mount_crypt_stat; | ||
331 | if (mount_crypt_stat->flags & ECRYPTFS_ENCRYPTED_VIEW_ENABLED) { | ||
332 | if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR) | ||
333 | file_size = (crypt_stat->metadata_size | ||
334 | + i_size_read(lower_dentry->d_inode)); | ||
335 | else | ||
336 | file_size = i_size_read(lower_dentry->d_inode); | ||
337 | } else { | ||
338 | file_size = get_unaligned_be64(page_virt); | ||
339 | } | ||
340 | i_size_write(ecryptfs_dentry->d_inode, (loff_t)file_size); | ||
341 | out_free_kmem: | 304 | out_free_kmem: |
342 | kmem_cache_free(ecryptfs_header_cache_2, page_virt); | 305 | kmem_cache_free(ecryptfs_header_cache_2, page_virt); |
343 | goto out; | 306 | goto out; |
@@ -346,6 +309,8 @@ out_put: | |||
346 | mntput(lower_mnt); | 309 | mntput(lower_mnt); |
347 | d_drop(ecryptfs_dentry); | 310 | d_drop(ecryptfs_dentry); |
348 | out: | 311 | out: |
312 | if (put_lower) | ||
313 | ecryptfs_put_lower_file(ecryptfs_dentry->d_inode); | ||
349 | return rc; | 314 | return rc; |
350 | } | 315 | } |
351 | 316 | ||
@@ -562,8 +527,6 @@ static int ecryptfs_rmdir(struct inode *dir, struct dentry *dentry) | |||
562 | dget(lower_dentry); | 527 | dget(lower_dentry); |
563 | rc = vfs_rmdir(lower_dir_dentry->d_inode, lower_dentry); | 528 | rc = vfs_rmdir(lower_dir_dentry->d_inode, lower_dentry); |
564 | dput(lower_dentry); | 529 | dput(lower_dentry); |
565 | if (!rc) | ||
566 | d_delete(lower_dentry); | ||
567 | fsstack_copy_attr_times(dir, lower_dir_dentry->d_inode); | 530 | fsstack_copy_attr_times(dir, lower_dir_dentry->d_inode); |
568 | dir->i_nlink = lower_dir_dentry->d_inode->i_nlink; | 531 | dir->i_nlink = lower_dir_dentry->d_inode->i_nlink; |
569 | unlock_dir(lower_dir_dentry); | 532 | unlock_dir(lower_dir_dentry); |
@@ -634,8 +597,8 @@ ecryptfs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
634 | fsstack_copy_attr_all(old_dir, lower_old_dir_dentry->d_inode); | 597 | fsstack_copy_attr_all(old_dir, lower_old_dir_dentry->d_inode); |
635 | out_lock: | 598 | out_lock: |
636 | unlock_rename(lower_old_dir_dentry, lower_new_dir_dentry); | 599 | unlock_rename(lower_old_dir_dentry, lower_new_dir_dentry); |
637 | dput(lower_new_dentry->d_parent); | 600 | dput(lower_new_dir_dentry); |
638 | dput(lower_old_dentry->d_parent); | 601 | dput(lower_old_dir_dentry); |
639 | dput(lower_new_dentry); | 602 | dput(lower_new_dentry); |
640 | dput(lower_old_dentry); | 603 | dput(lower_old_dentry); |
641 | return rc; | 604 | return rc; |
@@ -783,8 +746,11 @@ static int truncate_upper(struct dentry *dentry, struct iattr *ia, | |||
783 | 746 | ||
784 | if (unlikely((ia->ia_size == i_size))) { | 747 | if (unlikely((ia->ia_size == i_size))) { |
785 | lower_ia->ia_valid &= ~ATTR_SIZE; | 748 | lower_ia->ia_valid &= ~ATTR_SIZE; |
786 | goto out; | 749 | return 0; |
787 | } | 750 | } |
751 | rc = ecryptfs_get_lower_file(dentry); | ||
752 | if (rc) | ||
753 | return rc; | ||
788 | crypt_stat = &ecryptfs_inode_to_private(dentry->d_inode)->crypt_stat; | 754 | crypt_stat = &ecryptfs_inode_to_private(dentry->d_inode)->crypt_stat; |
789 | /* Switch on growing or shrinking file */ | 755 | /* Switch on growing or shrinking file */ |
790 | if (ia->ia_size > i_size) { | 756 | if (ia->ia_size > i_size) { |
@@ -862,6 +828,7 @@ static int truncate_upper(struct dentry *dentry, struct iattr *ia, | |||
862 | lower_ia->ia_valid &= ~ATTR_SIZE; | 828 | lower_ia->ia_valid &= ~ATTR_SIZE; |
863 | } | 829 | } |
864 | out: | 830 | out: |
831 | ecryptfs_put_lower_file(inode); | ||
865 | return rc; | 832 | return rc; |
866 | } | 833 | } |
867 | 834 | ||
@@ -937,7 +904,13 @@ static int ecryptfs_setattr(struct dentry *dentry, struct iattr *ia) | |||
937 | 904 | ||
938 | mount_crypt_stat = &ecryptfs_superblock_to_private( | 905 | mount_crypt_stat = &ecryptfs_superblock_to_private( |
939 | dentry->d_sb)->mount_crypt_stat; | 906 | dentry->d_sb)->mount_crypt_stat; |
907 | rc = ecryptfs_get_lower_file(dentry); | ||
908 | if (rc) { | ||
909 | mutex_unlock(&crypt_stat->cs_mutex); | ||
910 | goto out; | ||
911 | } | ||
940 | rc = ecryptfs_read_metadata(dentry); | 912 | rc = ecryptfs_read_metadata(dentry); |
913 | ecryptfs_put_lower_file(inode); | ||
941 | if (rc) { | 914 | if (rc) { |
942 | if (!(mount_crypt_stat->flags | 915 | if (!(mount_crypt_stat->flags |
943 | & ECRYPTFS_PLAINTEXT_PASSTHROUGH_ENABLED)) { | 916 | & ECRYPTFS_PLAINTEXT_PASSTHROUGH_ENABLED)) { |
@@ -951,10 +924,17 @@ static int ecryptfs_setattr(struct dentry *dentry, struct iattr *ia) | |||
951 | goto out; | 924 | goto out; |
952 | } | 925 | } |
953 | rc = 0; | 926 | rc = 0; |
954 | crypt_stat->flags &= ~(ECRYPTFS_ENCRYPTED); | 927 | crypt_stat->flags &= ~(ECRYPTFS_I_SIZE_INITIALIZED |
928 | | ECRYPTFS_ENCRYPTED); | ||
955 | } | 929 | } |
956 | } | 930 | } |
957 | mutex_unlock(&crypt_stat->cs_mutex); | 931 | mutex_unlock(&crypt_stat->cs_mutex); |
932 | if (S_ISREG(inode->i_mode)) { | ||
933 | rc = filemap_write_and_wait(inode->i_mapping); | ||
934 | if (rc) | ||
935 | goto out; | ||
936 | fsstack_copy_attr_all(inode, lower_inode); | ||
937 | } | ||
958 | memcpy(&lower_ia, ia, sizeof(lower_ia)); | 938 | memcpy(&lower_ia, ia, sizeof(lower_ia)); |
959 | if (ia->ia_valid & ATTR_FILE) | 939 | if (ia->ia_valid & ATTR_FILE) |
960 | lower_ia.ia_file = ecryptfs_file_to_lower(ia->ia_file); | 940 | lower_ia.ia_file = ecryptfs_file_to_lower(ia->ia_file); |
diff --git a/fs/ecryptfs/keystore.c b/fs/ecryptfs/keystore.c index c1436cff6f2d..03e609c45012 100644 --- a/fs/ecryptfs/keystore.c +++ b/fs/ecryptfs/keystore.c | |||
@@ -65,6 +65,24 @@ static int process_request_key_err(long err_code) | |||
65 | return rc; | 65 | return rc; |
66 | } | 66 | } |
67 | 67 | ||
68 | static int process_find_global_auth_tok_for_sig_err(int err_code) | ||
69 | { | ||
70 | int rc = err_code; | ||
71 | |||
72 | switch (err_code) { | ||
73 | case -ENOENT: | ||
74 | ecryptfs_printk(KERN_WARNING, "Missing auth tok\n"); | ||
75 | break; | ||
76 | case -EINVAL: | ||
77 | ecryptfs_printk(KERN_WARNING, "Invalid auth tok\n"); | ||
78 | break; | ||
79 | default: | ||
80 | rc = process_request_key_err(err_code); | ||
81 | break; | ||
82 | } | ||
83 | return rc; | ||
84 | } | ||
85 | |||
68 | /** | 86 | /** |
69 | * ecryptfs_parse_packet_length | 87 | * ecryptfs_parse_packet_length |
70 | * @data: Pointer to memory containing length at offset | 88 | * @data: Pointer to memory containing length at offset |
@@ -403,27 +421,120 @@ out: | |||
403 | return rc; | 421 | return rc; |
404 | } | 422 | } |
405 | 423 | ||
424 | /** | ||
425 | * ecryptfs_verify_version | ||
426 | * @version: The version number to confirm | ||
427 | * | ||
428 | * Returns zero on good version; non-zero otherwise | ||
429 | */ | ||
430 | static int ecryptfs_verify_version(u16 version) | ||
431 | { | ||
432 | int rc = 0; | ||
433 | unsigned char major; | ||
434 | unsigned char minor; | ||
435 | |||
436 | major = ((version >> 8) & 0xFF); | ||
437 | minor = (version & 0xFF); | ||
438 | if (major != ECRYPTFS_VERSION_MAJOR) { | ||
439 | ecryptfs_printk(KERN_ERR, "Major version number mismatch. " | ||
440 | "Expected [%d]; got [%d]\n", | ||
441 | ECRYPTFS_VERSION_MAJOR, major); | ||
442 | rc = -EINVAL; | ||
443 | goto out; | ||
444 | } | ||
445 | if (minor != ECRYPTFS_VERSION_MINOR) { | ||
446 | ecryptfs_printk(KERN_ERR, "Minor version number mismatch. " | ||
447 | "Expected [%d]; got [%d]\n", | ||
448 | ECRYPTFS_VERSION_MINOR, minor); | ||
449 | rc = -EINVAL; | ||
450 | goto out; | ||
451 | } | ||
452 | out: | ||
453 | return rc; | ||
454 | } | ||
455 | |||
456 | /** | ||
457 | * ecryptfs_verify_auth_tok_from_key | ||
458 | * @auth_tok_key: key containing the authentication token | ||
459 | * @auth_tok: authentication token | ||
460 | * | ||
461 | * Returns zero on valid auth tok; -EINVAL otherwise | ||
462 | */ | ||
463 | static int | ||
464 | ecryptfs_verify_auth_tok_from_key(struct key *auth_tok_key, | ||
465 | struct ecryptfs_auth_tok **auth_tok) | ||
466 | { | ||
467 | int rc = 0; | ||
468 | |||
469 | (*auth_tok) = ecryptfs_get_key_payload_data(auth_tok_key); | ||
470 | if (ecryptfs_verify_version((*auth_tok)->version)) { | ||
471 | printk(KERN_ERR "Data structure version mismatch. Userspace " | ||
472 | "tools must match eCryptfs kernel module with major " | ||
473 | "version [%d] and minor version [%d]\n", | ||
474 | ECRYPTFS_VERSION_MAJOR, ECRYPTFS_VERSION_MINOR); | ||
475 | rc = -EINVAL; | ||
476 | goto out; | ||
477 | } | ||
478 | if ((*auth_tok)->token_type != ECRYPTFS_PASSWORD | ||
479 | && (*auth_tok)->token_type != ECRYPTFS_PRIVATE_KEY) { | ||
480 | printk(KERN_ERR "Invalid auth_tok structure " | ||
481 | "returned from key query\n"); | ||
482 | rc = -EINVAL; | ||
483 | goto out; | ||
484 | } | ||
485 | out: | ||
486 | return rc; | ||
487 | } | ||
488 | |||
406 | static int | 489 | static int |
407 | ecryptfs_find_global_auth_tok_for_sig( | 490 | ecryptfs_find_global_auth_tok_for_sig( |
408 | struct ecryptfs_global_auth_tok **global_auth_tok, | 491 | struct key **auth_tok_key, |
492 | struct ecryptfs_auth_tok **auth_tok, | ||
409 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat, char *sig) | 493 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat, char *sig) |
410 | { | 494 | { |
411 | struct ecryptfs_global_auth_tok *walker; | 495 | struct ecryptfs_global_auth_tok *walker; |
412 | int rc = 0; | 496 | int rc = 0; |
413 | 497 | ||
414 | (*global_auth_tok) = NULL; | 498 | (*auth_tok_key) = NULL; |
499 | (*auth_tok) = NULL; | ||
415 | mutex_lock(&mount_crypt_stat->global_auth_tok_list_mutex); | 500 | mutex_lock(&mount_crypt_stat->global_auth_tok_list_mutex); |
416 | list_for_each_entry(walker, | 501 | list_for_each_entry(walker, |
417 | &mount_crypt_stat->global_auth_tok_list, | 502 | &mount_crypt_stat->global_auth_tok_list, |
418 | mount_crypt_stat_list) { | 503 | mount_crypt_stat_list) { |
419 | if (memcmp(walker->sig, sig, ECRYPTFS_SIG_SIZE_HEX) == 0) { | 504 | if (memcmp(walker->sig, sig, ECRYPTFS_SIG_SIZE_HEX)) |
420 | rc = key_validate(walker->global_auth_tok_key); | 505 | continue; |
421 | if (!rc) | 506 | |
422 | (*global_auth_tok) = walker; | 507 | if (walker->flags & ECRYPTFS_AUTH_TOK_INVALID) { |
508 | rc = -EINVAL; | ||
423 | goto out; | 509 | goto out; |
424 | } | 510 | } |
511 | |||
512 | rc = key_validate(walker->global_auth_tok_key); | ||
513 | if (rc) { | ||
514 | if (rc == -EKEYEXPIRED) | ||
515 | goto out; | ||
516 | goto out_invalid_auth_tok; | ||
517 | } | ||
518 | |||
519 | down_write(&(walker->global_auth_tok_key->sem)); | ||
520 | rc = ecryptfs_verify_auth_tok_from_key( | ||
521 | walker->global_auth_tok_key, auth_tok); | ||
522 | if (rc) | ||
523 | goto out_invalid_auth_tok_unlock; | ||
524 | |||
525 | (*auth_tok_key) = walker->global_auth_tok_key; | ||
526 | key_get(*auth_tok_key); | ||
527 | goto out; | ||
425 | } | 528 | } |
426 | rc = -EINVAL; | 529 | rc = -ENOENT; |
530 | goto out; | ||
531 | out_invalid_auth_tok_unlock: | ||
532 | up_write(&(walker->global_auth_tok_key->sem)); | ||
533 | out_invalid_auth_tok: | ||
534 | printk(KERN_WARNING "Invalidating auth tok with sig = [%s]\n", sig); | ||
535 | walker->flags |= ECRYPTFS_AUTH_TOK_INVALID; | ||
536 | key_put(walker->global_auth_tok_key); | ||
537 | walker->global_auth_tok_key = NULL; | ||
427 | out: | 538 | out: |
428 | mutex_unlock(&mount_crypt_stat->global_auth_tok_list_mutex); | 539 | mutex_unlock(&mount_crypt_stat->global_auth_tok_list_mutex); |
429 | return rc; | 540 | return rc; |
@@ -451,14 +562,11 @@ ecryptfs_find_auth_tok_for_sig( | |||
451 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat, | 562 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat, |
452 | char *sig) | 563 | char *sig) |
453 | { | 564 | { |
454 | struct ecryptfs_global_auth_tok *global_auth_tok; | ||
455 | int rc = 0; | 565 | int rc = 0; |
456 | 566 | ||
457 | (*auth_tok_key) = NULL; | 567 | rc = ecryptfs_find_global_auth_tok_for_sig(auth_tok_key, auth_tok, |
458 | (*auth_tok) = NULL; | 568 | mount_crypt_stat, sig); |
459 | if (ecryptfs_find_global_auth_tok_for_sig(&global_auth_tok, | 569 | if (rc == -ENOENT) { |
460 | mount_crypt_stat, sig)) { | ||
461 | |||
462 | /* if the flag ECRYPTFS_GLOBAL_MOUNT_AUTH_TOK_ONLY is set in the | 570 | /* if the flag ECRYPTFS_GLOBAL_MOUNT_AUTH_TOK_ONLY is set in the |
463 | * mount_crypt_stat structure, we prevent to use auth toks that | 571 | * mount_crypt_stat structure, we prevent to use auth toks that |
464 | * are not inserted through the ecryptfs_add_global_auth_tok | 572 | * are not inserted through the ecryptfs_add_global_auth_tok |
@@ -470,8 +578,7 @@ ecryptfs_find_auth_tok_for_sig( | |||
470 | 578 | ||
471 | rc = ecryptfs_keyring_auth_tok_for_sig(auth_tok_key, auth_tok, | 579 | rc = ecryptfs_keyring_auth_tok_for_sig(auth_tok_key, auth_tok, |
472 | sig); | 580 | sig); |
473 | } else | 581 | } |
474 | (*auth_tok) = global_auth_tok->global_auth_tok; | ||
475 | return rc; | 582 | return rc; |
476 | } | 583 | } |
477 | 584 | ||
@@ -531,6 +638,16 @@ ecryptfs_write_tag_70_packet(char *dest, size_t *remaining_bytes, | |||
531 | } | 638 | } |
532 | s->desc.flags = CRYPTO_TFM_REQ_MAY_SLEEP; | 639 | s->desc.flags = CRYPTO_TFM_REQ_MAY_SLEEP; |
533 | (*packet_size) = 0; | 640 | (*packet_size) = 0; |
641 | rc = ecryptfs_find_auth_tok_for_sig( | ||
642 | &auth_tok_key, | ||
643 | &s->auth_tok, mount_crypt_stat, | ||
644 | mount_crypt_stat->global_default_fnek_sig); | ||
645 | if (rc) { | ||
646 | printk(KERN_ERR "%s: Error attempting to find auth tok for " | ||
647 | "fnek sig [%s]; rc = [%d]\n", __func__, | ||
648 | mount_crypt_stat->global_default_fnek_sig, rc); | ||
649 | goto out; | ||
650 | } | ||
534 | rc = ecryptfs_get_tfm_and_mutex_for_cipher_name( | 651 | rc = ecryptfs_get_tfm_and_mutex_for_cipher_name( |
535 | &s->desc.tfm, | 652 | &s->desc.tfm, |
536 | &s->tfm_mutex, mount_crypt_stat->global_default_fn_cipher_name); | 653 | &s->tfm_mutex, mount_crypt_stat->global_default_fn_cipher_name); |
@@ -616,16 +733,6 @@ ecryptfs_write_tag_70_packet(char *dest, size_t *remaining_bytes, | |||
616 | goto out_free_unlock; | 733 | goto out_free_unlock; |
617 | } | 734 | } |
618 | dest[s->i++] = s->cipher_code; | 735 | dest[s->i++] = s->cipher_code; |
619 | rc = ecryptfs_find_auth_tok_for_sig( | ||
620 | &auth_tok_key, | ||
621 | &s->auth_tok, mount_crypt_stat, | ||
622 | mount_crypt_stat->global_default_fnek_sig); | ||
623 | if (rc) { | ||
624 | printk(KERN_ERR "%s: Error attempting to find auth tok for " | ||
625 | "fnek sig [%s]; rc = [%d]\n", __func__, | ||
626 | mount_crypt_stat->global_default_fnek_sig, rc); | ||
627 | goto out_free_unlock; | ||
628 | } | ||
629 | /* TODO: Support other key modules than passphrase for | 736 | /* TODO: Support other key modules than passphrase for |
630 | * filename encryption */ | 737 | * filename encryption */ |
631 | if (s->auth_tok->token_type != ECRYPTFS_PASSWORD) { | 738 | if (s->auth_tok->token_type != ECRYPTFS_PASSWORD) { |
@@ -765,8 +872,10 @@ out_free_unlock: | |||
765 | out_unlock: | 872 | out_unlock: |
766 | mutex_unlock(s->tfm_mutex); | 873 | mutex_unlock(s->tfm_mutex); |
767 | out: | 874 | out: |
768 | if (auth_tok_key) | 875 | if (auth_tok_key) { |
876 | up_write(&(auth_tok_key->sem)); | ||
769 | key_put(auth_tok_key); | 877 | key_put(auth_tok_key); |
878 | } | ||
770 | kfree(s); | 879 | kfree(s); |
771 | return rc; | 880 | return rc; |
772 | } | 881 | } |
@@ -879,6 +988,15 @@ ecryptfs_parse_tag_70_packet(char **filename, size_t *filename_size, | |||
879 | __func__, s->cipher_code); | 988 | __func__, s->cipher_code); |
880 | goto out; | 989 | goto out; |
881 | } | 990 | } |
991 | rc = ecryptfs_find_auth_tok_for_sig(&auth_tok_key, | ||
992 | &s->auth_tok, mount_crypt_stat, | ||
993 | s->fnek_sig_hex); | ||
994 | if (rc) { | ||
995 | printk(KERN_ERR "%s: Error attempting to find auth tok for " | ||
996 | "fnek sig [%s]; rc = [%d]\n", __func__, s->fnek_sig_hex, | ||
997 | rc); | ||
998 | goto out; | ||
999 | } | ||
882 | rc = ecryptfs_get_tfm_and_mutex_for_cipher_name(&s->desc.tfm, | 1000 | rc = ecryptfs_get_tfm_and_mutex_for_cipher_name(&s->desc.tfm, |
883 | &s->tfm_mutex, | 1001 | &s->tfm_mutex, |
884 | s->cipher_string); | 1002 | s->cipher_string); |
@@ -925,15 +1043,6 @@ ecryptfs_parse_tag_70_packet(char **filename, size_t *filename_size, | |||
925 | * >= ECRYPTFS_MAX_IV_BYTES. */ | 1043 | * >= ECRYPTFS_MAX_IV_BYTES. */ |
926 | memset(s->iv, 0, ECRYPTFS_MAX_IV_BYTES); | 1044 | memset(s->iv, 0, ECRYPTFS_MAX_IV_BYTES); |
927 | s->desc.info = s->iv; | 1045 | s->desc.info = s->iv; |
928 | rc = ecryptfs_find_auth_tok_for_sig(&auth_tok_key, | ||
929 | &s->auth_tok, mount_crypt_stat, | ||
930 | s->fnek_sig_hex); | ||
931 | if (rc) { | ||
932 | printk(KERN_ERR "%s: Error attempting to find auth tok for " | ||
933 | "fnek sig [%s]; rc = [%d]\n", __func__, s->fnek_sig_hex, | ||
934 | rc); | ||
935 | goto out_free_unlock; | ||
936 | } | ||
937 | /* TODO: Support other key modules than passphrase for | 1046 | /* TODO: Support other key modules than passphrase for |
938 | * filename encryption */ | 1047 | * filename encryption */ |
939 | if (s->auth_tok->token_type != ECRYPTFS_PASSWORD) { | 1048 | if (s->auth_tok->token_type != ECRYPTFS_PASSWORD) { |
@@ -1002,8 +1111,10 @@ out: | |||
1002 | (*filename_size) = 0; | 1111 | (*filename_size) = 0; |
1003 | (*filename) = NULL; | 1112 | (*filename) = NULL; |
1004 | } | 1113 | } |
1005 | if (auth_tok_key) | 1114 | if (auth_tok_key) { |
1115 | up_write(&(auth_tok_key->sem)); | ||
1006 | key_put(auth_tok_key); | 1116 | key_put(auth_tok_key); |
1117 | } | ||
1007 | kfree(s); | 1118 | kfree(s); |
1008 | return rc; | 1119 | return rc; |
1009 | } | 1120 | } |
@@ -1520,38 +1631,6 @@ out: | |||
1520 | return rc; | 1631 | return rc; |
1521 | } | 1632 | } |
1522 | 1633 | ||
1523 | /** | ||
1524 | * ecryptfs_verify_version | ||
1525 | * @version: The version number to confirm | ||
1526 | * | ||
1527 | * Returns zero on good version; non-zero otherwise | ||
1528 | */ | ||
1529 | static int ecryptfs_verify_version(u16 version) | ||
1530 | { | ||
1531 | int rc = 0; | ||
1532 | unsigned char major; | ||
1533 | unsigned char minor; | ||
1534 | |||
1535 | major = ((version >> 8) & 0xFF); | ||
1536 | minor = (version & 0xFF); | ||
1537 | if (major != ECRYPTFS_VERSION_MAJOR) { | ||
1538 | ecryptfs_printk(KERN_ERR, "Major version number mismatch. " | ||
1539 | "Expected [%d]; got [%d]\n", | ||
1540 | ECRYPTFS_VERSION_MAJOR, major); | ||
1541 | rc = -EINVAL; | ||
1542 | goto out; | ||
1543 | } | ||
1544 | if (minor != ECRYPTFS_VERSION_MINOR) { | ||
1545 | ecryptfs_printk(KERN_ERR, "Minor version number mismatch. " | ||
1546 | "Expected [%d]; got [%d]\n", | ||
1547 | ECRYPTFS_VERSION_MINOR, minor); | ||
1548 | rc = -EINVAL; | ||
1549 | goto out; | ||
1550 | } | ||
1551 | out: | ||
1552 | return rc; | ||
1553 | } | ||
1554 | |||
1555 | int ecryptfs_keyring_auth_tok_for_sig(struct key **auth_tok_key, | 1634 | int ecryptfs_keyring_auth_tok_for_sig(struct key **auth_tok_key, |
1556 | struct ecryptfs_auth_tok **auth_tok, | 1635 | struct ecryptfs_auth_tok **auth_tok, |
1557 | char *sig) | 1636 | char *sig) |
@@ -1563,31 +1642,16 @@ int ecryptfs_keyring_auth_tok_for_sig(struct key **auth_tok_key, | |||
1563 | printk(KERN_ERR "Could not find key with description: [%s]\n", | 1642 | printk(KERN_ERR "Could not find key with description: [%s]\n", |
1564 | sig); | 1643 | sig); |
1565 | rc = process_request_key_err(PTR_ERR(*auth_tok_key)); | 1644 | rc = process_request_key_err(PTR_ERR(*auth_tok_key)); |
1645 | (*auth_tok_key) = NULL; | ||
1566 | goto out; | 1646 | goto out; |
1567 | } | 1647 | } |
1568 | (*auth_tok) = ecryptfs_get_key_payload_data(*auth_tok_key); | 1648 | down_write(&(*auth_tok_key)->sem); |
1569 | if (ecryptfs_verify_version((*auth_tok)->version)) { | 1649 | rc = ecryptfs_verify_auth_tok_from_key(*auth_tok_key, auth_tok); |
1570 | printk(KERN_ERR | ||
1571 | "Data structure version mismatch. " | ||
1572 | "Userspace tools must match eCryptfs " | ||
1573 | "kernel module with major version [%d] " | ||
1574 | "and minor version [%d]\n", | ||
1575 | ECRYPTFS_VERSION_MAJOR, | ||
1576 | ECRYPTFS_VERSION_MINOR); | ||
1577 | rc = -EINVAL; | ||
1578 | goto out_release_key; | ||
1579 | } | ||
1580 | if ((*auth_tok)->token_type != ECRYPTFS_PASSWORD | ||
1581 | && (*auth_tok)->token_type != ECRYPTFS_PRIVATE_KEY) { | ||
1582 | printk(KERN_ERR "Invalid auth_tok structure " | ||
1583 | "returned from key query\n"); | ||
1584 | rc = -EINVAL; | ||
1585 | goto out_release_key; | ||
1586 | } | ||
1587 | out_release_key: | ||
1588 | if (rc) { | 1650 | if (rc) { |
1651 | up_write(&(*auth_tok_key)->sem); | ||
1589 | key_put(*auth_tok_key); | 1652 | key_put(*auth_tok_key); |
1590 | (*auth_tok_key) = NULL; | 1653 | (*auth_tok_key) = NULL; |
1654 | goto out; | ||
1591 | } | 1655 | } |
1592 | out: | 1656 | out: |
1593 | return rc; | 1657 | return rc; |
@@ -1809,6 +1873,7 @@ int ecryptfs_parse_packet_set(struct ecryptfs_crypt_stat *crypt_stat, | |||
1809 | find_next_matching_auth_tok: | 1873 | find_next_matching_auth_tok: |
1810 | found_auth_tok = 0; | 1874 | found_auth_tok = 0; |
1811 | if (auth_tok_key) { | 1875 | if (auth_tok_key) { |
1876 | up_write(&(auth_tok_key->sem)); | ||
1812 | key_put(auth_tok_key); | 1877 | key_put(auth_tok_key); |
1813 | auth_tok_key = NULL; | 1878 | auth_tok_key = NULL; |
1814 | } | 1879 | } |
@@ -1895,8 +1960,10 @@ found_matching_auth_tok: | |||
1895 | out_wipe_list: | 1960 | out_wipe_list: |
1896 | wipe_auth_tok_list(&auth_tok_list); | 1961 | wipe_auth_tok_list(&auth_tok_list); |
1897 | out: | 1962 | out: |
1898 | if (auth_tok_key) | 1963 | if (auth_tok_key) { |
1964 | up_write(&(auth_tok_key->sem)); | ||
1899 | key_put(auth_tok_key); | 1965 | key_put(auth_tok_key); |
1966 | } | ||
1900 | return rc; | 1967 | return rc; |
1901 | } | 1968 | } |
1902 | 1969 | ||
@@ -2324,7 +2391,7 @@ ecryptfs_generate_key_packet_set(char *dest_base, | |||
2324 | size_t max) | 2391 | size_t max) |
2325 | { | 2392 | { |
2326 | struct ecryptfs_auth_tok *auth_tok; | 2393 | struct ecryptfs_auth_tok *auth_tok; |
2327 | struct ecryptfs_global_auth_tok *global_auth_tok; | 2394 | struct key *auth_tok_key = NULL; |
2328 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat = | 2395 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat = |
2329 | &ecryptfs_superblock_to_private( | 2396 | &ecryptfs_superblock_to_private( |
2330 | ecryptfs_dentry->d_sb)->mount_crypt_stat; | 2397 | ecryptfs_dentry->d_sb)->mount_crypt_stat; |
@@ -2343,21 +2410,16 @@ ecryptfs_generate_key_packet_set(char *dest_base, | |||
2343 | list_for_each_entry(key_sig, &crypt_stat->keysig_list, | 2410 | list_for_each_entry(key_sig, &crypt_stat->keysig_list, |
2344 | crypt_stat_list) { | 2411 | crypt_stat_list) { |
2345 | memset(key_rec, 0, sizeof(*key_rec)); | 2412 | memset(key_rec, 0, sizeof(*key_rec)); |
2346 | rc = ecryptfs_find_global_auth_tok_for_sig(&global_auth_tok, | 2413 | rc = ecryptfs_find_global_auth_tok_for_sig(&auth_tok_key, |
2414 | &auth_tok, | ||
2347 | mount_crypt_stat, | 2415 | mount_crypt_stat, |
2348 | key_sig->keysig); | 2416 | key_sig->keysig); |
2349 | if (rc) { | 2417 | if (rc) { |
2350 | printk(KERN_ERR "Error attempting to get the global " | 2418 | printk(KERN_WARNING "Unable to retrieve auth tok with " |
2351 | "auth_tok; rc = [%d]\n", rc); | 2419 | "sig = [%s]\n", key_sig->keysig); |
2420 | rc = process_find_global_auth_tok_for_sig_err(rc); | ||
2352 | goto out_free; | 2421 | goto out_free; |
2353 | } | 2422 | } |
2354 | if (global_auth_tok->flags & ECRYPTFS_AUTH_TOK_INVALID) { | ||
2355 | printk(KERN_WARNING | ||
2356 | "Skipping invalid auth tok with sig = [%s]\n", | ||
2357 | global_auth_tok->sig); | ||
2358 | continue; | ||
2359 | } | ||
2360 | auth_tok = global_auth_tok->global_auth_tok; | ||
2361 | if (auth_tok->token_type == ECRYPTFS_PASSWORD) { | 2423 | if (auth_tok->token_type == ECRYPTFS_PASSWORD) { |
2362 | rc = write_tag_3_packet((dest_base + (*len)), | 2424 | rc = write_tag_3_packet((dest_base + (*len)), |
2363 | &max, auth_tok, | 2425 | &max, auth_tok, |
@@ -2395,6 +2457,9 @@ ecryptfs_generate_key_packet_set(char *dest_base, | |||
2395 | rc = -EINVAL; | 2457 | rc = -EINVAL; |
2396 | goto out_free; | 2458 | goto out_free; |
2397 | } | 2459 | } |
2460 | up_write(&(auth_tok_key->sem)); | ||
2461 | key_put(auth_tok_key); | ||
2462 | auth_tok_key = NULL; | ||
2398 | } | 2463 | } |
2399 | if (likely(max > 0)) { | 2464 | if (likely(max > 0)) { |
2400 | dest_base[(*len)] = 0x00; | 2465 | dest_base[(*len)] = 0x00; |
@@ -2407,6 +2472,11 @@ out_free: | |||
2407 | out: | 2472 | out: |
2408 | if (rc) | 2473 | if (rc) |
2409 | (*len) = 0; | 2474 | (*len) = 0; |
2475 | if (auth_tok_key) { | ||
2476 | up_write(&(auth_tok_key->sem)); | ||
2477 | key_put(auth_tok_key); | ||
2478 | } | ||
2479 | |||
2410 | mutex_unlock(&crypt_stat->keysig_list_mutex); | 2480 | mutex_unlock(&crypt_stat->keysig_list_mutex); |
2411 | return rc; | 2481 | return rc; |
2412 | } | 2482 | } |
@@ -2424,6 +2494,7 @@ int ecryptfs_add_keysig(struct ecryptfs_crypt_stat *crypt_stat, char *sig) | |||
2424 | return -ENOMEM; | 2494 | return -ENOMEM; |
2425 | } | 2495 | } |
2426 | memcpy(new_key_sig->keysig, sig, ECRYPTFS_SIG_SIZE_HEX); | 2496 | memcpy(new_key_sig->keysig, sig, ECRYPTFS_SIG_SIZE_HEX); |
2497 | new_key_sig->keysig[ECRYPTFS_SIG_SIZE_HEX] = '\0'; | ||
2427 | /* Caller must hold keysig_list_mutex */ | 2498 | /* Caller must hold keysig_list_mutex */ |
2428 | list_add(&new_key_sig->crypt_stat_list, &crypt_stat->keysig_list); | 2499 | list_add(&new_key_sig->crypt_stat_list, &crypt_stat->keysig_list); |
2429 | 2500 | ||
@@ -2453,7 +2524,6 @@ ecryptfs_add_global_auth_tok(struct ecryptfs_mount_crypt_stat *mount_crypt_stat, | |||
2453 | mutex_lock(&mount_crypt_stat->global_auth_tok_list_mutex); | 2524 | mutex_lock(&mount_crypt_stat->global_auth_tok_list_mutex); |
2454 | list_add(&new_auth_tok->mount_crypt_stat_list, | 2525 | list_add(&new_auth_tok->mount_crypt_stat_list, |
2455 | &mount_crypt_stat->global_auth_tok_list); | 2526 | &mount_crypt_stat->global_auth_tok_list); |
2456 | mount_crypt_stat->num_global_auth_toks++; | ||
2457 | mutex_unlock(&mount_crypt_stat->global_auth_tok_list_mutex); | 2527 | mutex_unlock(&mount_crypt_stat->global_auth_tok_list_mutex); |
2458 | out: | 2528 | out: |
2459 | return rc; | 2529 | return rc; |
diff --git a/fs/ecryptfs/kthread.c b/fs/ecryptfs/kthread.c index 0851ab6980f5..69f994a7d524 100644 --- a/fs/ecryptfs/kthread.c +++ b/fs/ecryptfs/kthread.c | |||
@@ -44,7 +44,7 @@ static struct task_struct *ecryptfs_kthread; | |||
44 | * @ignored: ignored | 44 | * @ignored: ignored |
45 | * | 45 | * |
46 | * The eCryptfs kernel thread that has the responsibility of getting | 46 | * The eCryptfs kernel thread that has the responsibility of getting |
47 | * the lower persistent file with RW permissions. | 47 | * the lower file with RW permissions. |
48 | * | 48 | * |
49 | * Returns zero on success; non-zero otherwise | 49 | * Returns zero on success; non-zero otherwise |
50 | */ | 50 | */ |
@@ -141,8 +141,8 @@ int ecryptfs_privileged_open(struct file **lower_file, | |||
141 | int rc = 0; | 141 | int rc = 0; |
142 | 142 | ||
143 | /* Corresponding dput() and mntput() are done when the | 143 | /* Corresponding dput() and mntput() are done when the |
144 | * persistent file is fput() when the eCryptfs inode is | 144 | * lower file is fput() when all eCryptfs files for the inode are |
145 | * destroyed. */ | 145 | * released. */ |
146 | dget(lower_dentry); | 146 | dget(lower_dentry); |
147 | mntget(lower_mnt); | 147 | mntget(lower_mnt); |
148 | flags |= IS_RDONLY(lower_dentry->d_inode) ? O_RDONLY : O_RDWR; | 148 | flags |= IS_RDONLY(lower_dentry->d_inode) ? O_RDONLY : O_RDWR; |
diff --git a/fs/ecryptfs/main.c b/fs/ecryptfs/main.c index 758323a0f09a..89b93389af8e 100644 --- a/fs/ecryptfs/main.c +++ b/fs/ecryptfs/main.c | |||
@@ -96,7 +96,7 @@ void __ecryptfs_printk(const char *fmt, ...) | |||
96 | } | 96 | } |
97 | 97 | ||
98 | /** | 98 | /** |
99 | * ecryptfs_init_persistent_file | 99 | * ecryptfs_init_lower_file |
100 | * @ecryptfs_dentry: Fully initialized eCryptfs dentry object, with | 100 | * @ecryptfs_dentry: Fully initialized eCryptfs dentry object, with |
101 | * the lower dentry and the lower mount set | 101 | * the lower dentry and the lower mount set |
102 | * | 102 | * |
@@ -104,44 +104,70 @@ void __ecryptfs_printk(const char *fmt, ...) | |||
104 | * inode. All I/O operations to the lower inode occur through that | 104 | * inode. All I/O operations to the lower inode occur through that |
105 | * file. When the first eCryptfs dentry that interposes with the first | 105 | * file. When the first eCryptfs dentry that interposes with the first |
106 | * lower dentry for that inode is created, this function creates the | 106 | * lower dentry for that inode is created, this function creates the |
107 | * persistent file struct and associates it with the eCryptfs | 107 | * lower file struct and associates it with the eCryptfs |
108 | * inode. When the eCryptfs inode is destroyed, the file is closed. | 108 | * inode. When all eCryptfs files associated with the inode are released, the |
109 | * file is closed. | ||
109 | * | 110 | * |
110 | * The persistent file will be opened with read/write permissions, if | 111 | * The lower file will be opened with read/write permissions, if |
111 | * possible. Otherwise, it is opened read-only. | 112 | * possible. Otherwise, it is opened read-only. |
112 | * | 113 | * |
113 | * This function does nothing if a lower persistent file is already | 114 | * This function does nothing if a lower file is already |
114 | * associated with the eCryptfs inode. | 115 | * associated with the eCryptfs inode. |
115 | * | 116 | * |
116 | * Returns zero on success; non-zero otherwise | 117 | * Returns zero on success; non-zero otherwise |
117 | */ | 118 | */ |
118 | int ecryptfs_init_persistent_file(struct dentry *ecryptfs_dentry) | 119 | static int ecryptfs_init_lower_file(struct dentry *dentry, |
120 | struct file **lower_file) | ||
119 | { | 121 | { |
120 | const struct cred *cred = current_cred(); | 122 | const struct cred *cred = current_cred(); |
123 | struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry); | ||
124 | struct vfsmount *lower_mnt = ecryptfs_dentry_to_lower_mnt(dentry); | ||
125 | int rc; | ||
126 | |||
127 | rc = ecryptfs_privileged_open(lower_file, lower_dentry, lower_mnt, | ||
128 | cred); | ||
129 | if (rc) { | ||
130 | printk(KERN_ERR "Error opening lower file " | ||
131 | "for lower_dentry [0x%p] and lower_mnt [0x%p]; " | ||
132 | "rc = [%d]\n", lower_dentry, lower_mnt, rc); | ||
133 | (*lower_file) = NULL; | ||
134 | } | ||
135 | return rc; | ||
136 | } | ||
137 | |||
138 | int ecryptfs_get_lower_file(struct dentry *dentry) | ||
139 | { | ||
121 | struct ecryptfs_inode_info *inode_info = | 140 | struct ecryptfs_inode_info *inode_info = |
122 | ecryptfs_inode_to_private(ecryptfs_dentry->d_inode); | 141 | ecryptfs_inode_to_private(dentry->d_inode); |
123 | int rc = 0; | 142 | int count, rc = 0; |
124 | 143 | ||
125 | mutex_lock(&inode_info->lower_file_mutex); | 144 | mutex_lock(&inode_info->lower_file_mutex); |
126 | if (!inode_info->lower_file) { | 145 | count = atomic_inc_return(&inode_info->lower_file_count); |
127 | struct dentry *lower_dentry; | 146 | if (WARN_ON_ONCE(count < 1)) |
128 | struct vfsmount *lower_mnt = | 147 | rc = -EINVAL; |
129 | ecryptfs_dentry_to_lower_mnt(ecryptfs_dentry); | 148 | else if (count == 1) { |
130 | 149 | rc = ecryptfs_init_lower_file(dentry, | |
131 | lower_dentry = ecryptfs_dentry_to_lower(ecryptfs_dentry); | 150 | &inode_info->lower_file); |
132 | rc = ecryptfs_privileged_open(&inode_info->lower_file, | 151 | if (rc) |
133 | lower_dentry, lower_mnt, cred); | 152 | atomic_set(&inode_info->lower_file_count, 0); |
134 | if (rc) { | ||
135 | printk(KERN_ERR "Error opening lower persistent file " | ||
136 | "for lower_dentry [0x%p] and lower_mnt [0x%p]; " | ||
137 | "rc = [%d]\n", lower_dentry, lower_mnt, rc); | ||
138 | inode_info->lower_file = NULL; | ||
139 | } | ||
140 | } | 153 | } |
141 | mutex_unlock(&inode_info->lower_file_mutex); | 154 | mutex_unlock(&inode_info->lower_file_mutex); |
142 | return rc; | 155 | return rc; |
143 | } | 156 | } |
144 | 157 | ||
158 | void ecryptfs_put_lower_file(struct inode *inode) | ||
159 | { | ||
160 | struct ecryptfs_inode_info *inode_info; | ||
161 | |||
162 | inode_info = ecryptfs_inode_to_private(inode); | ||
163 | if (atomic_dec_and_mutex_lock(&inode_info->lower_file_count, | ||
164 | &inode_info->lower_file_mutex)) { | ||
165 | fput(inode_info->lower_file); | ||
166 | inode_info->lower_file = NULL; | ||
167 | mutex_unlock(&inode_info->lower_file_mutex); | ||
168 | } | ||
169 | } | ||
170 | |||
145 | static struct inode *ecryptfs_get_inode(struct inode *lower_inode, | 171 | static struct inode *ecryptfs_get_inode(struct inode *lower_inode, |
146 | struct super_block *sb) | 172 | struct super_block *sb) |
147 | { | 173 | { |
@@ -241,14 +267,14 @@ static int ecryptfs_init_global_auth_toks( | |||
241 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat) | 267 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat) |
242 | { | 268 | { |
243 | struct ecryptfs_global_auth_tok *global_auth_tok; | 269 | struct ecryptfs_global_auth_tok *global_auth_tok; |
270 | struct ecryptfs_auth_tok *auth_tok; | ||
244 | int rc = 0; | 271 | int rc = 0; |
245 | 272 | ||
246 | list_for_each_entry(global_auth_tok, | 273 | list_for_each_entry(global_auth_tok, |
247 | &mount_crypt_stat->global_auth_tok_list, | 274 | &mount_crypt_stat->global_auth_tok_list, |
248 | mount_crypt_stat_list) { | 275 | mount_crypt_stat_list) { |
249 | rc = ecryptfs_keyring_auth_tok_for_sig( | 276 | rc = ecryptfs_keyring_auth_tok_for_sig( |
250 | &global_auth_tok->global_auth_tok_key, | 277 | &global_auth_tok->global_auth_tok_key, &auth_tok, |
251 | &global_auth_tok->global_auth_tok, | ||
252 | global_auth_tok->sig); | 278 | global_auth_tok->sig); |
253 | if (rc) { | 279 | if (rc) { |
254 | printk(KERN_ERR "Could not find valid key in user " | 280 | printk(KERN_ERR "Could not find valid key in user " |
@@ -256,8 +282,10 @@ static int ecryptfs_init_global_auth_toks( | |||
256 | "option: [%s]\n", global_auth_tok->sig); | 282 | "option: [%s]\n", global_auth_tok->sig); |
257 | global_auth_tok->flags |= ECRYPTFS_AUTH_TOK_INVALID; | 283 | global_auth_tok->flags |= ECRYPTFS_AUTH_TOK_INVALID; |
258 | goto out; | 284 | goto out; |
259 | } else | 285 | } else { |
260 | global_auth_tok->flags &= ~ECRYPTFS_AUTH_TOK_INVALID; | 286 | global_auth_tok->flags &= ~ECRYPTFS_AUTH_TOK_INVALID; |
287 | up_write(&(global_auth_tok->global_auth_tok_key)->sem); | ||
288 | } | ||
261 | } | 289 | } |
262 | out: | 290 | out: |
263 | return rc; | 291 | return rc; |
@@ -276,7 +304,7 @@ static void ecryptfs_init_mount_crypt_stat( | |||
276 | /** | 304 | /** |
277 | * ecryptfs_parse_options | 305 | * ecryptfs_parse_options |
278 | * @sb: The ecryptfs super block | 306 | * @sb: The ecryptfs super block |
279 | * @options: The options pased to the kernel | 307 | * @options: The options passed to the kernel |
280 | * | 308 | * |
281 | * Parse mount options: | 309 | * Parse mount options: |
282 | * debug=N - ecryptfs_verbosity level for debug output | 310 | * debug=N - ecryptfs_verbosity level for debug output |
@@ -840,7 +868,7 @@ static int __init ecryptfs_init(void) | |||
840 | } | 868 | } |
841 | rc = ecryptfs_init_messaging(); | 869 | rc = ecryptfs_init_messaging(); |
842 | if (rc) { | 870 | if (rc) { |
843 | printk(KERN_ERR "Failure occured while attempting to " | 871 | printk(KERN_ERR "Failure occurred while attempting to " |
844 | "initialize the communications channel to " | 872 | "initialize the communications channel to " |
845 | "ecryptfsd\n"); | 873 | "ecryptfsd\n"); |
846 | goto out_destroy_kthread; | 874 | goto out_destroy_kthread; |
diff --git a/fs/ecryptfs/mmap.c b/fs/ecryptfs/mmap.c index cc64fca89f8d..6a44148c5fb9 100644 --- a/fs/ecryptfs/mmap.c +++ b/fs/ecryptfs/mmap.c | |||
@@ -62,6 +62,18 @@ static int ecryptfs_writepage(struct page *page, struct writeback_control *wbc) | |||
62 | { | 62 | { |
63 | int rc; | 63 | int rc; |
64 | 64 | ||
65 | /* | ||
66 | * Refuse to write the page out if we are called from reclaim context | ||
67 | * since our writepage() path may potentially allocate memory when | ||
68 | * calling into the lower fs vfs_write() which may in turn invoke | ||
69 | * us again. | ||
70 | */ | ||
71 | if (current->flags & PF_MEMALLOC) { | ||
72 | redirty_page_for_writepage(wbc, page); | ||
73 | rc = 0; | ||
74 | goto out; | ||
75 | } | ||
76 | |||
65 | rc = ecryptfs_encrypt_page(page); | 77 | rc = ecryptfs_encrypt_page(page); |
66 | if (rc) { | 78 | if (rc) { |
67 | ecryptfs_printk(KERN_WARNING, "Error encrypting " | 79 | ecryptfs_printk(KERN_WARNING, "Error encrypting " |
@@ -70,8 +82,8 @@ static int ecryptfs_writepage(struct page *page, struct writeback_control *wbc) | |||
70 | goto out; | 82 | goto out; |
71 | } | 83 | } |
72 | SetPageUptodate(page); | 84 | SetPageUptodate(page); |
73 | unlock_page(page); | ||
74 | out: | 85 | out: |
86 | unlock_page(page); | ||
75 | return rc; | 87 | return rc; |
76 | } | 88 | } |
77 | 89 | ||
@@ -193,11 +205,7 @@ static int ecryptfs_readpage(struct file *file, struct page *page) | |||
193 | &ecryptfs_inode_to_private(page->mapping->host)->crypt_stat; | 205 | &ecryptfs_inode_to_private(page->mapping->host)->crypt_stat; |
194 | int rc = 0; | 206 | int rc = 0; |
195 | 207 | ||
196 | if (!crypt_stat | 208 | if (!crypt_stat || !(crypt_stat->flags & ECRYPTFS_ENCRYPTED)) { |
197 | || !(crypt_stat->flags & ECRYPTFS_ENCRYPTED) | ||
198 | || (crypt_stat->flags & ECRYPTFS_NEW_FILE)) { | ||
199 | ecryptfs_printk(KERN_DEBUG, | ||
200 | "Passing through unencrypted page\n"); | ||
201 | rc = ecryptfs_read_lower_page_segment(page, page->index, 0, | 209 | rc = ecryptfs_read_lower_page_segment(page, page->index, 0, |
202 | PAGE_CACHE_SIZE, | 210 | PAGE_CACHE_SIZE, |
203 | page->mapping->host); | 211 | page->mapping->host); |
@@ -295,8 +303,7 @@ static int ecryptfs_write_begin(struct file *file, | |||
295 | struct ecryptfs_crypt_stat *crypt_stat = | 303 | struct ecryptfs_crypt_stat *crypt_stat = |
296 | &ecryptfs_inode_to_private(mapping->host)->crypt_stat; | 304 | &ecryptfs_inode_to_private(mapping->host)->crypt_stat; |
297 | 305 | ||
298 | if (!(crypt_stat->flags & ECRYPTFS_ENCRYPTED) | 306 | if (!(crypt_stat->flags & ECRYPTFS_ENCRYPTED)) { |
299 | || (crypt_stat->flags & ECRYPTFS_NEW_FILE)) { | ||
300 | rc = ecryptfs_read_lower_page_segment( | 307 | rc = ecryptfs_read_lower_page_segment( |
301 | page, index, 0, PAGE_CACHE_SIZE, mapping->host); | 308 | page, index, 0, PAGE_CACHE_SIZE, mapping->host); |
302 | if (rc) { | 309 | if (rc) { |
@@ -374,6 +381,11 @@ static int ecryptfs_write_begin(struct file *file, | |||
374 | && (pos != 0)) | 381 | && (pos != 0)) |
375 | zero_user(page, 0, PAGE_CACHE_SIZE); | 382 | zero_user(page, 0, PAGE_CACHE_SIZE); |
376 | out: | 383 | out: |
384 | if (unlikely(rc)) { | ||
385 | unlock_page(page); | ||
386 | page_cache_release(page); | ||
387 | *pagep = NULL; | ||
388 | } | ||
377 | return rc; | 389 | return rc; |
378 | } | 390 | } |
379 | 391 | ||
@@ -486,13 +498,8 @@ static int ecryptfs_write_end(struct file *file, | |||
486 | struct ecryptfs_crypt_stat *crypt_stat = | 498 | struct ecryptfs_crypt_stat *crypt_stat = |
487 | &ecryptfs_inode_to_private(ecryptfs_inode)->crypt_stat; | 499 | &ecryptfs_inode_to_private(ecryptfs_inode)->crypt_stat; |
488 | int rc; | 500 | int rc; |
501 | int need_unlock_page = 1; | ||
489 | 502 | ||
490 | if (crypt_stat->flags & ECRYPTFS_NEW_FILE) { | ||
491 | ecryptfs_printk(KERN_DEBUG, "ECRYPTFS_NEW_FILE flag set in " | ||
492 | "crypt_stat at memory location [%p]\n", crypt_stat); | ||
493 | crypt_stat->flags &= ~(ECRYPTFS_NEW_FILE); | ||
494 | } else | ||
495 | ecryptfs_printk(KERN_DEBUG, "Not a new file\n"); | ||
496 | ecryptfs_printk(KERN_DEBUG, "Calling fill_zeros_to_end_of_page" | 503 | ecryptfs_printk(KERN_DEBUG, "Calling fill_zeros_to_end_of_page" |
497 | "(page w/ index = [0x%.16lx], to = [%d])\n", index, to); | 504 | "(page w/ index = [0x%.16lx], to = [%d])\n", index, to); |
498 | if (!(crypt_stat->flags & ECRYPTFS_ENCRYPTED)) { | 505 | if (!(crypt_stat->flags & ECRYPTFS_ENCRYPTED)) { |
@@ -512,26 +519,26 @@ static int ecryptfs_write_end(struct file *file, | |||
512 | "zeros in page with index = [0x%.16lx]\n", index); | 519 | "zeros in page with index = [0x%.16lx]\n", index); |
513 | goto out; | 520 | goto out; |
514 | } | 521 | } |
515 | rc = ecryptfs_encrypt_page(page); | 522 | set_page_dirty(page); |
516 | if (rc) { | 523 | unlock_page(page); |
517 | ecryptfs_printk(KERN_WARNING, "Error encrypting page (upper " | 524 | need_unlock_page = 0; |
518 | "index [0x%.16lx])\n", index); | ||
519 | goto out; | ||
520 | } | ||
521 | if (pos + copied > i_size_read(ecryptfs_inode)) { | 525 | if (pos + copied > i_size_read(ecryptfs_inode)) { |
522 | i_size_write(ecryptfs_inode, pos + copied); | 526 | i_size_write(ecryptfs_inode, pos + copied); |
523 | ecryptfs_printk(KERN_DEBUG, "Expanded file size to " | 527 | ecryptfs_printk(KERN_DEBUG, "Expanded file size to " |
524 | "[0x%.16llx]\n", | 528 | "[0x%.16llx]\n", |
525 | (unsigned long long)i_size_read(ecryptfs_inode)); | 529 | (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 | } | ||
526 | } | 537 | } |
527 | rc = ecryptfs_write_inode_size_to_metadata(ecryptfs_inode); | 538 | rc = copied; |
528 | if (rc) | ||
529 | printk(KERN_ERR "Error writing inode size to metadata; " | ||
530 | "rc = [%d]\n", rc); | ||
531 | else | ||
532 | rc = copied; | ||
533 | out: | 539 | out: |
534 | unlock_page(page); | 540 | if (need_unlock_page) |
541 | unlock_page(page); | ||
535 | page_cache_release(page); | 542 | page_cache_release(page); |
536 | return rc; | 543 | return rc; |
537 | } | 544 | } |
diff --git a/fs/ecryptfs/read_write.c b/fs/ecryptfs/read_write.c index db184ef15d3d..85d430963116 100644 --- a/fs/ecryptfs/read_write.c +++ b/fs/ecryptfs/read_write.c | |||
@@ -44,15 +44,11 @@ int ecryptfs_write_lower(struct inode *ecryptfs_inode, char *data, | |||
44 | ssize_t rc; | 44 | ssize_t rc; |
45 | 45 | ||
46 | inode_info = ecryptfs_inode_to_private(ecryptfs_inode); | 46 | inode_info = ecryptfs_inode_to_private(ecryptfs_inode); |
47 | mutex_lock(&inode_info->lower_file_mutex); | ||
48 | BUG_ON(!inode_info->lower_file); | 47 | BUG_ON(!inode_info->lower_file); |
49 | inode_info->lower_file->f_pos = offset; | ||
50 | fs_save = get_fs(); | 48 | fs_save = get_fs(); |
51 | set_fs(get_ds()); | 49 | set_fs(get_ds()); |
52 | rc = vfs_write(inode_info->lower_file, data, size, | 50 | rc = vfs_write(inode_info->lower_file, data, size, &offset); |
53 | &inode_info->lower_file->f_pos); | ||
54 | set_fs(fs_save); | 51 | set_fs(fs_save); |
55 | mutex_unlock(&inode_info->lower_file_mutex); | ||
56 | mark_inode_dirty_sync(ecryptfs_inode); | 52 | mark_inode_dirty_sync(ecryptfs_inode); |
57 | return rc; | 53 | return rc; |
58 | } | 54 | } |
@@ -234,15 +230,11 @@ int ecryptfs_read_lower(char *data, loff_t offset, size_t size, | |||
234 | mm_segment_t fs_save; | 230 | mm_segment_t fs_save; |
235 | ssize_t rc; | 231 | ssize_t rc; |
236 | 232 | ||
237 | mutex_lock(&inode_info->lower_file_mutex); | ||
238 | BUG_ON(!inode_info->lower_file); | 233 | BUG_ON(!inode_info->lower_file); |
239 | inode_info->lower_file->f_pos = offset; | ||
240 | fs_save = get_fs(); | 234 | fs_save = get_fs(); |
241 | set_fs(get_ds()); | 235 | set_fs(get_ds()); |
242 | rc = vfs_read(inode_info->lower_file, data, size, | 236 | rc = vfs_read(inode_info->lower_file, data, size, &offset); |
243 | &inode_info->lower_file->f_pos); | ||
244 | set_fs(fs_save); | 237 | set_fs(fs_save); |
245 | mutex_unlock(&inode_info->lower_file_mutex); | ||
246 | return rc; | 238 | return rc; |
247 | } | 239 | } |
248 | 240 | ||
diff --git a/fs/ecryptfs/super.c b/fs/ecryptfs/super.c index 3042fe123a34..245b517bf1b6 100644 --- a/fs/ecryptfs/super.c +++ b/fs/ecryptfs/super.c | |||
@@ -56,6 +56,7 @@ static struct inode *ecryptfs_alloc_inode(struct super_block *sb) | |||
56 | goto out; | 56 | goto out; |
57 | ecryptfs_init_crypt_stat(&inode_info->crypt_stat); | 57 | ecryptfs_init_crypt_stat(&inode_info->crypt_stat); |
58 | mutex_init(&inode_info->lower_file_mutex); | 58 | mutex_init(&inode_info->lower_file_mutex); |
59 | atomic_set(&inode_info->lower_file_count, 0); | ||
59 | inode_info->lower_file = NULL; | 60 | inode_info->lower_file = NULL; |
60 | inode = &inode_info->vfs_inode; | 61 | inode = &inode_info->vfs_inode; |
61 | out: | 62 | out: |
@@ -78,8 +79,7 @@ static void ecryptfs_i_callback(struct rcu_head *head) | |||
78 | * | 79 | * |
79 | * This is used during the final destruction of the inode. All | 80 | * This is used during the final destruction of the inode. All |
80 | * allocation of memory related to the inode, including allocated | 81 | * allocation of memory related to the inode, including allocated |
81 | * memory in the crypt_stat struct, will be released here. This | 82 | * memory in the crypt_stat struct, will be released here. |
82 | * function also fput()'s the persistent file for the lower inode. | ||
83 | * There should be no chance that this deallocation will be missed. | 83 | * There should be no chance that this deallocation will be missed. |
84 | */ | 84 | */ |
85 | static void ecryptfs_destroy_inode(struct inode *inode) | 85 | static void ecryptfs_destroy_inode(struct inode *inode) |
@@ -87,16 +87,7 @@ static void ecryptfs_destroy_inode(struct inode *inode) | |||
87 | struct ecryptfs_inode_info *inode_info; | 87 | struct ecryptfs_inode_info *inode_info; |
88 | 88 | ||
89 | inode_info = ecryptfs_inode_to_private(inode); | 89 | inode_info = ecryptfs_inode_to_private(inode); |
90 | if (inode_info->lower_file) { | 90 | BUG_ON(inode_info->lower_file); |
91 | struct dentry *lower_dentry = | ||
92 | inode_info->lower_file->f_dentry; | ||
93 | |||
94 | BUG_ON(!lower_dentry); | ||
95 | if (lower_dentry->d_inode) { | ||
96 | fput(inode_info->lower_file); | ||
97 | inode_info->lower_file = NULL; | ||
98 | } | ||
99 | } | ||
100 | ecryptfs_destroy_crypt_stat(&inode_info->crypt_stat); | 91 | ecryptfs_destroy_crypt_stat(&inode_info->crypt_stat); |
101 | call_rcu(&inode->i_rcu, ecryptfs_i_callback); | 92 | call_rcu(&inode->i_rcu, ecryptfs_i_callback); |
102 | } | 93 | } |
@@ -198,7 +189,7 @@ static int ecryptfs_show_options(struct seq_file *m, struct vfsmount *mnt) | |||
198 | const struct super_operations ecryptfs_sops = { | 189 | const struct super_operations ecryptfs_sops = { |
199 | .alloc_inode = ecryptfs_alloc_inode, | 190 | .alloc_inode = ecryptfs_alloc_inode, |
200 | .destroy_inode = ecryptfs_destroy_inode, | 191 | .destroy_inode = ecryptfs_destroy_inode, |
201 | .drop_inode = generic_delete_inode, | 192 | .drop_inode = generic_drop_inode, |
202 | .statfs = ecryptfs_statfs, | 193 | .statfs = ecryptfs_statfs, |
203 | .remount_fs = NULL, | 194 | .remount_fs = NULL, |
204 | .evict_inode = ecryptfs_evict_inode, | 195 | .evict_inode = ecryptfs_evict_inode, |