linux-ext4.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] ext2/ext3/ext4: Add block bitmap validation
@ 2007-07-09 18:24 Aneesh Kumar K.V
  2007-07-09 19:16 ` Andreas Dilger
  0 siblings, 1 reply; 5+ messages in thread
From: Aneesh Kumar K.V @ 2007-07-09 18:24 UTC (permalink / raw)
  To: linux-ext4; +Cc: adilger, Aneesh Kumar K.V

When a new block bitmap is read from disk in read_block_bitmap()
there are a few bits that should ALWAYS be set. In particular, the
blocks given by ext4_blk_bitmap, ext4_inode_bitmap and ext4_inode_table.
Validate the block bitmap against these blocks.

Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
---
 fs/ext2/balloc.c |   51 +++++++++++++++++++++++++++++++++++++----------
 fs/ext3/balloc.c |   48 ++++++++++++++++++++++++++++++++++++---------
 fs/ext4/balloc.c |   57 ++++++++++++++++++++++++++++++++++++++++-------------
 3 files changed, 121 insertions(+), 35 deletions(-)

diff --git a/fs/ext2/balloc.c b/fs/ext2/balloc.c
index baf71dd..8127682 100644
--- a/fs/ext2/balloc.c
+++ b/fs/ext2/balloc.c
@@ -69,6 +69,14 @@ struct ext2_group_desc * ext2_get_group_desc(struct super_block * sb,
 	return desc + offset;
 }
 
+static inline int
+block_in_use(unsigned long block, struct super_block *sb, unsigned char *map)
+{
+	return ext2_test_bit ((block -
+		le32_to_cpu(EXT2_SB(sb)->s_es->s_first_data_block)) %
+			 EXT2_BLOCKS_PER_GROUP(sb), map);
+}
+
 /*
  * Read the bitmap for a given block_group, reading into the specified 
  * slot in the superblock's bitmap cache.
@@ -80,18 +88,46 @@ read_block_bitmap(struct super_block *sb, unsigned int block_group)
 {
 	struct ext2_group_desc * desc;
 	struct buffer_head * bh = NULL;
-	
+	unsigned int bitmap_blk;
+
 	desc = ext2_get_group_desc (sb, block_group, NULL);
 	if (!desc)
-		goto error_out;
-	bh = sb_bread(sb, le32_to_cpu(desc->bg_block_bitmap));
+		return NULL;
+	bitmap_blk = le32_to_cpu(desc->bg_block_bitmap);
+	bh = sb_bread(sb, bitmap_blk);
 	if (!bh)
 		ext2_error (sb, "read_block_bitmap",
 			    "Cannot read block bitmap - "
 			    "block_group = %d, block_bitmap = %u",
 			    block_group, le32_to_cpu(desc->bg_block_bitmap));
-error_out:
+
+	/* check whether block bitmap block number is set */
+	if (!block_in_use(bitmap_blk, sb, bh->b_data)) {
+		/* bad block bitmap */
+		goto error_out;
+	}
+	/* check whether the inode bitmap block number is set */
+	bitmap_blk = le32_to_cpu(desc->bg_inode_bitmap);
+	if (!block_in_use(bitmap_blk, sb, bh->b_data)) {
+		/* bad block bitmap */
+		goto error_out;
+	}
+	/* check whether the inode table block number is set */
+	bitmap_blk = le32_to_cpu(desc->bg_inode_table);
+	if (!block_in_use(bitmap_blk, sb, bh->b_data)) {
+		/* bad block bitmap */
+		goto error_out;
+	}
+
 	return bh;
+
+error_out:
+	brelse(bh);
+	ext2_error(sb, "read_block_bitmap",
+			"Invalid block bitmap - "
+			"block_group = %d, block = %u",
+			block_group, bitmap_blk);
+	return NULL;
 }
 
 /*
@@ -583,13 +619,6 @@ unsigned long ext2_count_free_blocks (struct super_block * sb)
 #endif
 }
 
-static inline int
-block_in_use(unsigned long block, struct super_block *sb, unsigned char *map)
-{
-	return ext2_test_bit ((block -
-		le32_to_cpu(EXT2_SB(sb)->s_es->s_first_data_block)) %
-			 EXT2_BLOCKS_PER_GROUP(sb), map);
-}
 
 static inline int test_root(int a, int b)
 {
diff --git a/fs/ext3/balloc.c b/fs/ext3/balloc.c
index ca8aee6..fc5ef29 100644
--- a/fs/ext3/balloc.c
+++ b/fs/ext3/balloc.c
@@ -79,6 +79,13 @@ struct ext3_group_desc * ext3_get_group_desc(struct super_block * sb,
 		*bh = sbi->s_group_desc[group_desc];
 	return desc + offset;
 }
+static inline int
+block_in_use(ext3_fsblk_t block, struct super_block *sb, unsigned char *map)
+{
+	return ext3_test_bit ((block -
+		le32_to_cpu(EXT3_SB(sb)->s_es->s_first_data_block)) %
+			 EXT3_BLOCKS_PER_GROUP(sb), map);
+}
 
 /**
  * read_block_bitmap()
@@ -95,18 +102,46 @@ read_block_bitmap(struct super_block *sb, unsigned int block_group)
 {
 	struct ext3_group_desc * desc;
 	struct buffer_head * bh = NULL;
+	ext3_fsblk_t bitmap_blk;
 
 	desc = ext3_get_group_desc (sb, block_group, NULL);
 	if (!desc)
-		goto error_out;
-	bh = sb_bread(sb, le32_to_cpu(desc->bg_block_bitmap));
+		return NULL;
+	bitmap_blk = le32_to_cpu(desc->bg_block_bitmap);
+	bh = sb_bread(sb, bitmap_blk);
 	if (!bh)
 		ext3_error (sb, "read_block_bitmap",
 			    "Cannot read block bitmap - "
 			    "block_group = %d, block_bitmap = %u",
 			    block_group, le32_to_cpu(desc->bg_block_bitmap));
-error_out:
+
+	/* check whether block bitmap block number is set */
+	if (!block_in_use(bitmap_blk, sb, bh->b_data)) {
+		/* bad block bitmap */
+		goto error_out;
+	}
+	/* check whether the inode bitmap block number is set */
+	bitmap_blk = le32_to_cpu(desc->bg_inode_bitmap);
+	if (!block_in_use(bitmap_blk, sb, bh->b_data)) {
+		/* bad block bitmap */
+		goto error_out;
+	}
+	/* check whether the inode table block number is set */
+	bitmap_blk = le32_to_cpu(desc->bg_inode_table);
+	if (!block_in_use(bitmap_blk, sb, bh->b_data)) {
+		/* bad block bitmap */
+		goto error_out;
+	}
+
 	return bh;
+
+error_out:
+	brelse(bh);
+	ext3_error(sb, "read_block_bitmap",
+			"Invalid block bitmap - "
+			"block_group = %d, block = %lu",
+			block_group, bitmap_blk);
+	return NULL;
 }
 /*
  * The reservation window structure operations
@@ -1733,13 +1768,6 @@ ext3_fsblk_t ext3_count_free_blocks(struct super_block *sb)
 #endif
 }
 
-static inline int
-block_in_use(ext3_fsblk_t block, struct super_block *sb, unsigned char *map)
-{
-	return ext3_test_bit ((block -
-		le32_to_cpu(EXT3_SB(sb)->s_es->s_first_data_block)) %
-			 EXT3_BLOCKS_PER_GROUP(sb), map);
-}
 
 static inline int test_root(int a, int b)
 {
diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c
index 3b64bb1..7986d4e 100644
--- a/fs/ext4/balloc.c
+++ b/fs/ext4/balloc.c
@@ -99,6 +99,15 @@ struct ext4_group_desc * ext4_get_group_desc(struct super_block * sb,
 		*bh = sbi->s_group_desc[group_desc];
 	return desc;
 }
+static inline int
+block_in_use(ext4_fsblk_t block, struct super_block *sb, unsigned char *map)
+{
+	ext4_grpblk_t offset;
+
+	ext4_get_group_no_and_offset(sb, block, NULL, &offset);
+	return ext4_test_bit (offset, map);
+}
+
 
 /**
  * read_block_bitmap()
@@ -115,19 +124,48 @@ read_block_bitmap(struct super_block *sb, unsigned int block_group)
 {
 	struct ext4_group_desc * desc;
 	struct buffer_head * bh = NULL;
+	ext4_fsblk_t bitmap_blk;
 
 	desc = ext4_get_group_desc (sb, block_group, NULL);
 	if (!desc)
-		goto error_out;
-	bh = sb_bread(sb, ext4_block_bitmap(sb, desc));
+		return NULL;
+	bitmap_blk = ext4_block_bitmap(sb, desc);
+	bh = sb_bread(sb, bitmap_blk);
 	if (!bh)
 		ext4_error (sb, "read_block_bitmap",
 			    "Cannot read block bitmap - "
 			    "block_group = %d, block_bitmap = %llu",
-			    block_group,
-			    ext4_block_bitmap(sb, desc));
-error_out:
+			    block_group, bitmap_blk);
+
+	/* check whether block bitmap block number is set */
+	if (!block_in_use(bitmap_blk, sb, bh->b_data)) {
+		/* bad block bitmap */
+		goto error_out;
+	}
+
+	/* check whether the inode bitmap block number is set */
+	bitmap_blk = ext4_inode_bitmap(sb, desc);
+	if (!block_in_use(bitmap_blk, sb, bh->b_data)) {
+		/* bad block bitmap */
+		goto error_out;
+	}
+	/* check whether the inode table block number is set */
+	bitmap_blk = ext4_inode_table(sb, desc);
+	if (!block_in_use(bitmap_blk, sb, bh->b_data)) {
+		/* bad block bitmap */
+		goto error_out;
+	}
+
 	return bh;
+
+error_out:
+	brelse(bh);
+	ext4_error(sb, "read_block_bitmap",
+			"Invalid block bitmap - "
+			"block_group = %d, block = %llu",
+			block_group, bitmap_blk);
+	return NULL;
+
 }
 /*
  * The reservation window structure operations
@@ -1747,15 +1785,6 @@ ext4_fsblk_t ext4_count_free_blocks(struct super_block *sb)
 #endif
 }
 
-static inline int
-block_in_use(ext4_fsblk_t block, struct super_block *sb, unsigned char *map)
-{
-	ext4_grpblk_t offset;
-
-	ext4_get_group_no_and_offset(sb, block, NULL, &offset);
-	return ext4_test_bit (offset, map);
-}
-
 static inline int test_root(int a, int b)
 {
 	int num = b;
-- 
1.5.3.rc0.63.gc956-dirty

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH] ext2/ext3/ext4: Add block bitmap validation
  2007-07-09 18:24 [PATCH] ext2/ext3/ext4: Add block bitmap validation Aneesh Kumar K.V
@ 2007-07-09 19:16 ` Andreas Dilger
  0 siblings, 0 replies; 5+ messages in thread
