diff options
author | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2025-03-13 21:22:24 +0100 |
---|---|---|
committer | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2025-03-13 21:24:16 +0100 |
commit | 54c0b9b9dbf72467f099291950680ff8270b02ad (patch) | |
tree | 867839d92f5a70d01493a5a26c7e23581aed9369 | |
parent | 5ff93bc7b5727024394a75defbabb0bff9a2820b (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.c | 8 | ||||
-rw-r--r-- | ext2fs/ext2fs.h | 4 | ||||
-rw-r--r-- | ext2fs/getblk.c | 4 | ||||
-rw-r--r-- | ext2fs/hyper.c | 2 | ||||
-rw-r--r-- | ext2fs/pager.c | 8 |
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); |