diff options
| -rw-r--r-- | fs/ecryptfs/crypto.c | 2 | ||||
| -rw-r--r-- | fs/ecryptfs/ecryptfs_kernel.h | 30 | ||||
| -rw-r--r-- | fs/ecryptfs/file.c | 9 | ||||
| -rw-r--r-- | fs/ecryptfs/inode.c | 24 | ||||
| -rw-r--r-- | fs/ecryptfs/keystore.c | 272 | ||||
| -rw-r--r-- | fs/ecryptfs/main.c | 10 | ||||
| -rw-r--r-- | fs/ecryptfs/mmap.c | 61 | ||||
| -rw-r--r-- | fs/ecryptfs/read_write.c | 12 | ||||
| -rw-r--r-- | fs/ecryptfs/super.c | 3 |
9 files changed, 235 insertions, 188 deletions
diff --git a/fs/ecryptfs/crypto.c b/fs/ecryptfs/crypto.c index bfd8b680e648..d2a70a4561f9 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)) { |
diff --git a/fs/ecryptfs/ecryptfs_kernel.h b/fs/ecryptfs/ecryptfs_kernel.h index e00753496e3e..bd3cafd0949d 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,18 @@ 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 | ||
| 273 | u32 flags; | 272 | u32 flags; |
| 274 | unsigned int file_version; | 273 | unsigned int file_version; |
| 275 | size_t iv_bytes; | 274 | size_t iv_bytes; |
| @@ -297,7 +296,6 @@ struct ecryptfs_inode_info { | |||
| 297 | struct inode vfs_inode; | 296 | struct inode vfs_inode; |
| 298 | struct inode *wii_inode; | 297 | struct inode *wii_inode; |
| 299 | struct file *lower_file; | 298 | struct file *lower_file; |
| 300 | struct mutex lower_file_mutex; | ||
| 301 | struct ecryptfs_crypt_stat crypt_stat; | 299 | struct ecryptfs_crypt_stat crypt_stat; |
| 302 | }; | 300 | }; |
| 303 | 301 | ||
| @@ -333,7 +331,6 @@ struct ecryptfs_global_auth_tok { | |||
| 333 | u32 flags; | 331 | u32 flags; |
| 334 | struct list_head mount_crypt_stat_list; | 332 | struct list_head mount_crypt_stat_list; |
| 335 | struct key *global_auth_tok_key; | 333 | struct key *global_auth_tok_key; |
| 336 | struct ecryptfs_auth_tok *global_auth_tok; | ||
| 337 | unsigned char sig[ECRYPTFS_SIG_SIZE_HEX + 1]; | 334 | unsigned char sig[ECRYPTFS_SIG_SIZE_HEX + 1]; |
| 338 | }; | 335 | }; |
| 339 | 336 | ||
| @@ -380,7 +377,6 @@ struct ecryptfs_mount_crypt_stat { | |||
| 380 | u32 flags; | 377 | u32 flags; |
| 381 | struct list_head global_auth_tok_list; | 378 | struct list_head global_auth_tok_list; |
| 382 | struct mutex global_auth_tok_list_mutex; | 379 | struct mutex global_auth_tok_list_mutex; |
| 383 | size_t num_global_auth_toks; | ||
| 384 | size_t global_default_cipher_key_size; | 380 | size_t global_default_cipher_key_size; |
| 385 | size_t global_default_fn_cipher_key_bytes; | 381 | size_t global_default_fn_cipher_key_bytes; |
| 386 | unsigned char global_default_cipher_name[ECRYPTFS_MAX_CIPHER_NAME_SIZE | 382 | unsigned char global_default_cipher_name[ECRYPTFS_MAX_CIPHER_NAME_SIZE |
diff --git a/fs/ecryptfs/file.c b/fs/ecryptfs/file.c index 7d1050e254f9..cedc913d11ba 100644 --- a/fs/ecryptfs/file.c +++ b/fs/ecryptfs/file.c | |||
| @@ -273,7 +273,14 @@ static int ecryptfs_release(struct inode *inode, struct file *file) | |||
| 273 | static int | 273 | static int |
| 274 | ecryptfs_fsync(struct file *file, int datasync) | 274 | ecryptfs_fsync(struct file *file, int datasync) |
| 275 | { | 275 | { |
| 276 | return vfs_fsync(ecryptfs_file_to_lower(file), datasync); | 276 | int rc = 0; |
| 277 | |||
| 278 | rc = generic_file_fsync(file, datasync); | ||
| 279 | if (rc) | ||
| 280 | goto out; | ||
| 281 | rc = vfs_fsync(ecryptfs_file_to_lower(file), datasync); | ||
| 282 | out: | ||
| 283 | return rc; | ||
| 277 | } | 284 | } |
| 278 | 285 | ||
| 279 | static int ecryptfs_fasync(int fd, struct file *file, int flag) | 286 | 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..f99051b7adab 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) { |
| @@ -202,9 +181,6 @@ static int ecryptfs_initialize_file(struct dentry *ecryptfs_dentry) | |||
| 202 | printk(KERN_ERR "Error writing headers; rc = [%d]\n", rc); | 181 | printk(KERN_ERR "Error writing headers; rc = [%d]\n", rc); |
| 203 | goto out; | 182 | goto out; |
| 204 | } | 183 | } |
| 205 | rc = grow_file(ecryptfs_dentry); | ||
| 206 | if (rc) | ||
| 207 | printk(KERN_ERR "Error growing file; rc = [%d]\n", rc); | ||
| 208 | out: | 184 | out: |
| 209 | return rc; | 185 | return rc; |
| 210 | } | 186 | } |
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/main.c b/fs/ecryptfs/main.c index 758323a0f09a..c27c0ecf90bc 100644 --- a/fs/ecryptfs/main.c +++ b/fs/ecryptfs/main.c | |||
| @@ -122,7 +122,6 @@ int ecryptfs_init_persistent_file(struct dentry *ecryptfs_dentry) | |||
| 122 | ecryptfs_inode_to_private(ecryptfs_dentry->d_inode); | 122 | ecryptfs_inode_to_private(ecryptfs_dentry->d_inode); |
| 123 | int rc = 0; | 123 | int rc = 0; |
| 124 | 124 | ||
| 125 | mutex_lock(&inode_info->lower_file_mutex); | ||
| 126 | if (!inode_info->lower_file) { | 125 | if (!inode_info->lower_file) { |
| 127 | struct dentry *lower_dentry; | 126 | struct dentry *lower_dentry; |
| 128 | struct vfsmount *lower_mnt = | 127 | struct vfsmount *lower_mnt = |
| @@ -138,7 +137,6 @@ int ecryptfs_init_persistent_file(struct dentry *ecryptfs_dentry) | |||
| 138 | inode_info->lower_file = NULL; | 137 | inode_info->lower_file = NULL; |
| 139 | } | 138 | } |
| 140 | } | 139 | } |
| 141 | mutex_unlock(&inode_info->lower_file_mutex); | ||
| 142 | return rc; | 140 | return rc; |
| 143 | } | 141 | } |
| 144 | 142 | ||
| @@ -241,14 +239,14 @@ static int ecryptfs_init_global_auth_toks( | |||
| 241 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat) | 239 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat) |
| 242 | { | 240 | { |
| 243 | struct ecryptfs_global_auth_tok *global_auth_tok; | 241 | struct ecryptfs_global_auth_tok *global_auth_tok; |
| 242 | struct ecryptfs_auth_tok *auth_tok; | ||
| 244 | int rc = 0; | 243 | int rc = 0; |
| 245 | 244 | ||
| 246 | list_for_each_entry(global_auth_tok, | 245 | list_for_each_entry(global_auth_tok, |
| 247 | &mount_crypt_stat->global_auth_tok_list, | 246 | &mount_crypt_stat->global_auth_tok_list, |
| 248 | mount_crypt_stat_list) { | 247 | mount_crypt_stat_list) { |
| 249 | rc = ecryptfs_keyring_auth_tok_for_sig( | 248 | rc = ecryptfs_keyring_auth_tok_for_sig( |
| 250 | &global_auth_tok->global_auth_tok_key, | 249 | &global_auth_tok->global_auth_tok_key, &auth_tok, |
| 251 | &global_auth_tok->global_auth_tok, | ||
| 252 | global_auth_tok->sig); | 250 | global_auth_tok->sig); |
| 253 | if (rc) { | 251 | if (rc) { |
| 254 | printk(KERN_ERR "Could not find valid key in user " | 252 | printk(KERN_ERR "Could not find valid key in user " |
| @@ -256,8 +254,10 @@ static int ecryptfs_init_global_auth_toks( | |||
| 256 | "option: [%s]\n", global_auth_tok->sig); | 254 | "option: [%s]\n", global_auth_tok->sig); |
| 257 | global_auth_tok->flags |= ECRYPTFS_AUTH_TOK_INVALID; | 255 | global_auth_tok->flags |= ECRYPTFS_AUTH_TOK_INVALID; |
| 258 | goto out; | 256 | goto out; |
| 259 | } else | 257 | } else { |
| 260 | global_auth_tok->flags &= ~ECRYPTFS_AUTH_TOK_INVALID; | 258 | global_auth_tok->flags &= ~ECRYPTFS_AUTH_TOK_INVALID; |
| 259 | up_write(&(global_auth_tok->global_auth_tok_key)->sem); | ||
| 260 | } | ||
| 261 | } | 261 | } |
| 262 | out: | 262 | out: |
| 263 | return rc; | 263 | return rc; |
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..bacc882e1ae4 100644 --- a/fs/ecryptfs/super.c +++ b/fs/ecryptfs/super.c | |||
| @@ -55,7 +55,6 @@ static struct inode *ecryptfs_alloc_inode(struct super_block *sb) | |||
| 55 | if (unlikely(!inode_info)) | 55 | if (unlikely(!inode_info)) |
| 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); | ||
| 59 | inode_info->lower_file = NULL; | 58 | inode_info->lower_file = NULL; |
| 60 | inode = &inode_info->vfs_inode; | 59 | inode = &inode_info->vfs_inode; |
| 61 | out: | 60 | out: |
| @@ -198,7 +197,7 @@ static int ecryptfs_show_options(struct seq_file *m, struct vfsmount *mnt) | |||
| 198 | const struct super_operations ecryptfs_sops = { | 197 | const struct super_operations ecryptfs_sops = { |
| 199 | .alloc_inode = ecryptfs_alloc_inode, | 198 | .alloc_inode = ecryptfs_alloc_inode, |
| 200 | .destroy_inode = ecryptfs_destroy_inode, | 199 | .destroy_inode = ecryptfs_destroy_inode, |
| 201 | .drop_inode = generic_delete_inode, | 200 | .drop_inode = generic_drop_inode, |
| 202 | .statfs = ecryptfs_statfs, | 201 | .statfs = ecryptfs_statfs, |
| 203 | .remount_fs = NULL, | 202 | .remount_fs = NULL, |
| 204 | .evict_inode = ecryptfs_evict_inode, | 203 | .evict_inode = ecryptfs_evict_inode, |