From: Andreas Dilger @ 2007-07-09 19:16 UTC (permalink / raw)
  To: Aneesh Kumar K.V; +Cc: linux-ext4

On Jul 09, 2007  23:54 +0530, Aneesh Kumar K.V wrote:
> When a new block bitmap is read from disk in read_block_bitmap()
> there are a few bits that should ALWAYS be set. In particular, the
> blocks given by ext4_blk_bitmap, ext4_inode_bitmap and ext4_inode_table.
> Validate the block bitmap against these blocks.

Ah, our emails passed each other...  Mine has the added change that it
checks all of the itable bits, but otherwise it seems we made the same
cleanups.

Cheers, Andreas
--
Andreas Dilger
Principal Software Engineer
Cluster File Systems, Inc.

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH] ext2/ext3/ext4: Add block bitmap validation
@ 2007-07-10  4:43 Aneesh Kumar K.V
  0 siblings, 0 replies; 5+ messages in thread
From: Aneesh Kumar K.V @ 2007-07-10  4:43 UTC (permalink / raw)
  To: linux-ext4; +Cc: cmm, tytso, Aneesh Kumar K.V, Andreas Dilger

When a new block bitmap is read from disk in read_block_bitmap()
there are a few bits that should ALWAYS be set. In particular, the
blocks given by ext4_blk_bitmap, ext4_inode_bitmap and ext4_inode_table.
Validate the block bitmap against these blocks.

Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
Signed-off-by: Andreas Dilger <adilger@clusterfs.com>
---
 fs/ext2/balloc.c |   56 ++++++++++++++++++++++++++++++++++++++----------
 fs/ext3/balloc.c |   53 ++++++++++++++++++++++++++++++++++++---------
 fs/ext4/balloc.c |   62 ++++++++++++++++++++++++++++++++++++++++-------------
 3 files changed, 133 insertions(+), 38 deletions(-)

