• R/O
  • HTTP
  • SSH
  • HTTPS

linux-2.4.36: Commit

2.4.36-stable kernel tree


Commit MetaInfo

Revisionbf45d0bda54148841426979209d5f1df4f4d34e0 (tree)
Time2007-11-12 02:44:09
AuthorMoritz Muehlenhoff <jmm@inut...>
CommiterWilly Tarreau

Log Message

[PATCH] corrupted cramfs filesystems cause kernel oops (CVE-2006-5823)

From http://projects.info-pull.com/mokb/MOKB-07-11-2006.html :

| The zlib_inflate function in Linux kernel 2.6.x allows local users to cause a
| denial of service (crash) via a malformed filesystem that uses zlib
| compression that triggers memory corruption, as demonstrated using cramfs.

We could reproduce this with 2.4.27, since there aren't any changes to git
for cramfs since initial import this is likely unfixed in 2.4.35 too.
2.6 patch below.

http://www.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=8bb0269160df2a60764013994d0bc5165406cf4a

| Steve Grubb's fzfuzzer tool (http://people.redhat.com/sgrubb/files/
| fsfuzzer-0.6.tar.gz) generates corrupt Cramfs filesystems which cause
| Cramfs to kernel oops in cramfs_uncompress_block(). The cause of the oops
| is an unchecked corrupted block length field read by cramfs_readpage().
|
| This patch adds a sanity check to cramfs_readpage() which checks that the
| block length field is sensible. The (PAGE_CACHE_SIZE << 1) size check is
| intentional, even though the uncompressed data is not going to be larger
| than PAGE_CACHE_SIZE, gzip sometimes generates compressed data larger than
| the original source data. Mkcramfs checks that the compressed size is
| always less than or equal to PAGE_CACHE_SIZE << 1. Of course Cramfs could
| use the original uncompressed data in this case, but it doesn't.
|
| Signed-off-by: Phillip Lougher <phillip@lougher.org.uk>
| Signed-off-by: Andrew Morton <akpm@osdl.org>
| Signed-off-by: Linus Torvalds <torvalds@osdl.org>

Change Summary

Incremental Difference

--- a/fs/cramfs/inode.c
+++ b/fs/cramfs/inode.c
@@ -404,6 +404,8 @@ static int cramfs_readpage(struct file *file, struct page * page)
404404 pgdata = kmap(page);
405405 if (compr_len == 0)
406406 ; /* hole */
407+ else if (compr_len > (PAGE_CACHE_SIZE << 1))
408+ printk(KERN_ERR "cramfs: bad compressed blocksize %u\n", compr_len);
407409 else {
408410 down(&read_mutex);
409411 bytes_filled = cramfs_uncompress_block(pgdata,
Show on old repository browser