pctx->blk = blk;
pctx->errcode = ext2fs_read_ext_attr3(fs, blk, block_buf, pctx->ino);
if (pctx->errcode == EXT2_ET_EXT_ATTR_CSUM_INVALID) {
- if (fix_problem(ctx, PR_1_EA_BLOCK_CSUM_INVALID, pctx))
- goto clear_extattr;
+ pctx->errcode = 0;
failed_csum = 1;
- }
- if (pctx->errcode && fix_problem(ctx, PR_1_READ_EA_BLOCK, pctx))
+ } else if (pctx->errcode == EXT2_ET_BAD_EA_HEADER)
+ pctx->errcode = 0;
+
+ if (pctx->errcode &&
+ fix_problem(ctx, PR_1_READ_EA_BLOCK, pctx)) {
+ pctx->errcode = 0;
goto clear_extattr;
+ }
header = (struct ext2_ext_attr_header *) block_buf;
pctx->blk = ext2fs_file_acl_block(fs, inode);
if (((ctx->ext_attr_ver == 1) &&
goto clear_extattr;
}
+ if (pctx->errcode && fix_problem(ctx, PR_1_READ_EA_BLOCK, pctx))
+ goto clear_extattr;
+
region = region_create(0, fs->blocksize);
if (!region) {
fix_problem(ctx, PR_1_EA_ALLOC_REGION_ABORT, pctx);
}
}
- if (ext2fs_file_acl_block(fs, inode) &&
- check_ext_attr(ctx, pctx, block_buf)) {
+ if (check_ext_attr(ctx, pctx, block_buf)) {
if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
goto out;
pb.num_blocks++;
"extent\n\t(logical @b %c, @n physical @b %b, len %N)\n"),
PROMPT_FIX, 0 },
- /* Inode extended attribute block checksum does not match block. */
- { PR_1_EA_BLOCK_CSUM_INVALID,
- N_("@i %i @a @b %b checksum does not match block. "),
- PROMPT_CLEAR, 0 },
-
/*
* Inode extended attribute block passes checks, but checksum does not
* match block.
/* extent block passes checks, but checksum does not match extent block */
#define PR_1_EXTENT_ONLY_CSUM_INVALID 0x01006A
-/* ea block checksum invalid */
-#define PR_1_EA_BLOCK_CSUM_INVALID 0x01006B
-
/* ea block passes checks, but checksum invalid */
#define PR_1_EA_BLOCK_ONLY_CSUM_INVALID 0x01006C
return hash;
}
+static errcode_t check_ext_attr_header(struct ext2_ext_attr_header *header)
+{
+ if ((header->h_magic != EXT2_EXT_ATTR_MAGIC_v1 &&
+ header->h_magic != EXT2_EXT_ATTR_MAGIC) ||
+ header->h_blocks != 1)
+ return EXT2_ET_BAD_EA_HEADER;
+
+ return 0;
+}
+
#undef NAME_HASH_SHIFT
#undef VALUE_HASH_SHIFT
errcode_t ext2fs_read_ext_attr3(ext2_filsys fs, blk64_t block, void *buf,
ext2_ino_t inum)
{
+ int csum_failed = 0;
errcode_t retval;
retval = io_channel_read_blk64(fs->io, block, 1, buf);
if (!(fs->flags & EXT2_FLAG_IGNORE_CSUM_ERRORS) &&
!ext2fs_ext_attr_block_csum_verify(fs, inum, block, buf))
- retval = EXT2_ET_EXT_ATTR_CSUM_INVALID;
+ csum_failed = 1;
#ifdef WORDS_BIGENDIAN
ext2fs_swap_ext_attr(buf, buf, fs->blocksize, 1);
#endif
+ retval = check_ext_attr_header(buf);
+ if (retval == 0 && csum_failed)
+ retval = EXT2_ET_EXT_ATTR_CSUM_INVALID;
+
return retval;
}
if (err)
goto out2;
+ /* We only know how to deal with v2 EA blocks */
header = (struct ext2_ext_attr_header *) block_buf;
if (header->h_magic != EXT2_EXT_ATTR_MAGIC) {
err = EXT2_ET_BAD_EA_HEADER;
if (err)
goto out2;
+ /* We only know how to deal with v2 EA blocks */
header = (struct ext2_ext_attr_header *) block_buf;
if (header->h_magic != EXT2_EXT_ATTR_MAGIC) {
err = EXT2_ET_BAD_EA_HEADER;
if (err)
goto out3;
+ /* We only know how to deal with v2 EA blocks */
header = (struct ext2_ext_attr_header *) block_buf;
if (header->h_magic != EXT2_EXT_ATTR_MAGIC) {
err = EXT2_ET_BAD_EA_HEADER;
goto out3;
}
- if (header->h_blocks != 1) {
- err = EXT2_ET_BAD_EA_HEADER;
- goto out3;
- }
-
/* Read EAs */
storage_size = handle->fs->blocksize -
sizeof(struct ext2_ext_attr_header);