diff --git a/fs/ext2/balloc.c b/fs/ext2/balloc.c
index baf71dd..917a443 100644
--- a/fs/ext2/balloc.c
+++ b/fs/ext2/balloc.c
@@ -69,6 +69,14 @@ struct ext2_group_desc * ext2_get_group_desc(struct super_block * sb,
 	return desc + offset;
 }
 
+static inline int
+block_in_use(unsigned long block, struct super_block *sb, unsigned char *map)
+{
+	return ext2_test_bit ((block -
+		le32_to_cpu(EXT2_SB(sb)->s_es->s_first_data_block)) %
+			 EXT2_BLOCKS_PER_GROUP(sb), map);
+}
+
 /*
  * Read the bitmap for a given block_group, reading into the specified 
  * slot in the superblock's bitmap cache.
@@ -78,20 +86,51 @@ struct ext2_group_desc * ext2_get_group_desc(struct super_block * sb,
 static struct buffer_head *
 read_block_bitmap(struct super_block *sb, unsigned int block_group)
 {
+	int i;
 	struct ext2_group_desc * desc;
 	struct buffer_head * bh = NULL;
-	
+	unsigned int bitmap_blk;
+
 	desc = ext2_get_group_desc (sb, block_group, NULL);
 	if (!desc)
-		goto error_out;
-	bh = sb_bread(sb, le32_to_cpu(desc->bg_block_bitmap));
+		return NULL;
+	bitmap_blk = le32_to_cpu(desc->bg_block_bitmap);
+	bh = sb_bread(sb, bitmap_blk);
 	if (!bh)
-		ext2_error (sb, "read_block_bitmap",
+		ext2_error (sb, __FUNCTION__,
 			    "Cannot read block bitmap - "
 			    "block_group = %d, block_bitmap = %u",
 			    block_group, le32_to_cpu(desc->bg_block_bitmap));
-error_out:
+
+	/* check whether block bitmap block number is set */
+	if (!block_in_use(bitmap_blk, sb, bh->b_data)) {
+		/* bad block bitmap */
+		goto error_out;
+	}
+	/* check whether the inode bitmap block number is set */
+	bitmap_blk = le32_to_cpu(desc->bg_inode_bitmap);
+	if (!block_in_use(bitmap_blk, sb, bh->b_data)) {
+		/* bad block bitmap */
+		goto error_out;
+	}
+	/* check whether the inode table block number is set */
+	bitmap_blk = le32_to_cpu(desc->bg_inode_table);
+	for (i = 0; i < EXT2_SB(sb)->s_itb_per_group; i++, bitmap_blk++) {
+		if (!block_in_use(bitmap_blk, sb, bh->b_data)) {
+			/* bad block bitmap */
+			goto error_out;
+		}
+	}
+
 	return bh;
