commit 54c0b9b9dbf72467f099291950680ff8270b02ad
Author: Samuel Thibault <samuel.thibault@ens-lyon.org>
Date:   Thu Mar 13 21:22:24 2025 +0100

    ext2fs: Trap trying to access bogus data areas
    
    i.e. superblock, block group descriptor table or beyond the end.

diff --git a/ext2fs/balloc.c b/ext2fs/balloc.c
index 14c18b5d..fc09c0d1 100644
--- a/ext2fs/balloc.c
+++ b/ext2fs/balloc.c
@@ -63,6 +63,10 @@ ext2_free_blocks (block_t block, unsigned long count)
   unsigned long i;
   struct ext2_group_desc *gdp;
 
+  /* Trap trying to free superblock, block group descriptor table, or beyond the end */
+  assert_backtrace (block >= group_desc_block_end
+		 && block < store->size >> log2_block_size);
+
   pthread_spin_lock (&global_lock);
 
   if (block < le32toh (sblock->s_first_data_block) ||
@@ -402,6 +406,10 @@ got_block:
   pthread_spin_unlock (&global_lock);
   alloc_sync (0);
 
+  /* Trap trying to allocate superblock, block group descriptor table, or beyond the end */
+  assert_backtrace (j >= group_desc_block_end
+		 && j < store->size >> log2_block_size);
+
   return j;
 }
 
diff --git a/ext2fs/ext2fs.h b/ext2fs/ext2fs.h
index 99e93555..62ee9f77 100644
--- a/ext2fs/ext2fs.h
+++ b/ext2fs/ext2fs.h
@@ -405,6 +405,10 @@ bptr_offs (void *ptr)
 #define group_desc(num)	(&group_desc_image[num])
 extern struct ext2_group_desc *group_desc_image;
 
+#define group_desc_block (boffs_block (SBLOCK_OFFS) + 1)
+#define group_desc_size (groups_count * sizeof(struct ext2_group_desc))
+#define group_desc_block_end (group_desc_block + boffs_block(round_block(group_desc_size)))
+
 #define inode_group_num(inum) (((inum) - 1) / le32toh (sblock->s_inodes_per_group))
 
 /* Forward declarations for the following functions that are usually
diff --git a/ext2fs/getblk.c b/ext2fs/getblk.c
index 00a35135..7c94d87f 100644
--- a/ext2fs/getblk.c
+++ b/ext2fs/getblk.c
@@ -98,6 +98,10 @@ ext2_alloc_block (struct node *node, block_t goal, int zero)
 	 &diskfs_node_disknode (node)->info.i_prealloc_count,
 	 &diskfs_node_disknode (node)->info.i_prealloc_block);
     }
+
+  /* Trap trying to allocate superblock, block group descriptor table, or beyond the end */
+  assert_backtrace (result >= group_desc_block_end
+		 && result < store->size >> log2_block_size);
 #else
   result = ext2_new_block (goal, 0, 0);
 #endif
diff --git a/ext2fs/hyper.c b/ext2fs/hyper.c
index d2440dc0..2af7e870 100644
--- a/ext2fs/hyper.c
+++ b/ext2fs/hyper.c
@@ -180,7 +180,7 @@ map_hypermetadata (void)
   /* Cache a convenient pointer to the block group descriptors for allocation.
      These are stored in the filesystem blocks following the superblock.  */
   group_desc_image =
-    (struct ext2_group_desc *) bptr (bptr_block (mapped_sblock) + 1);
+    (struct ext2_group_desc *) bptr (group_desc_block);
 }
 
 error_t
diff --git a/ext2fs/pager.c b/ext2fs/pager.c
index 99dac140..b93a9edd 100644
--- a/ext2fs/pager.c
+++ b/ext2fs/pager.c
@@ -41,6 +41,8 @@ struct pager_requests *file_pager_requests;
 
 pthread_spinlock_t node_to_page_lock = PTHREAD_SPINLOCK_INITIALIZER;
 
+static int disk_cache_initialized;
+
 
 #ifdef DONT_CACHE_MEMORY_OBJECTS
 #define MAY_CACHE 0
@@ -953,6 +955,7 @@ disk_cache_init (void)
       assert_backtrace (disk_cache_info[i-fixed_first].block == i);
       disk_cache_info[i-fixed_first].flags |= DC_FIXED;
     }
+  disk_cache_initialized = 1;
 }
 
 static void
@@ -1022,7 +1025,10 @@ disk_cache_block_ref (block_t block)
   void *bptr;
   hurd_ihash_locp_t slot;
 
-  assert_backtrace (block < store->size >> log2_block_size);
+  /* Trap trying to map superblock, block group descriptor table, or beyond the end */
+  if (disk_cache_initialized)
+    assert_backtrace (block >= group_desc_block_end
+		   && block < store->size >> log2_block_size);
 
   ext2_debug ("(%u)", block);
 
