2022-03-17 20:32:32

by zhanchengbin

[permalink] [raw]
Subject: [PATCH] e2fsck: handle->level is overflow in scan_extent_node

In function check_blocks_extents, program call scan_extent_node
recursively until
leaf extent is found, and if this leaf extent is the last one in this
extent_idx,
it will delete the parent extent_idx of this leaf extent in
ext2fs_extent_delete,
and do handle->level--. After scan_extent_node return, program allways
to get up extent,
but level was already decreased.
So calling ext2fs_extent_get(EXT2_EXTENT_UP) again will return
EXT2_ET_EXTENT_NO_UP,
and then print failed.

Signed-off-by: zhanchengbin <[email protected]>
Signed-off-by: Zhiqiang Liu <[email protected]>
---
e2fsck/pass1.c | 18 +++++++++++-------
lib/ext2fs/ext2fs.h | 1 +
lib/ext2fs/extent.c | 5 +++++
3 files changed, 17 insertions(+), 7 deletions(-)

diff --git a/e2fsck/pass1.c b/e2fsck/pass1.c
index 26b9ab71..e4395709 100644
--- a/e2fsck/pass1.c
+++ b/e2fsck/pass1.c
@@ -3050,6 +3050,7 @@ report_problem:
goto report_problem;
return;
}
+ int level_bak = ext2fs_current_level_get(ehandle);
/* The next extent should match this index's logical start */
if (extent.e_lblk != lblk) {
struct ext2_extent_info e_info;
@@ -3079,14 +3080,17 @@ report_problem:
next_try_repairs);
if (pctx->errcode)
return;
- pctx->errcode = ext2fs_extent_get(ehandle,
- EXT2_EXTENT_UP, &extent);
- if (pctx->errcode) {
- pctx->str = "EXT2_EXTENT_UP";
- return;
+
+ if (level_bak == ext2fs_current_level_get(ehandle)) {
+ pctx->errcode = ext2fs_extent_get(ehandle,
+ EXT2_EXTENT_UP, &extent);
+ if (pctx->errcode) {
+ pctx->str = "EXT2_EXTENT_UP";
+ return;
+ }
+ mark_block_used(ctx, blk);
+ pb->num_blocks++;
}
- mark_block_used(ctx, blk);
- pb->num_blocks++;
goto next;
}

diff --git a/lib/ext2fs/ext2fs.h b/lib/ext2fs/ext2fs.h
index 68f9c1fe..d0468f11 100644
--- a/lib/ext2fs/ext2fs.h
+++ b/lib/ext2fs/ext2fs.h
@@ -1333,6 +1333,7 @@ extern errcode_t ext2fs_extent_open2(ext2_filsys
fs, ext2_ino_t ino,
extern void ext2fs_extent_free(ext2_extent_handle_t handle);
extern errcode_t ext2fs_extent_get(ext2_extent_handle_t handle,
int flags, struct ext2fs_extent *extent);
+extern int ext2fs_current_level_get(ext2_extent_handle_t handle);
extern errcode_t ext2fs_extent_node_split(ext2_extent_handle_t handle);
extern errcode_t ext2fs_extent_replace(ext2_extent_handle_t handle,
int flags,
struct ext2fs_extent *extent);
diff --git a/lib/ext2fs/extent.c b/lib/ext2fs/extent.c
index b324c7b0..07acd4e0 100644
--- a/lib/ext2fs/extent.c
+++ b/lib/ext2fs/extent.c
@@ -575,6 +575,11 @@ retry:
return 0;
}

+int ext2fs_current_level_get(ext2_extent_handle_t handle)
+{
+ return handle->level;
+}
+
static errcode_t update_path(ext2_extent_handle_t handle)
{
blk64_t blk;
--
2.27.0