+
+error_out:
+	brelse(bh);
+	ext2_error(sb, __FUNCTION__,
+			"Invalid block bitmap - "
+			"block_group = %d, block = %u",
+			block_group, bitmap_blk);
+	return NULL;
 }
 
 /*
@@ -583,13 +622,6 @@ unsigned long ext2_count_free_blocks (struct super_block * sb)
 #endif
 }
 
-static inline int
-block_in_use(unsigned long block, struct super_block *sb, unsigned char *map)
-{
-	return ext2_test_bit ((block -
-		le32_to_cpu(EXT2_SB(sb)->s_es->s_first_data_block)) %
-			 EXT2_BLOCKS_PER_GROUP(sb), map);
-}
 
 static inline int test_root(int a, int b)
 {
diff --git a/fs/ext3/balloc.c b/fs/ext3/balloc.c
index ca8aee6..b44c76f 100644
--- a/fs/ext3/balloc.c
+++ b/fs/ext3/balloc.c
@@ -79,6 +79,13 @@ struct ext3_group_desc * ext3_get_group_desc(struct super_block * sb,
 		*bh = sbi->s_group_desc[group_desc];
 	return desc + offset;
 }
+static inline int
+block_in_use(ext3_fsblk_t block, struct super_block *sb, unsigned char *map)
+{
+	return ext3_test_bit ((block -
+		le32_to_cpu(EXT3_SB(sb)->s_es->s_first_data_block)) %
+			 EXT3_BLOCKS_PER_GROUP(sb), map);
+}
 
 /**
  * read_block_bitmap()
@@ -93,20 +100,51 @@ struct ext3_group_desc * ext3_get_group_desc(struct super_block * sb,
 static struct buffer_head *
 read_block_bitmap(struct super_block *sb, unsigned int block_group)
 {
+	int i;
 	struct ext3_group_desc * desc;
 	struct buffer_head * bh = NULL;
+	ext3_fsblk_t bitmap_blk;
 
 	desc = ext3_get_group_desc (sb, block_group, NULL);
 	if (!desc)
-		goto error_out;
-	bh = sb_bread(sb, le32_to_cpu(desc->bg_block_bitmap));
+		return NULL;
+	bitmap_blk = le32_to_cpu(desc->bg_block_bitmap);
+	bh = sb_bread(sb, bitmap_blk);
 	if (!bh)
-		ext3_error (sb, "read_block_bitmap",
+		ext3_error (sb, __FUNCTION__,
 			    "Cannot read block bitmap - "
 			    "block_group = %d, block_bitmap = %u",
 			    block_group, le32_to_cpu(desc->bg_block_bitmap));
-error_out:
+
+	/* check whether block bitmap block number is set */
+	if (!block_in_use(bitmap_blk, sb, bh->b_data)) {
+		/* bad block bitmap */
+		goto error_out;
+	}
+	/* check whether the inode bitmap block number is set */
+	bitmap_blk = le32_to_cpu(desc->bg_inode_bitmap);
+	if (!block_in_use(bitmap_blk, sb, bh->b_data)) {
+		/* bad block bitmap */
+		goto error_out;
+	}
+	/* check whether the inode table block number is set */
+	bitmap_blk = le32_to_cpu(desc->bg_inode_table);
+	for (i = 0; i < EXT3_SB(sb)->s_itb_per_group; i++, bitmap_blk++) {
+		if (!block_in_use(bitmap_blk, sb, bh->b_data)) {
+			/* bad block bitmap */
+			goto error_out;
+		}
+	}
+
 	return bh;
