> This set of patches handles most memory allocators that we have in gnulib.

And this patch handles the 'ssfmalloc' memory allocator.


2023-11-11  Bruno Haible  <br...@clisp.org>

        ssfmalloc: Take advantage of CHERI bounds-checking.
        * lib/ssfmalloc.h: Include <cheri.h>.
        (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.

>From 131fd99e619b41c007521c97b6566cb833d58fb5 Mon Sep 17 00:00:00 2001
From: Bruno Haible <br...@clisp.org>
Date: Sun, 12 Nov 2023 00:45:39 +0100
Subject: [PATCH] ssfmalloc: Take advantage of CHERI bounds-checking.

* lib/ssfmalloc.h: Include <cheri.h>.
(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  <br...@clisp.org>
+
+	ssfmalloc: Take advantage of CHERI bounds-checking.
+	* lib/ssfmalloc.h: Include <cheri.h>.
+	(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  <johannes.schinde...@gmx.de>
 
 	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 <cheri.h>
+#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

Reply via email to