diff options
author | Michael Halcrow <mhalcrow@us.ibm.com> | 2007-10-16 04:27:56 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-10-16 12:43:10 -0400 |
commit | 132181796af08273ab9fa835420b9f5f78d70234 (patch) | |
tree | 87d016885edb62138facbdc098894909855e0db4 /fs/ecryptfs | |
parent | 956159c3d6e7eed61da0aaee740fbfba52849ff8 (diff) |
eCryptfs: fix Tag 1 parsing code
Fix up the Tag 1 parsing code to handle size limits and boundaries more
explicitly. Initialize the new auth_tok's flags.
Signed-off-by: Michael Halcrow <mhalcrow@us.ibm.com>
Cc: Josef Sipek <jsipek@fsl.cs.sunysb.edu>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs/ecryptfs')
-rw-r--r-- | fs/ecryptfs/keystore.c | 78 |
1 files changed, 33 insertions, 45 deletions
diff --git a/fs/ecryptfs/keystore.c b/fs/ecryptfs/keystore.c index 8eb0746313d0..f7debe6961d1 100644 --- a/fs/ecryptfs/keystore.c +++ b/fs/ecryptfs/keystore.c | |||
@@ -512,72 +512,64 @@ parse_tag_1_packet(struct ecryptfs_crypt_stat *crypt_stat, | |||
512 | 512 | ||
513 | (*packet_size) = 0; | 513 | (*packet_size) = 0; |
514 | (*new_auth_tok) = NULL; | 514 | (*new_auth_tok) = NULL; |
515 | 515 | /** | |
516 | /* we check that: | 516 | * This format is inspired by OpenPGP; see RFC 2440 |
517 | * one byte for the Tag 1 ID flag | 517 | * packet tag 1 |
518 | * two bytes for the body size | 518 | * |
519 | * do not exceed the maximum_packet_size | 519 | * Tag 1 identifier (1 byte) |
520 | * Max Tag 1 packet size (max 3 bytes) | ||
521 | * Version (1 byte) | ||
522 | * Key identifier (8 bytes; ECRYPTFS_SIG_SIZE) | ||
523 | * Cipher identifier (1 byte) | ||
524 | * Encrypted key size (arbitrary) | ||
525 | * | ||
526 | * 12 bytes minimum packet size | ||
520 | */ | 527 | */ |
521 | if (unlikely((*packet_size) + 3 > max_packet_size)) { | 528 | if (unlikely(max_packet_size < 12)) { |
522 | ecryptfs_printk(KERN_ERR, "Packet size exceeds max\n"); | 529 | printk(KERN_ERR "Invalid max packet size; must be >=12\n"); |
523 | rc = -EINVAL; | 530 | rc = -EINVAL; |
524 | goto out; | 531 | goto out; |
525 | } | 532 | } |
526 | /* check for Tag 1 identifier - one byte */ | ||
527 | if (data[(*packet_size)++] != ECRYPTFS_TAG_1_PACKET_TYPE) { | 533 | if (data[(*packet_size)++] != ECRYPTFS_TAG_1_PACKET_TYPE) { |
528 | ecryptfs_printk(KERN_ERR, "Enter w/ first byte != 0x%.2x\n", | 534 | printk(KERN_ERR "Enter w/ first byte != 0x%.2x\n", |
529 | ECRYPTFS_TAG_1_PACKET_TYPE); | 535 | ECRYPTFS_TAG_1_PACKET_TYPE); |
530 | rc = -EINVAL; | 536 | rc = -EINVAL; |
531 | goto out; | 537 | goto out; |
532 | } | 538 | } |
533 | /* Released: wipe_auth_tok_list called in ecryptfs_parse_packet_set or | 539 | /* Released: wipe_auth_tok_list called in ecryptfs_parse_packet_set or |
534 | * at end of function upon failure */ | 540 | * at end of function upon failure */ |
535 | auth_tok_list_item = | 541 | auth_tok_list_item = |
536 | kmem_cache_alloc(ecryptfs_auth_tok_list_item_cache, | 542 | kmem_cache_zalloc(ecryptfs_auth_tok_list_item_cache, |
537 | GFP_KERNEL); | 543 | GFP_KERNEL); |
538 | if (!auth_tok_list_item) { | 544 | if (!auth_tok_list_item) { |
539 | ecryptfs_printk(KERN_ERR, "Unable to allocate memory\n"); | 545 | printk(KERN_ERR "Unable to allocate memory\n"); |
540 | rc = -ENOMEM; | 546 | rc = -ENOMEM; |
541 | goto out; | 547 | goto out; |
542 | } | 548 | } |
543 | memset(auth_tok_list_item, 0, | ||
544 | sizeof(struct ecryptfs_auth_tok_list_item)); | ||
545 | (*new_auth_tok) = &auth_tok_list_item->auth_tok; | 549 | (*new_auth_tok) = &auth_tok_list_item->auth_tok; |
546 | /* check for body size - one to two bytes | 550 | if ((rc = parse_packet_length(&data[(*packet_size)], &body_size, |
547 | * | 551 | &length_size))) { |
548 | * ***** TAG 1 Packet Format ***** | 552 | printk(KERN_WARNING "Error parsing packet length; " |
549 | * | version number | 1 byte | | 553 | "rc = [%d]\n", rc); |
550 | * | key ID | 8 bytes | | ||
551 | * | public key algorithm | 1 byte | | ||
552 | * | encrypted session key | arbitrary | | ||
553 | */ | ||
554 | rc = parse_packet_length(&data[(*packet_size)], &body_size, | ||
555 | &length_size); | ||
556 | if (rc) { | ||
557 | ecryptfs_printk(KERN_WARNING, "Error parsing packet length; " | ||
558 | "rc = [%d]\n", rc); | ||
559 | goto out_free; | 554 | goto out_free; |
560 | } | 555 | } |
561 | if (unlikely(body_size < (0x02 + ECRYPTFS_SIG_SIZE))) { | 556 | if (unlikely(body_size < (ECRYPTFS_SIG_SIZE + 2))) { |
562 | ecryptfs_printk(KERN_WARNING, "Invalid body size ([%d])\n", | 557 | printk(KERN_WARNING "Invalid body size ([%d])\n", body_size); |
563 | body_size); | ||
564 | rc = -EINVAL; | 558 | rc = -EINVAL; |
565 | goto out_free; | 559 | goto out_free; |
566 | } | 560 | } |
567 | (*packet_size) += length_size; | 561 | (*packet_size) += length_size; |
568 | if (unlikely((*packet_size) + body_size > max_packet_size)) { | 562 | if (unlikely((*packet_size) + body_size > max_packet_size)) { |
569 | ecryptfs_printk(KERN_ERR, "Packet size exceeds max\n"); | 563 | printk(KERN_WARNING "Packet size exceeds max\n"); |
570 | rc = -EINVAL; | 564 | rc = -EINVAL; |
571 | goto out_free; | 565 | goto out_free; |
572 | } | 566 | } |
573 | /* Version 3 (from RFC2440) - one byte */ | ||
574 | if (unlikely(data[(*packet_size)++] != 0x03)) { | 567 | if (unlikely(data[(*packet_size)++] != 0x03)) { |
575 | ecryptfs_printk(KERN_DEBUG, "Unknown version number " | 568 | printk(KERN_WARNING "Unknown version number [%d]\n", |
576 | "[%d]\n", data[(*packet_size) - 1]); | 569 | data[(*packet_size) - 1]); |
577 | rc = -EINVAL; | 570 | rc = -EINVAL; |
578 | goto out_free; | 571 | goto out_free; |
579 | } | 572 | } |
580 | /* Read Signature */ | ||
581 | ecryptfs_to_hex((*new_auth_tok)->token.private_key.signature, | 573 | ecryptfs_to_hex((*new_auth_tok)->token.private_key.signature, |
582 | &data[(*packet_size)], ECRYPTFS_SIG_SIZE); | 574 | &data[(*packet_size)], ECRYPTFS_SIG_SIZE); |
583 | *packet_size += ECRYPTFS_SIG_SIZE; | 575 | *packet_size += ECRYPTFS_SIG_SIZE; |
@@ -585,27 +577,23 @@ parse_tag_1_packet(struct ecryptfs_crypt_stat *crypt_stat, | |||
585 | * know which public key encryption algorithm was used */ | 577 | * know which public key encryption algorithm was used */ |
586 | (*packet_size)++; | 578 | (*packet_size)++; |
587 | (*new_auth_tok)->session_key.encrypted_key_size = | 579 | (*new_auth_tok)->session_key.encrypted_key_size = |
588 | body_size - (0x02 + ECRYPTFS_SIG_SIZE); | 580 | body_size - (ECRYPTFS_SIG_SIZE + 2); |
589 | if ((*new_auth_tok)->session_key.encrypted_key_size | 581 | if ((*new_auth_tok)->session_key.encrypted_key_size |
590 | > ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES) { | 582 | > ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES) { |
591 | ecryptfs_printk(KERN_ERR, "Tag 1 packet contains key larger " | 583 | printk(KERN_WARNING "Tag 1 packet contains key larger " |
592 | "than ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES"); | 584 | "than ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES"); |
593 | rc = -EINVAL; | 585 | rc = -EINVAL; |
594 | goto out; | 586 | goto out; |
595 | } | 587 | } |
596 | ecryptfs_printk(KERN_DEBUG, "Encrypted key size = [%d]\n", | ||
597 | (*new_auth_tok)->session_key.encrypted_key_size); | ||
598 | memcpy((*new_auth_tok)->session_key.encrypted_key, | 588 | memcpy((*new_auth_tok)->session_key.encrypted_key, |
599 | &data[(*packet_size)], (body_size - 0x02 - ECRYPTFS_SIG_SIZE)); | 589 | &data[(*packet_size)], (body_size - (ECRYPTFS_SIG_SIZE + 2))); |
600 | (*packet_size) += (*new_auth_tok)->session_key.encrypted_key_size; | 590 | (*packet_size) += (*new_auth_tok)->session_key.encrypted_key_size; |
601 | (*new_auth_tok)->session_key.flags &= | 591 | (*new_auth_tok)->session_key.flags &= |
602 | ~ECRYPTFS_CONTAINS_DECRYPTED_KEY; | 592 | ~ECRYPTFS_CONTAINS_DECRYPTED_KEY; |
603 | (*new_auth_tok)->session_key.flags |= | 593 | (*new_auth_tok)->session_key.flags |= |
604 | ECRYPTFS_CONTAINS_ENCRYPTED_KEY; | 594 | ECRYPTFS_CONTAINS_ENCRYPTED_KEY; |
605 | (*new_auth_tok)->token_type = ECRYPTFS_PRIVATE_KEY; | 595 | (*new_auth_tok)->token_type = ECRYPTFS_PRIVATE_KEY; |
606 | (*new_auth_tok)->flags |= ECRYPTFS_PRIVATE_KEY; | 596 | (*new_auth_tok)->flags = 0; |
607 | /* TODO: Why are we setting this flag here? Don't we want the | ||
608 | * userspace to decrypt the session key? */ | ||
609 | (*new_auth_tok)->session_key.flags &= | 597 | (*new_auth_tok)->session_key.flags &= |
610 | ~(ECRYPTFS_USERSPACE_SHOULD_TRY_TO_DECRYPT); | 598 | ~(ECRYPTFS_USERSPACE_SHOULD_TRY_TO_DECRYPT); |
611 | (*new_auth_tok)->session_key.flags &= | 599 | (*new_auth_tok)->session_key.flags &= |