+
+error_out:
+	brelse(bh);
+	ext3_error(sb, __FUNCTION__,
+			"Invalid block bitmap - "
+			"block_group = %d, block = %lu",
+			block_group, bitmap_blk);
+	return NULL;
 }
 /*
  * The reservation window structure operations
@@ -1733,13 +1771,6 @@ ext3_fsblk_t ext3_count_free_blocks(struct super_block *sb)
 #endif
 }
 
-static inline int
-block_in_use(ext3_fsblk_t block, struct super_block *sb, unsigned char *map)
-{
-	return ext3_test_bit ((block -
-		le32_to_cpu(EXT3_SB(sb)->s_es->s_first_data_block)) %
-			 EXT3_BLOCKS_PER_GROUP(sb), map);
-}
 
 static inline int test_root(int a, int b)
 {
diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c
index 3b64bb1..7d58f12 100644
--- a/fs/ext4/balloc.c
+++ b/fs/ext4/balloc.c
@@ -99,6 +99,15 @@ struct ext4_group_desc * ext4_get_group_desc(struct super_block * sb,
 		*bh = sbi->s_group_desc[group_desc];
 	return desc;
 }
+static inline int
+block_in_use(ext4_fsblk_t block, struct super_block *sb, unsigned char *map)
+{
+	ext4_grpblk_t offset;
+
+	ext4_get_group_no_and_offset(sb, block, NULL, &offset);
+	return ext4_test_bit (offset, map);
+}
+
 
 /**
  * read_block_bitmap()
@@ -113,21 +122,53 @@ struct ext4_group_desc * ext4_get_group_desc(struct super_block * sb,
 static struct buffer_head *
 read_block_bitmap(struct super_block *sb, unsigned int block_group)
 {
+	int i;
 	struct ext4_group_desc * desc;
 	struct buffer_head * bh = NULL;
+	ext4_fsblk_t bitmap_blk;
 
 	desc = ext4_get_group_desc (sb, block_group, NULL);
 	if (!desc)
-		goto error_out;
-	bh = sb_bread(sb, ext4_block_bitmap(sb, desc));
+		return NULL;
+	bitmap_blk = ext4_block_bitmap(sb, desc);
+	bh = sb_bread(sb, bitmap_blk);
 	if (!bh)
-		ext4_error (sb, "read_block_bitmap",
+		ext4_error (sb, __FUNCTION__,
 			    "Cannot read block bitmap - "
 			    "block_group = %d, block_bitmap = %llu",
-			    block_group,
-			    ext4_block_bitmap(sb, desc));
-error_out:
+			    block_group, bitmap_blk);
+
+	/* check whether block bitmap block number is set */
+	if (!block_in_use(bitmap_blk, sb, bh->b_data)) {
+		/* bad block bitmap */
+		goto error_out;
+	}
+
+	/* check whether the inode bitmap block number is set */
+	bitmap_blk = ext4_inode_bitmap(sb, desc);
+	if (!block_in_use(bitmap_blk, sb, bh->b_data)) {
+		/* bad block bitmap */
+		goto error_out;
+	}
+	/* check whether the inode table block number is set */
+	bitmap_blk = ext4_inode_table(sb, desc);
+	for (i = 0; i < EXT4_SB(sb)->s_itb_per_group; i++, bitmap_blk++) {
+		if (!block_in_use(bitmap_blk, sb, bh->b_data)) {
+			/* bad block bitmap */
+			goto error_out;
+		}
+	}
+
 	return bh;
