aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ecryptfs
diff options
context:
space:
mode:
authorMichael Halcrow <mhalcrow@us.ibm.com>2007-10-16 04:27:57 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-10-16 12:43:11 -0400
commitf648104a0d44d7c551f8025ad7e50c4815d3b6eb (patch)
treef02a40f291c67171f86facc9e2fa80c01a0bd03b /fs/ecryptfs
parentc59becfceea8de57c35a3de5ee45a7bb883cf90a (diff)
eCryptfs: fix Tag 11 parsing code
Fix up the Tag 11 parsing code to handle size limits and boundaries more explicitly. Pay attention to *8* bytes for the key identifier (literal data), no more, no less. Signed-off-by: Michael Halcrow <mhalcrow@us.ibm.com> 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.c76
1 files changed, 27 insertions, 49 deletions
diff --git a/fs/ecryptfs/keystore.c b/fs/ecryptfs/keystore.c
index 72086141a6e8..aedff506899e 100644
--- a/fs/ecryptfs/keystore.c
+++ b/fs/ecryptfs/keystore.c
@@ -803,82 +803,60 @@ parse_tag_11_packet(unsigned char *data, unsigned char *contents,
803 803
804 (*packet_size) = 0; 804 (*packet_size) = 0;
805 (*tag_11_contents_size) = 0; 805 (*tag_11_contents_size) = 0;
806 806 /* This format is inspired by OpenPGP; see RFC 2440
807 /* check that: 807 * packet tag 11
808 * one byte for the Tag 11 ID flag 808 *
809 * two bytes for the Tag 11 length 809 * Tag 11 identifier (1 byte)
810 * do not exceed the maximum_packet_size 810 * Max Tag 11 packet size (max 3 bytes)
811 * Binary format specifier (1 byte)
812 * Filename length (1 byte)
813 * Filename ("_CONSOLE") (8 bytes)
814 * Modification date (4 bytes)
815 * Literal data (arbitrary)
816 *
817 * We need at least 16 bytes of data for the packet to even be
818 * valid.
811 */ 819 */
812 if (unlikely((*packet_size) + 3 > max_packet_size)) { 820 if (max_packet_size < 16) {
813 ecryptfs_printk(KERN_ERR, "Packet size exceeds max\n"); 821 printk(KERN_ERR "Maximum packet size too small\n");
814 rc = -EINVAL; 822 rc = -EINVAL;
815 goto out; 823 goto out;
816 } 824 }
817
818 /* check for Tag 11 identifyer - one byte */
819 if (data[(*packet_size)++] != ECRYPTFS_TAG_11_PACKET_TYPE) { 825 if (data[(*packet_size)++] != ECRYPTFS_TAG_11_PACKET_TYPE) {
820 ecryptfs_printk(KERN_WARNING, 826 printk(KERN_WARNING "Invalid tag 11 packet format\n");
821 "Invalid tag 11 packet format\n");
822 rc = -EINVAL; 827 rc = -EINVAL;
823 goto out; 828 goto out;
824 } 829 }
825 830 if ((rc = parse_packet_length(&data[(*packet_size)], &body_size,
826 /* get Tag 11 content length - one or two bytes */ 831 &length_size))) {
827 rc = parse_packet_length(&data[(*packet_size)], &body_size, 832 printk(KERN_WARNING "Invalid tag 11 packet format\n");
828 &length_size);
829 if (rc) {
830 ecryptfs_printk(KERN_WARNING,
831 "Invalid tag 11 packet format\n");
832 goto out; 833 goto out;
833 } 834 }
834 (*packet_size) += length_size; 835 if (body_size < 14) {
835 836 printk(KERN_WARNING "Invalid body size ([%d])\n", body_size);
836 if (body_size < 13) {
837 ecryptfs_printk(KERN_WARNING, "Invalid body size ([%d])\n",
838 body_size);
839 rc = -EINVAL; 837 rc = -EINVAL;
840 goto out; 838 goto out;
841 } 839 }
842 /* We have 13 bytes of surrounding packet values */ 840 (*packet_size) += length_size;
843 (*tag_11_contents_size) = (body_size - 13); 841 (*tag_11_contents_size) = (body_size - 14);
844
845 /* now we know the length of the remainting Tag 11 packet size:
846 * 14 fix bytes for: special flag one, special flag two,
847 * 12 skipped bytes
848 * body_size bytes minus the stuff above is the Tag 11 content
849 */
850 /* FIXME why is the body size one byte smaller than the actual
851 * size of the body?
852 * this seems to be an error here as well as in
853 * write_tag_11_packet() */
854 if (unlikely((*packet_size) + body_size + 1 > max_packet_size)) { 842 if (unlikely((*packet_size) + body_size + 1 > max_packet_size)) {
855 ecryptfs_printk(KERN_ERR, "Packet size exceeds max\n"); 843 printk(KERN_ERR "Packet size exceeds max\n");
856 rc = -EINVAL; 844 rc = -EINVAL;
857 goto out; 845 goto out;
858 } 846 }
859
860 /* special flag one - one byte */
861 if (data[(*packet_size)++] != 0x62) { 847 if (data[(*packet_size)++] != 0x62) {
862 ecryptfs_printk(KERN_WARNING, "Unrecognizable packet\n"); 848 printk(KERN_WARNING "Unrecognizable packet\n");
863 rc = -EINVAL; 849 rc = -EINVAL;
864 goto out; 850 goto out;
865 } 851 }
866
867 /* special flag two - one byte */
868 if (data[(*packet_size)++] != 0x08) { 852 if (data[(*packet_size)++] != 0x08) {
869 ecryptfs_printk(KERN_WARNING, "Unrecognizable packet\n"); 853 printk(KERN_WARNING "Unrecognizable packet\n");
870 rc = -EINVAL; 854 rc = -EINVAL;
871 goto out; 855 goto out;
872 } 856 }
873 857 (*packet_size) += 12; /* Ignore filename and modification date */
874 /* skip the next 12 bytes */
875 (*packet_size) += 12; /* We don't care about the filename or
876 * the timestamp */
877
878 /* get the Tag 11 contents - tag_11_contents_size bytes */
879 memcpy(contents, &data[(*packet_size)], (*tag_11_contents_size)); 858 memcpy(contents, &data[(*packet_size)], (*tag_11_contents_size));
880 (*packet_size) += (*tag_11_contents_size); 859 (*packet_size) += (*tag_11_contents_size);
881
882out: 860out:
883 if (rc) { 861 if (rc) {
884 (*packet_size) = 0; 862 (*packet_size) = 0;