[2/2] ext4: always verify the magic number in xattr blocks

Message ID 20180613045205.19240-2-tytso@mit.edu
State New
Headers show
Series
  • [1/2] ext4: add corruption check in ext4_xattr_set_entry()
Related show

Commit Message

Theodore Y. Ts'o June 13, 2018, 4:52 a.m.
If there an inode points to a block which is also some other type of
metadata block (such as a block allocation bitmap), the
buffer_verified flag can be set when it was validated as that other
metadata block type; however, it would make a really terrible external
attribute block.  The reason why we use the verified flag is to avoid
constantly reverifying the block.  However, it doesn't take much
overhead to make sure the magic number of the xattr block is correct,
and this will avoid potential crashes.

https://bugzilla.kernel.org/show_bug.cgi?id=200001
https://bugzilla.kernel.org/show_bug.cgi?id=199997

Signed-off-by: Theodore Ts'o <tytso@mit.edu>
---
 fs/ext4/xattr.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

Comments

Andreas Dilger June 13, 2018, 5:12 a.m. | #1
On Jun 12, 2018, at 10:52 PM, Theodore Ts'o <tytso@mit.edu> wrote:
> 
> If there an inode points to a block which is also some other type of
> metadata block (such as a block allocation bitmap), the
> buffer_verified flag can be set when it was validated as that other
> metadata block type; however, it would make a really terrible external
> attribute block.  The reason why we use the verified flag is to avoid
> constantly reverifying the block.  However, it doesn't take much
> overhead to make sure the magic number of the xattr block is correct,
> and this will avoid potential crashes.
> 
> https://bugzilla.kernel.org/show_bug.cgi?id=200001
> https://bugzilla.kernel.org/show_bug.cgi?id=199997
> 
> Signed-off-by: Theodore Ts'o <tytso@mit.edu>

This also could be a problem with other incorrectly-shared blocks that
use the verified flag (e.g. directory leaf blocks), etc.  Should we
separate these into BH_verified_dir, BH_verified_ibmap, BH_verified_bbmap,
and BH_verified_xattr to avoid the potential conflicts?

It looks like we still have enough free bits to handle this.

That said, this patch is still an improvement over the current state.

Reviewed-by: Andreas Dilger <adilger@dilger.ca>

> ---
> fs/ext4/xattr.c | 6 +++---
> 1 file changed, 3 insertions(+), 3 deletions(-)
> 
> diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c
> index 230ba79715f6..0263692979ec 100644
> --- a/fs/ext4/xattr.c
> +++ b/fs/ext4/xattr.c
> @@ -230,12 +230,12 @@ __ext4_xattr_check_block(struct inode *inode, struct buffer_head *bh,
> {
> 	int error = -EFSCORRUPTED;
> 
> -	if (buffer_verified(bh))
> -		return 0;
> -
> 	if (BHDR(bh)->h_magic != cpu_to_le32(EXT4_XATTR_MAGIC) ||
> 	    BHDR(bh)->h_blocks != cpu_to_le32(1))
> 		goto errout;
> +	if (buffer_verified(bh))
> +		return 0;
> +
> 	error = -EFSBADCRC;
> 	if (!ext4_xattr_block_csum_verify(inode, bh))
> 		goto errout;
> --
> 2.18.0.rc0
> 


Cheers, Andreas
Theodore Y. Ts'o June 13, 2018, 5:26 a.m. | #2
On Tue, Jun 12, 2018 at 11:12:02PM -0600, Andreas Dilger wrote:
> 
> This also could be a problem with other incorrectly-shared blocks that
> use the verified flag (e.g. directory leaf blocks), etc.  Should we
> separate these into BH_verified_dir, BH_verified_ibmap, BH_verified_bbmap,
> and BH_verified_xattr to avoid the potential conflicts?

That thought did cross my mind.  It's more bits than that, though,
since we also have extent tree blocks (and do we distinguish between
leaf and interior node blocks, etc.)

On the other hand we can detect some of these conflicts by using the
block_validity test (since allocation bitmaps are fixed metadata), and
a some of these metadata blocks (but not all) have magic numbers at
the beginning of each block which can be used to disambiguate them.

Or we could steal some bits from b_this_page or b_page (which would
never be used in metadata buffer heads) to simply stash a block type.
I'm somewhat more partial to that solution, myself.

					- Ted

Patch

diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c
index 230ba79715f6..0263692979ec 100644
--- a/fs/ext4/xattr.c
+++ b/fs/ext4/xattr.c
@@ -230,12 +230,12 @@  __ext4_xattr_check_block(struct inode *inode, struct buffer_head *bh,
 {
 	int error = -EFSCORRUPTED;
 
-	if (buffer_verified(bh))
-		return 0;
-
 	if (BHDR(bh)->h_magic != cpu_to_le32(EXT4_XATTR_MAGIC) ||
 	    BHDR(bh)->h_blocks != cpu_to_le32(1))
 		goto errout;
+	if (buffer_verified(bh))
+		return 0;
+
 	error = -EFSBADCRC;
 	if (!ext4_xattr_block_csum_verify(inode, bh))
 		goto errout;