+
+error_out:
+	brelse(bh);
+	ext4_error(sb, __FUNCTION__,
+			"Invalid block bitmap - "
+			"block_group = %d, block = %llu",
+			block_group, bitmap_blk);
+	return NULL;
+
 }
 /*
  * The reservation window structure operations
@@ -1747,15 +1788,6 @@ ext4_fsblk_t ext4_count_free_blocks(struct super_block *sb)
 #endif
 }
 
-static inline int
-block_in_use(ext4_fsblk_t block, struct super_block *sb, unsigned char *map)
-{
-	ext4_grpblk_t offset;
-
-	ext4_get_group_no_and_offset(sb, block, NULL, &offset);
-	return ext4_test_bit (offset, map);
-}
-
 static inline int test_root(int a, int b)
 {
 	int num = b;
-- 
1.5.3.rc0.63.gc956-dirty

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH] ext2/ext3/ext4: Add block bitmap validation
@ 2007-08-03  7:10 Aneesh Kumar K.V
  2007-08-03  7:44 ` Kalpak Shah
  0 siblings, 1 reply; 5+ messages in thread
From: Aneesh Kumar K.V @ 2007-08-03  7:10 UTC (permalink / raw)
  To: cmm; +Cc: linux-ext4, Aneesh Kumar K.V, Andreas Dilger

When a new block bitmap is read from disk in read_block_bitmap()
there are a few bits that should ALWAYS be set. In particular, the
blocks given by ext4_blk_bitmap, ext4_inode_bitmap and ext4_inode_table.
Validate the block bitmap against these blocks.

Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
Signed-off-by: Andreas Dilger <adilger@clusterfs.com>
---
 fs/ext2/balloc.c |   56 ++++++++++++++++++++++++++++++++++++++----------
 fs/ext3/balloc.c |   53 ++++++++++++++++++++++++++++++++++++---------
 fs/ext4/balloc.c |   62 ++++++++++++++++++++++++++++++++++++++++-------------
 3 files changed, 133 insertions(+), 38 deletions(-)

diff --git a/fs/ext2/balloc.c b/fs/ext2/balloc.c
index baf71dd..917a443 100644
--- a/fs/ext2/balloc.c
+++ b/fs/ext2/balloc.c
@@ -69,6 +69,14 @@ struct ext2_group_desc * ext2_get_group_desc(struct super_block * sb,
 	return desc + offset;
 }
 
+static inline int
+block_in_use(unsigned long block, struct super_block *sb, unsigned char *map)
+{
+	return ext2_test_bit ((block -
+		le32_to_cpu(EXT2_SB(sb)->s_es->s_first_data_block)) %
+			 EXT2_BLOCKS_PER_GROUP(sb), map);
+}
+
 /*
  * Read the bitmap for a given block_group, reading into the specified 
  * slot in the superblock's bitmap cache.
@@ -78,20 +86,51 @@ struct ext2_group_desc * ext2_get_group_desc(struct super_block * sb,
 static struct buffer_head *
 read_block_bitmap(struct super_block *sb, unsigned int block_group)
 {
+	int i;
 	struct ext2_group_desc * desc;
 	struct buffer_head * bh = NULL;
-	
+	unsigned int bitmap_blk;
+
 	desc = ext2_get_group_desc (sb, block_group, NULL);
 	if (!desc)
-		goto error_out;
-	bh = sb_bread(sb, le32_to_cpu(desc->bg_block_bitmap));
+		return NULL;
+	bitmap_blk = le32_to_cpu(desc->bg_block_bitmap);
+	bh = sb_bread(sb, bitmap_blk);
 	if (!bh)
-		ext2_error (sb, "read_block_bitmap",
+		ext2_error (sb, __FUNCTION__,
 			    "Cannot read block bitmap - "
 			    "block_group = %d, block_bitmap = %u",
 			    block_group, le32_to_cpu(desc->bg_block_bitmap));
-error_out:
+
+	/* check whether block bitmap block number is set */
+	if (!block_in_use(bitmap_blk, sb, bh->b_data)) {
+		/* bad block bitmap */
+		goto error_out;
+	}
+	/* check whether the inode bitmap block number is set */
+	bitmap_blk = le32_to_cpu(desc->bg_inode_bitmap);
+	if (!block_in_use(bitmap_blk, sb, bh->b_data)) {
+		/* bad block bitmap */
+		goto error_out;
+	}
+	/* check whether the inode table block number is set */
+	bitmap_blk = le32_to_cpu(desc->bg_inode_table);
+	for (i = 0; i < EXT2_SB(sb)->s_itb_per_group; i++, bitmap_blk++) {
+		if (!block_in_use(bitmap_blk, sb, bh->b_data)) {
+			/* bad block bitmap */
+			goto error_out;
+		}
+	}
+
 	return bh;
