Description: Fix stack out-of-bounds write / recursion with large di_height (CVE-2026-71220)
 In gfs2_edit, the on-disk di_height field (an unbounded uint16_t read
 from untrusted filesystem metadata) is used without bounds checking.
 .
 In metapath_to_lblock() in gfs2/edit/extended.c it is used as an index
 into the stack array factor[GFS2_MAX_META_HEIGHT]
 (factor[height - 1] = 1ull), causing a stack buffer overflow that may
 lead to arbitrary code execution.
 .
 In display_indirect() the same unbounded di_height value drives the
 recursion into print_block_details()/display_indirect() and the
 mp.mp_list[cur_height + 1] indexing, so a crafted image with a large
 di_height causes deep recursion (stack exhaustion) and an out-of-bounds
 write when processed by gfs2_edit.
 .
 Validate that di_height does not exceed GFS2_MAX_META_HEIGHT before using
 it as an array index, and cap the display recursion depth so that the
 metapath index stays in bounds.
Author: Valentin Vidic <vvidic@debian.org>
Last-Update: 2026-10-06
---
This patch header follows DEP-3: http://dep.debian.net/deps/dep3/
--- a/gfs2/edit/extended.c
+++ b/gfs2/edit/extended.c
@@ -105,6 +105,12 @@ static uint64_t metapath_to_lblock(struct lgfs2_metapath *mp, int hgt)
 
 	if (height < 2)
 		return mp->mp_list[0];
+	if (height > GFS2_MAX_META_HEIGHT) {
+		fprintf(stderr, "Invalid metadata height %u (maximum is %u); "
+			"ignoring it.\n", (unsigned)height,
+			(unsigned)GFS2_MAX_META_HEIGHT);
+		return mp->mp_list[0];
+	}
 	/* figure out multiplication factors for each height */
 	memset(&factor, 0, sizeof(factor));
 	factor[height - 1] = 1ull;
@@ -210,6 +216,7 @@ static int display_indirect(struct iinfo *ind, int indblocks, int level,
 		else
 			file_offset = 0;
 		if (dinode_valid() && !termlines &&
+		    level < GFS2_MAX_META_HEIGHT - 1 &&
 		    ((level + 1 < be16_to_cpu(di->di_height)) ||
 		     (S_ISDIR(be32_to_cpu(di->di_mode)) && level <= be16_to_cpu(di->di_height)))) {
 			print_block_details(ind, level, cur_height, pndx,
