summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSamuel Thibault <samuel.thibault@ens-lyon.org>2025-03-13 21:22:24 +0100
committerSamuel Thibault <samuel.thibault@ens-lyon.org>2025-03-13 21:24:16 +0100
commit54c0b9b9dbf72467f099291950680ff8270b02ad (patch)
tree867839d92f5a70d01493a5a26c7e23581aed9369
parent5ff93bc7b5727024394a75defbabb0bff9a2820b (diff)
ext2fs: Trap trying to access bogus data areas
i.e. superblock, block group descriptor table or beyond the end.
-rw-r--r--ext2fs/balloc.c8
-rw-r--r--ext2fs/ext2fs.h4
-rw-r--r--ext2fs/getblk.c4
-rw-r--r--ext2fs/hyper.c2
-rw-r--r--ext2fs/pager.c8
5 files changed, 24 insertions, 2 deletions
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);