aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorMichael Halcrow <mhalcrow@us.ibm.com>2007-10-16 04:27:56 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-10-16 12:43:10 -0400
commit132181796af08273ab9fa835420b9f5f78d70234 (patch)
tree87d016885edb62138facbdc098894909855e0db4 /fs
parent956159c3d6e7eed61da0aaee740fbfba52849ff8 (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')
-rw-r--r--fs/ecryptfs/keystore.c78
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 &=