+
+error_out:
+	brelse(bh);
+	ext2_error(sb, __FUNCTION__,
+			"Invalid block bitmap - "
+			"block_group = %d, block = %u",
+			block_group, bitmap_blk);
+	return NULL;
 }
 
 /*
@@ -583,13 +622,6 @@ unsigned long ext2_count_free_blocks (struct super_block * sb)
 #endif
 }
 
-static inline int
-block_in_use(unsigned long block, struct super_block *sb, unsigned char *map)
-{
-	return ext2_test_bit ((block -
-		le32_to_cpu(EXT2_SB(sb)->s_es->s_first_data_block)) %
-			 EXT2_BLOCKS_PER_GROUP(sb), map);
-}
 
 static inline int test_root(int a, int b)
 {
diff --git a/fs/ext3/balloc.c b/fs/ext3/balloc.c
index ca8aee6..b44c76f 100644
--- a/fs/ext3/balloc.c
+++ b/fs/ext3/balloc.c
@@ -79,6 +79,13 @@ struct ext3_group_desc * ext3_get_group_desc(struct super_block * sb,
 		*bh = sbi->s_group_desc[group_desc];
 	return desc + offset;
 }
+static inline int
+block_in_use(ext3_fsblk_t block, struct super_block *sb, unsigned char *map)
+{
+	return ext3_test_bit ((block -
+		le32_to_cpu(EXT3_SB(sb)->s_es->s_first_data_block)) %
+			 EXT3_BLOCKS_PER_GROUP(sb), map);
+}
 
 /**
  * read_block_bitmap()
@@ -93,20 +100,51 @@ struct ext3_group_desc * ext3_get_group_desc(struct super_block * sb,
 static struct buffer_head *
 read_block_bitmap(struct super_block *sb, unsigned int block_group)
 {
+	int i;
 	struct ext3_group_desc * desc;
 	struct buffer_head * bh = NULL;
+	ext3_fsblk_t bitmap_blk;
 
 	desc = ext3_get_group_desc (sb, block_group, NULL);
 	if (!desc)
-		goto error_out;
-	bh = sb_bread(sb, le32_to_cpu(desc->bg_block_bitmap));
+		return NULL;
+	bitmap_blk = le32_to_cpu(desc->bg_block_bitmap);
+	bh = sb_bread(sb, bitmap_blk);
 	if (!bh)
-		ext3_error (sb, "read_block_bitmap",
+		ext3_error (sb, __FUNCTION__,
 			    "Cannot read block bitmap - "
 			    "block_group = %d, block_bitmap = %u",
 			    block_group, le32_to_cpu(desc->bg_block_bitmap));
-error_out:
+
+	/* check whether block bitmap block number is set */
+	if (!block_in_use(bitmap_blk, sb, bh->b_data)) {
+		/* bad block bitmap */
+		goto error_out;
+	}
+	/* check whether the inode bitmap block number is set */
+	bitmap_blk = le32_to_cpu(desc->bg_inode_bitmap);
+	if (!block_in_use(bitmap_blk, sb, bh->b_data)) {
+		/* bad block bitmap */
+		goto error_out;
+	}
+	/* check whether the inode table block number is set */
+	bitmap_blk = le32_to_cpu(desc->bg_inode_table);
+	for (i = 0; i < EXT3_SB(sb)->s_itb_per_group; i++, bitmap_blk++) {
+		if (!block_in_use(bitmap_blk, sb, bh->b_data)) {
+			/* bad block bitmap */
+			goto error_out;
+		}
+	}
+
 	return bh;
+
+error_out:
+	brelse(bh);
+	ext3_error(sb, __FUNCTION__,
+			"Invalid block bitmap - "
+			"block_group = %d, block = %lu",
+			block_group, bitmap_blk);
+	return NULL;
 }
 /*
  * The reservation window structure operations
@@ -1733,13 +1771,6 @@ ext3_fsblk_t ext3_count_free_blocks(struct super_block *sb)
 #endif
 }
 
-static inline int
-block_in_use(ext3_fsblk_t block, struct super_block *sb, unsigned char *map)
-{
-	return ext3_test_bit ((block -
-		le32_to_cpu(EXT3_SB(sb)->s_es->s_first_data_block)) %
-			 EXT3_BLOCKS_PER_GROUP(sb), map);
-}
 
 static inline int test_root(int a, int b)
 {
diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c
index 3b64bb1..7d58f12 100644
--- a/fs/ext4/balloc.c
+++ b/fs/ext4/balloc.c
@@ -99,6 +99,15 @@ struct ext4_group_desc * ext4_get_group_desc(struct super_block * sb,
 		*bh = sbi->s_group_desc[group_desc];
 	return desc;
 }
+static inline int
+block_in_use(ext4_fsblk_t block, struct super_block *sb, unsigned char *map)
+{
+	ext4_grpblk_t offset;
+
+	ext4_get_group_no_and_offset(sb, block, NULL, &offset);
+	return ext4_test_bit (offset, map);
+}
+
 
 /**
  * read_block_bitmap()
@@ -113,21 +122,53 @@ struct ext4_group_desc * ext4_get_group_desc(struct super_block * sb,
 static struct buffer_head *
 read_block_bitmap(struct super_block *sb, unsigned int block_group)
 {
+	int i;
 	struct ext4_group_desc * desc;
 	struct buffer_head * bh = NULL;
+	ext4_fsblk_t bitmap_blk;
 
 	desc = ext4_get_group_desc (sb, block_group, NULL);
 	if (!desc)
-		goto error_out;
-	bh = sb_bread(sb, ext4_block_bitmap(sb, desc));
+		return NULL;
+	bitmap_blk = ext4_block_bitmap(sb, desc);
+	bh = sb_bread(sb, bitmap_blk);
 	if (!bh)
-		ext4_error (sb, "read_block_bitmap",
+		ext4_error (sb, __FUNCTION__,
 			    "Cannot read block bitmap - "
 			    "block_group = %d, block_bitmap = %llu",
-			    block_group,
-			    ext4_block_bitmap(sb, desc));
-error_out:
+			    block_group, bitmap_blk);
+
+	/* check whether block bitmap block number is set */
+	if (!block_in_use(bitmap_blk, sb, bh->b_data)) {
+		/* bad block bitmap */
+		goto error_out;
+	}
+
+	/* check whether the inode bitmap block number is set */
+	bitmap_blk = ext4_inode_bitmap(sb, desc);
+	if (!block_in_use(bitmap_blk, sb, bh->b_data)) {
+		/* bad block bitmap */
+		goto error_out;
+	}
+	/* check whether the inode table block number is set */
+	bitmap_blk = ext4_inode_table(sb, desc);
+	for (i = 0; i < EXT4_SB(sb)->s_itb_per_group; i++, bitmap_blk++) {
+		if (!block_in_use(bitmap_blk, sb, bh->b_data)) {
+			/* bad block bitmap */
+			goto error_out;
+		}
+	}
+
 	return bh;
