lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [day] [month] [year] [list]
Date:   Fri, 18 Mar 2022 00:26:15 +0800
From:   zhanchengbin <zhanchengbin1@...wei.com>
To:     Theodore Ts'o <tytso@....edu>
CC:     <linux-ext4@...r.kernel.org>, <liuzhiqiang26@...wei.com>,
        linfeilong <linfeilong@...wei.com>
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 <zhanchengbin1@...wei.com>
Signed-off-by: Zhiqiang Liu <liuzhiqiang26@...wei.com>
---
  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

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