From: Eric Sandeen <sandeen@redhat.com> Date: Wed, 22 Jul 2009 15:48:34 -0500 Subject: [fs] ecryptfs: check tag 11 packet data buffer size Message-id: 4A677B22.70703@redhat.com O-Subject: [kernel team] [PATCH V2 RHEL5.4] ecryptfs: check tag 11 packet literal data buffer size Bugzilla: 512863 RH-Acked-by: David Miller <davem@redhat.com> RH-Acked-by: David Howells <dhowells@redhat.com> RH-Acked-by: Thomas Graf <tgraf@redhat.com> CVE: CVE-2009-2406 RH-Acked-by: Alexander Viro <aviro@redhat.com> A value from disk (eventually tag_11_contents_size) was used as the size argument to memcpy without checking the size, potentially overflowing the target. Fix tested with an image provided by Tyler, demonstrating writing arbitrary gunk into the stack without the patch. With it, it is handled and we get EIO from the file. The patch is from the upstream eCryptfs maintainer. Thanks, -Eric >From f927e6c810759619317e4d682e0e61bef78efa96 Mon Sep 17 00:00:00 2001 From: Tyler Hicks <tyhicks@linux.vnet.ibm.com> Date: Wed, 15 Jul 2009 19:31:01 -0500 Subject: [PATCH] eCryptfs: Check Tag 11 literal data buffer size Tag 11 packets are stored in the metadata section of an eCryptfs file to store the key signature(s) used to encrypt the file encryption key. After extracting the packet length field to determine the key signature length, a check is not performed to see if the length would exceed the key signature buffer size that was passed into parse_tag_11_packet(). Thanks to Ramon de Carvalho Valle for finding this bug using fsfuzzer. Signed-off-by: Tyler Hicks <tyhicks@linux.vnet.ibm.com> diff --git a/fs/ecryptfs/keystore.c b/fs/ecryptfs/keystore.c index 0e5bbc0..66eb2f3 100644 --- a/fs/ecryptfs/keystore.c +++ b/fs/ecryptfs/keystore.c @@ -883,6 +883,12 @@ parse_tag_11_packet(unsigned char *data, unsigned char *contents, rc = -EINVAL; goto out; } + if (unlikely((*tag_11_contents_size) > max_contents_bytes)) { + printk(KERN_ERR "Literal data section in tag 11 packet exceeds " + "expected size\n"); + rc = -EINVAL; + goto out; + } if (data[(*packet_size)++] != 0x62) { printk(KERN_WARNING "Unrecognizable packet\n"); rc = -EINVAL;