+
+error_out:
+	brelse(bh);
+	ext4_error(sb, __FUNCTION__,
+			"Invalid block bitmap - "
+			"block_group = %d, block = %llu",
+			block_group, bitmap_blk);
+	return NULL;
+
 }
 /*
  * The reservation window structure operations
@@ -1747,15 +1788,6 @@ ext4_fsblk_t ext4_count_free_blocks(struct super_block *sb)
 #endif
 }
 
-static inline int
-block_in_use(ext4_fsblk_t block, struct super_block *sb, unsigned char *map)
-{
-	ext4_grpblk_t offset;
-
-	ext4_get_group_no_and_offset(sb, block, NULL, &offset);
-	return ext4_test_bit (offset, map);
-}
-
 static inline int test_root(int a, int b)
 {
 	int num = b;
-- 
1.5.3.rc2.22.g69a9b-dirty

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH] ext2/ext3/ext4: Add block bitmap validation
  2007-08-03  7:10 Aneesh Kumar K.V
@ 2007-08-03  7:44 ` Kalpak Shah
  0 siblings, 0 replies; 5+ messages in thread
From: Kalpak Shah @ 2007-08-03  7:44 UTC (permalink / raw)
  To: Aneesh Kumar K.V; +Cc: cmm, linux-ext4, Andreas Dilger

On Fri, 2007-08-03 at 12:40 +0530, Aneesh Kumar K.V wrote:
>  	desc = ext2_get_group_desc (sb, block_group, NULL);
>  	if (!desc)
> -		goto error_out;
> -	bh = sb_bread(sb, le32_to_cpu(desc->bg_block_bitmap));
> +		return NULL;
> +	bitmap_blk = le32_to_cpu(desc->bg_block_bitmap);
> +	bh = sb_bread(sb, bitmap_blk);
>  	if (!bh)
> -		ext2_error (sb, "read_block_bitmap",
> +		ext2_error (sb, __FUNCTION__,
>  			    "Cannot read block bitmap - "
>  			    "block_group = %d, block_bitmap = %u",
>  			    block_group, le32_to_cpu(desc->bg_block_bitmap));

bitmap_blk should be used here instead of
le32_to_cpu(desc->bg_block_bitmap). It reduces one endianness
conversion.

> -error_out:
> +
> +	/* check whether block bitmap block number is set */
> +	if (!block_in_use(bitmap_blk, sb, bh->b_data)) {
> +		/* bad block bitmap */
> +		goto error_out;
> +	}
> +	/* check whether the inode bitmap block number is set */
> +	bitmap_blk = le32_to_cpu(desc->bg_inode_bitmap);
> +	if (!block_in_use(bitmap_blk, sb, bh->b_data)) {
> +		/* bad block bitmap */
> +		goto error_out;
> +	}
> +	/* check whether the inode table block number is set */
> +	bitmap_blk = le32_to_cpu(desc->bg_inode_table);
> +	for (i = 0; i < EXT2_SB(sb)->s_itb_per_group; i++, bitmap_blk++) {
> +		if (!block_in_use(bitmap_blk, sb, bh->b_data)) {
> +			/* bad block bitmap */
> +			goto error_out;
> +		}
> +	}

Why not reduce a lot of this code by having:
int block_range_in_use(ext4_fsblk_t start_blk, ext4_fsblk_t num_blks,
struct super_block *sb, unsigned char *map)?

It will also help to do away with a lot of repetitive calculations in
block_in_use().

> +	ext3_error(sb, __FUNCTION__,
> +			"Invalid block bitmap - "
> +			"block_group = %d, block = %lu",
> +			block_group, bitmap_blk);

Please align this according to kernel coding style.

Thanks,
Kalpak.

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2007-08-03  7:42 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-07-09 18:24 [PATCH] ext2/ext3/ext4: Add block bitmap validation Aneesh Kumar K.V
2007-07-09 19:16 ` Andreas Dilger
  -- strict thread matches above, loose matches on Subject: below --
2007-07-10  4:43 Aneesh Kumar K.V
2007-08-03  7:10 Aneesh Kumar K.V
2007-08-03  7:44 ` Kalpak Shah

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).