>From 131fd99e619b41c007521c97b6566cb833d58fb5 Mon Sep 17 00:00:00 2001 From: Bruno Haible Date: Sun, 12 Nov 2023 00:45:39 +0100 Subject: [PATCH] ssfmalloc: Take advantage of CHERI bounds-checking. * lib/ssfmalloc.h: Include . (struct dissected_page_header) [CHERI]: Add field 'whole_page'. (init_small_block_page, init_medium_block_page) [CHERI]: Initialize it. (free_block_from_pool) [CHERI]: Use this field to initialize pool->freeable_page. (allocate_block) [CHERI]: Return a pointer with a tight upper bound. --- ChangeLog | 10 ++++++++++ lib/ssfmalloc.h | 26 ++++++++++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/ChangeLog b/ChangeLog index e9cd83b06e..c2a59f8f88 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2023-11-11 Bruno Haible + + ssfmalloc: Take advantage of CHERI bounds-checking. + * lib/ssfmalloc.h: Include . + (struct dissected_page_header) [CHERI]: Add field 'whole_page'. + (init_small_block_page, init_medium_block_page) [CHERI]: Initialize it. + (free_block_from_pool) [CHERI]: Use this field to initialize + pool->freeable_page. + (allocate_block) [CHERI]: Return a pointer with a tight upper bound. + 2023-11-11 Johannes Schindelin vasnprintf: Re-enable parsing of directive with I64 (regr. 2023-03-24). diff --git a/lib/ssfmalloc.h b/lib/ssfmalloc.h index 5dd69c8199..14644cb1d4 100644 --- a/lib/ssfmalloc.h +++ b/lib/ssfmalloc.h @@ -133,6 +133,9 @@ static void free_block (uintptr_t block); #include "thread-optim.h" #include "gl_oset.h" #include "gl_rbtree_oset.h" +#ifdef __CHERI__ +# include +#endif /* Help the branch prediction. */ #if __GNUC__ >= 3 @@ -178,6 +181,10 @@ struct page_tree_element struct dissected_page_header { struct any_page_header common; + #ifdef __CHERI__ + /* This page, with bounds [page, page + PAGESIZE). */ + uintptr_t whole_page; + #endif /* Amount of free space in this page. Always a multiple of ALIGNMENT. */ pg_offset_t free_space; /* The tree element. */ @@ -386,6 +393,9 @@ init_small_block_page (uintptr_t page) { struct small_page_header *pageptr = (struct small_page_header *) page; pageptr->common.common.page_type = small_page_type; + #ifdef __CHERI__ + pageptr->common.whole_page = page; + #endif /* Initialize available_bitmap. */ uint32_t *available_bitmap = small_block_page_available_bitmap (pageptr); @@ -545,6 +555,9 @@ init_medium_block_page (uintptr_t page) { struct medium_page_header *pageptr = (struct medium_page_header *) page; pageptr->common.common.page_type = medium_page_type; + #ifdef __CHERI__ + pageptr->common.whole_page = page; + #endif pageptr->num_gaps = 1; pageptr->gaps[0].start = MEDIUM_BLOCKS_PAGE_FIRST_GAP_START; pageptr->gaps[0].end = MEDIUM_BLOCKS_PAGE_LAST_GAP_END; @@ -844,7 +857,11 @@ free_block_from_pool (uintptr_t block, uintptr_t page, struct page_pool *pool) FREE_PAGES (pool->freeable_page, PAGESIZE); /* Don't free the page now, but later. */ + #ifdef __CHERI__ + pool->freeable_page = pageptr->whole_page; + #else pool->freeable_page = page; + #endif } } @@ -908,6 +925,15 @@ allocate_block (size_t size) (size <= SMALL_BLOCK_MAX_SIZE ? &small_block_pages : &medium_block_pages); block = allocate_block_from_pool (size, pool); if (mt) gl_lock_unlock (ssfmalloc_lock); +#if defined __CHERI__ + if (block != 0) + { + size_t offset = block & (PAGESIZE - 1); + block = (uintptr_t) cheri_bounds_set ((void *) (block - offset), + offset + size) + + offset; + } +#endif } return block; } -- 2.34.1