diff options
author | Eric Sandeen <sandeen@redhat.com> | 2007-10-17 02:27:15 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-10-17 11:42:53 -0400 |
commit | f44ec6f3f89889a469773b1fd894f8fcc07c29cf (patch) | |
tree | 3b58f7b094e61c02536c7414906d7e29190979de /fs/minix | |
parent | d8ea6cf89991000ae458e34e36379814cf202555 (diff) |
limit minixfs printks on corrupted dir i_size
This attempts to address CVE-2006-6058
http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2006-6058
first reported at http://projects.info-pull.com/mokb/MOKB-17-11-2006.html
Essentially a corrupted minix dir inode reporting a very large
i_size will loop for a very long time in minix_readdir, minix_find_entry,
etc, because on EIO they just move on to try the next page. This is
under the BKL, printk-storming as well. This can lock up the machine
for a very long time. Simply ratelimiting the printks gets things back
under control. Make the message a bit more informative while we're here.
Signed-off-by: Eric Sandeen <sandeen@redhat.com>
Cc: Bodo Eggert <7eggert@gmx.de>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs/minix')
-rw-r--r-- | fs/minix/itree_v1.c | 9 | ||||
-rw-r--r-- | fs/minix/itree_v2.c | 9 |
2 files changed, 14 insertions, 4 deletions
diff --git a/fs/minix/itree_v1.c b/fs/minix/itree_v1.c index 1a5f3bf0bcec..82d6554b02fe 100644 --- a/fs/minix/itree_v1.c +++ b/fs/minix/itree_v1.c | |||
@@ -23,11 +23,16 @@ static inline block_t *i_data(struct inode *inode) | |||
23 | static int block_to_path(struct inode * inode, long block, int offsets[DEPTH]) | 23 | static int block_to_path(struct inode * inode, long block, int offsets[DEPTH]) |
24 | { | 24 | { |
25 | int n = 0; | 25 | int n = 0; |
26 | char b[BDEVNAME_SIZE]; | ||
26 | 27 | ||
27 | if (block < 0) { | 28 | if (block < 0) { |
28 | printk("minix_bmap: block<0\n"); | 29 | printk("MINIX-fs: block_to_path: block %ld < 0 on dev %s\n", |
30 | block, bdevname(inode->i_sb->s_bdev, b)); | ||
29 | } else if (block >= (minix_sb(inode->i_sb)->s_max_size/BLOCK_SIZE)) { | 31 | } else if (block >= (minix_sb(inode->i_sb)->s_max_size/BLOCK_SIZE)) { |
30 | printk("minix_bmap: block>big\n"); | 32 | if (printk_ratelimit()) |
33 | printk("MINIX-fs: block_to_path: " | ||
34 | "block %ld too big on dev %s\n", | ||
35 | block, bdevname(inode->i_sb->s_bdev, b)); | ||
31 | } else if (block < 7) { | 36 | } else if (block < 7) { |
32 | offsets[n++] = block; | 37 | offsets[n++] = block; |
33 | } else if ((block -= 7) < 512) { | 38 | } else if ((block -= 7) < 512) { |
diff --git a/fs/minix/itree_v2.c b/fs/minix/itree_v2.c index ad8f0dec4ef4..f23010969369 100644 --- a/fs/minix/itree_v2.c +++ b/fs/minix/itree_v2.c | |||
@@ -23,12 +23,17 @@ static inline block_t *i_data(struct inode *inode) | |||
23 | static int block_to_path(struct inode * inode, long block, int offsets[DEPTH]) | 23 | static int block_to_path(struct inode * inode, long block, int offsets[DEPTH]) |
24 | { | 24 | { |
25 | int n = 0; | 25 | int n = 0; |
26 | char b[BDEVNAME_SIZE]; | ||
26 | struct super_block *sb = inode->i_sb; | 27 | struct super_block *sb = inode->i_sb; |
27 | 28 | ||
28 | if (block < 0) { | 29 | if (block < 0) { |
29 | printk("minix_bmap: block<0\n"); | 30 | printk("MINIX-fs: block_to_path: block %ld < 0 on dev %s\n", |
31 | block, bdevname(sb->s_bdev, b)); | ||
30 | } else if (block >= (minix_sb(inode->i_sb)->s_max_size/sb->s_blocksize)) { | 32 | } else if (block >= (minix_sb(inode->i_sb)->s_max_size/sb->s_blocksize)) { |
31 | printk("minix_bmap: block>big\n"); | 33 | if (printk_ratelimit()) |
34 | printk("MINIX-fs: block_to_path: " | ||
35 | "block %ld too big on dev %s\n", | ||
36 | block, bdevname(sb->s_bdev, b)); | ||
32 | } else if (block < 7) { | 37 | } else if (block < 7) { |
33 | offsets[n++] = block; | 38 | offsets[n++] = block; |
34 | } else if ((block -= 7) < 256) { | 39 | } else if ((block -= 7) < 256) { |