CVE-2009-0787: Linux kernel eCryptFS Information Leak

Information leak vulnerabilities can sometimes be extremely useful and this one leaks up to 4KB of kernel memory which is definitely enough to contain sensitive information. So, it was reported by Florian Streibelt and later fixed by Tyler Hicks on 20 March 2009 at 2.6.28.9 according to its changelog. The following code was taken from 2.6.28.8 release of the Linux kernel. Here is the vulnerable function from fs/ecryptfs/crypto.c:

This isn’t anything complicated. It justs allocates a zeroed page using get_zeroed_page() at line 1373 and later calling ecryptfs_write_headers_virt() to write the headers at the virtual address pointed by virt of size defined by the second argument, PAGE_CACHE_SIZE (which is equal to PAGE_SIZE, for example on x86 is 4096, have a look at arch/x86/include/asm/page.h). Now, by having a really quick look at fs/ecryptfs/ecryptfs_kernel.h we can notice the following:

Where as we saw earlier, this is defined at ecryptfs_kernel.h and it’s 8192. Now if we go back to ecryptfs_write_metadata() at line 1390 we’re going to see a function named ecryptfs_write_metadata_to_contents() being invoked. Judging by its name this should probably write the metadata to the contents but take a closer look at its parameters. It takes the following three arguments:
1) “struct ecryptfs_crypt_stat *” which is the actual context
2) “struct dentry *ecryptfs_dentry” which is the filesystem dentry
3) “char *virt” which is a pointer to the virtual address space allocated for the header
Now, take a look at this function:

from fs/ecryptfs/read_write.c we can easily deduce that it’s incorrectly passing num_header_bytes_at_front as the size of bytes to be written even though this value is 8192 and our allocation was 4096 bytes. This can leak up to 4096 additional bytes from kernel memory. To patch this various changes where made. First of all, now fs/ecryptfs/crypto.c has a wrapper around get_zeroed_page() function which is this: