bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: *alloc: Take advantage of CHERI bounds-checking


From: Bruno Haible
Subject: Re: *alloc: Take advantage of CHERI bounds-checking
Date: Mon, 13 Nov 2023 15:01:14 +0100

Jessica Clarke wrote:
> So it’s not really a case of not being necessary, it’s a case of “are
> you using void * or using void * __capability everywhere to opt into
> capability use?”

Indeed, when I try to compile the current Gnulib code in "hybrid" mode
(CC="clang -march=morello"), I get compilation errors due to mismatches
between 'void *' and 'void * __capability':

../../gltests/../gllib/alignalloc.h:101:11: error: converting capability type 
'void * __capability' to non-capability type 'void *' without an explicit cast; 
if this is intended use __cheri_fromcap
    ptr = cheri_bounds_set (ptr, size);
          ^
          (__cheri_fromcap void *)

../../gltests/test-malloca.c:28:24: error: converting capability type 'void * 
__capability' to non-capability type 'void *' without an explicit cast; if this 
is intended use __cheri_fromcap
../../gltests/../gllib/malloca.h:77:8: note: expanded from macro 'malloca'
     ? cheri_bounds_set ((void *) (((uintptr_t)                               \
       ^

../../gltests/../gllib/safe-alloc.h:50:11: error: converting capability type 
'void * __capability' to non-capability type 'void *' without an explicit cast; 
if this is intended use __cheri_fromcap
    ptr = cheri_bounds_set (ptr, 0);
          ^
          (__cheri_fromcap void *)

> This need to annotate all uses
> (including any third-party library APIs you use with them), which ends
> up spreading throughout entire codebases, is why hybrid is awkward to
> use at scale and only really works in highly-constrained environments.
> For most userspace code there’s very little benefit to using it

I see. So, I'm following your advice:


2023-11-13  Bruno Haible  <bruno@clisp.org>

        Don't use CHERI facilities with CC="clang -march=morello".
        Suggested by Jessica Clarke <jrtc27@jrtc27.com> in
        <https://lists.gnu.org/archive/html/bug-gnulib/2023-11/msg00116.html>.
        * lib/alignalloc.h (alignalloc): Test __CHERI_PURE_CAPABILITY__, not
        __CHERI__.
        * lib/eealloc.h (eemalloc, eerealloc): Likewise.
        * lib/ialloc.h (irealloc, ireallocarray): Likewise.
        * lib/malloca.h (malloca): Likewise.
        * lib/malloca.c (small_t, mmalloca, freea): Likewise.
        * lib/rawmemchr.c (rawmemchr): Likewise.
        * lib/safe-alloc.h (safe_alloc_realloc_n): Likewise.
        * lib/sigsegv.c (SIGSEGV_FAULT_STACKPOINTER): Likewise.
        * lib/ssfmalloc.h (struct dissected_page_header, init_small_block_page,
        init_medium_block_page, free_block_from_pool, allocate_block): Likewise.
        * tests/test-stdint.c: Likewise.

diff --git a/lib/alignalloc.h b/lib/alignalloc.h
index cb40b344e8..4f75084d13 100644
--- a/lib/alignalloc.h
+++ b/lib/alignalloc.h
@@ -29,7 +29,7 @@
 #include <errno.h>
 #include <stdlib.h>
 #include "idx.h"
-#if defined __CHERI__
+#if defined __CHERI_PURE_CAPABILITY__
 # include <cheri.h>
 #endif
 
@@ -96,7 +96,7 @@ alignalloc (idx_t alignment, idx_t size)
   if (alignment < sizeof (void *))
     alignment = sizeof (void *);
   errno = posix_memalign (&ptr, alignment, size | !size);
-#  if defined __CHERI__
+#  if defined __CHERI_PURE_CAPABILITY__
   if (ptr != NULL)
     ptr = cheri_bounds_set (ptr, size);
 #  endif
diff --git a/lib/eealloc.h b/lib/eealloc.h
index bae3915146..1c54465680 100644
--- a/lib/eealloc.h
+++ b/lib/eealloc.h
@@ -36,7 +36,7 @@
 #endif
 
 #include <stdlib.h>
-#if defined __CHERI__
+#if defined __CHERI_PURE_CAPABILITY__
 # include <cheri.h>
 #endif
 
@@ -59,7 +59,7 @@ eemalloc (size_t n)
   if (n == 0)
     nx = 1;
   void *ptr = malloc (nx);
-# if defined __CHERI__
+# if defined __CHERI_PURE_CAPABILITY__
   if (ptr != NULL)
     ptr = cheri_bounds_set (ptr, n);
 # endif
@@ -80,7 +80,7 @@ eerealloc (void *p, size_t n)
   if (n == 0)
     nx = 1;
   void *ptr = realloc (p, nx);
-# if defined __CHERI__
+# if defined __CHERI_PURE_CAPABILITY__
   if (ptr != NULL)
     ptr = cheri_bounds_set (ptr, n);
 # endif
diff --git a/lib/ialloc.h b/lib/ialloc.h
index 527b1f48be..5b336ab1c5 100644
--- a/lib/ialloc.h
+++ b/lib/ialloc.h
@@ -29,7 +29,7 @@
 #include <errno.h>
 #include <stdint.h>
 #include <stdlib.h>
-#if defined __CHERI__
+#if defined __CHERI_PURE_CAPABILITY__
 # include <cheri.h>
 #endif
 
@@ -73,7 +73,7 @@ irealloc (void *p, idx_t s)
       /* Work around GNU realloc glitch by treating a zero size as if it
          were 1, so that returning NULL is equivalent to failing.  */
       p = realloc (p, s | !s);
-#if defined __CHERI__
+#if defined __CHERI_PURE_CAPABILITY__
       if (p != NULL)
         p = cheri_bounds_set (p, s);
 #endif
@@ -121,7 +121,7 @@ ireallocarray (void *p, idx_t n, idx_t s)
       if (n == 0 || s == 0)
         nx = sx = 1;
       p = reallocarray (p, nx, sx);
-#if defined __CHERI__
+#if defined __CHERI_PURE_CAPABILITY__
       if (p != NULL && (n == 0 || s == 0))
         p = cheri_bounds_set (p, 0);
 #endif
diff --git a/lib/malloca.c b/lib/malloca.c
index f98fdf152d..5ddb867039 100644
--- a/lib/malloca.c
+++ b/lib/malloca.c
@@ -22,7 +22,7 @@
 #include "malloca.h"
 
 #include <stdckdint.h>
-#if defined __CHERI__
+#if defined __CHERI_PURE_CAPABILITY__
 # include <cheri.h>
 #endif
 
@@ -39,7 +39,7 @@
        allocation.
      - NULL comes from a failed heap allocation.  */
 
-#if defined __CHERI__
+#if defined __CHERI_PURE_CAPABILITY__
 /* Type for holding the original malloc() result.  */
 typedef uintptr_t small_t;
 #else
@@ -78,7 +78,7 @@ mmalloca (size_t n)
              So, the memory range [p, p+n) lies in the allocated memory range
              [mem, mem + nplus).  */
           small_t *sp = p;
-# if defined __CHERI__
+# if defined __CHERI_PURE_CAPABILITY__
           sp[-1] = umem;
           p = (char *) cheri_bounds_set ((char *) p - sizeof (small_t),
                                          sizeof (small_t) + n)
@@ -117,7 +117,7 @@ freea (void *p)
     {
       char *cp = p;
       small_t *sp = p;
-# if defined __CHERI__
+# if defined __CHERI_PURE_CAPABILITY__
       void *mem = sp[-1];
 # else
       void *mem = cp - sp[-1];
diff --git a/lib/malloca.h b/lib/malloca.h
index 120f406880..2165e07096 100644
--- a/lib/malloca.h
+++ b/lib/malloca.h
@@ -28,7 +28,7 @@
 #include <stddef.h>
 #include <stdlib.h>
 #include <stdint.h>
-#if defined __CHERI__
+#if defined __CHERI_PURE_CAPABILITY__
 # include <cheri.h>
 #endif
 
@@ -71,7 +71,7 @@ extern void freea (void *p);
    memory allocated on the stack, that must be freed using freea() before
    the function returns.  Upon failure, it returns NULL.  */
 #if HAVE_ALLOCA
-# if defined __CHERI__
+# if defined __CHERI_PURE_CAPABILITY__
 #  define malloca(N) \
     ((N) < 4032 - (2 * sa_alignment_max - 1)                                  \
      ? cheri_bounds_set ((void *) (((uintptr_t)                               \
diff --git a/lib/rawmemchr.c b/lib/rawmemchr.c
index 9386ffc628..1c4a662ebf 100644
--- a/lib/rawmemchr.c
+++ b/lib/rawmemchr.c
@@ -30,7 +30,7 @@
 void *
 rawmemchr (const void *s, int c_in)
 {
-# ifdef __CHERI__
+# ifdef __CHERI_PURE_CAPABILITY__
   /* Most architectures let you read an aligned word,
      even if the unsigned char array at S ends in the middle of the word.
      However CHERI does not, so call memchr
diff --git a/lib/safe-alloc.h b/lib/safe-alloc.h
index 27049d3836..556735ab74 100644
--- a/lib/safe-alloc.h
+++ b/lib/safe-alloc.h
@@ -27,7 +27,7 @@
 #endif
 
 #include <stdlib.h>
-#if defined __CHERI__
+#if defined __CHERI_PURE_CAPABILITY__
 # include <cheri.h>
 #endif
 
@@ -45,7 +45,7 @@ safe_alloc_realloc_n (void *ptr, size_t count, size_t size)
   if (count == 0 || size == 0)
     countx = sizex = 1;
   ptr = reallocarray (ptr, countx, sizex);
-#if defined __CHERI__
+#if defined __CHERI_PURE_CAPABILITY__
   if (ptr != NULL && (count == 0 || size == 0))
     ptr = cheri_bounds_set (ptr, 0);
 #endif
diff --git a/lib/sigsegv.c b/lib/sigsegv.c
index c683c03ac0..9a1b8cc6c0 100644
--- a/lib/sigsegv.c
+++ b/lib/sigsegv.c
@@ -440,7 +440,7 @@ int libsigsegv_version = LIBSIGSEGV_VERSION;
 
 /* See sys/arm64/include/ucontext.h.  */
 
-#   if defined __CHERI__
+#   if defined __CHERI_PURE_CAPABILITY__
 #    define SIGSEGV_FAULT_STACKPOINTER  ((ucontext_t *) 
ucp)->uc_mcontext.mc_capregs.cap_sp
 #   else
 #    define SIGSEGV_FAULT_STACKPOINTER  ((ucontext_t *) 
ucp)->uc_mcontext.mc_gpregs.gp_sp
diff --git a/lib/ssfmalloc.h b/lib/ssfmalloc.h
index 14644cb1d4..645a2eda07 100644
--- a/lib/ssfmalloc.h
+++ b/lib/ssfmalloc.h
@@ -133,7 +133,7 @@ static void free_block (uintptr_t block);
 #include "thread-optim.h"
 #include "gl_oset.h"
 #include "gl_rbtree_oset.h"
-#ifdef __CHERI__
+#ifdef __CHERI_PURE_CAPABILITY__
 # include <cheri.h>
 #endif
 
@@ -181,7 +181,7 @@ struct page_tree_element
 struct dissected_page_header
 {
   struct any_page_header common;
-  #ifdef __CHERI__
+  #ifdef __CHERI_PURE_CAPABILITY__
   /* This page, with bounds [page, page + PAGESIZE).  */
   uintptr_t whole_page;
   #endif
@@ -393,7 +393,7 @@ 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__
+  #ifdef __CHERI_PURE_CAPABILITY__
   pageptr->common.whole_page = page;
   #endif
 
@@ -555,7 +555,7 @@ 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__
+  #ifdef __CHERI_PURE_CAPABILITY__
   pageptr->common.whole_page = page;
   #endif
   pageptr->num_gaps = 1;
@@ -857,7 +857,7 @@ 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__
+      #ifdef __CHERI_PURE_CAPABILITY__
       pool->freeable_page = pageptr->whole_page;
       #else
       pool->freeable_page = page;
@@ -925,7 +925,7 @@ 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 defined __CHERI_PURE_CAPABILITY__
       if (block != 0)
         {
           size_t offset = block & (PAGESIZE - 1);
diff --git a/tests/test-stdint.c b/tests/test-stdint.c
index fd12207b34..988c452217 100644
--- a/tests/test-stdint.c
+++ b/tests/test-stdint.c
@@ -219,7 +219,7 @@ err or;
 #ifdef INTPTR_MAX
 intptr_t g[3] = { 17, INTPTR_MIN, INTPTR_MAX };
 verify (sizeof (void *) <= sizeof (intptr_t));
-# ifndef __CHERI__
+# ifndef __CHERI_PURE_CAPABILITY__
 verify (TYPE_MINIMUM (intptr_t) == INTPTR_MIN);
 verify (TYPE_MAXIMUM (intptr_t) == INTPTR_MAX);
 # endif
@@ -230,7 +230,7 @@ verify_same_types (INTPTR_MAX, (intptr_t) 0 + 0);
 #ifdef UINTPTR_MAX
 uintptr_t h[2] = { 17, UINTPTR_MAX };
 verify (sizeof (void *) <= sizeof (uintptr_t));
-# ifndef __CHERI__
+# ifndef __CHERI_PURE_CAPABILITY__
 verify (TYPE_MAXIMUM (uintptr_t) == UINTPTR_MAX);
 # endif
 verify_same_types (UINTPTR_MAX, (uintptr_t) 0 + 0);
@@ -410,7 +410,7 @@ verify_width (INT_FAST32_WIDTH, INT_FAST32_MIN, 
INT_FAST32_MAX);
 verify_width (UINT_FAST32_WIDTH, 0, UINT_FAST32_MAX);
 verify_width (INT_FAST64_WIDTH, INT_FAST64_MIN, INT_FAST64_MAX);
 verify_width (UINT_FAST64_WIDTH, 0, UINT_FAST64_MAX);
-#ifndef __CHERI__
+#ifndef __CHERI_PURE_CAPABILITY__
 # ifdef INTPTR_WIDTH
 verify_width (INTPTR_WIDTH, INTPTR_MIN, INTPTR_MAX);
 # endif






reply via email to

[Prev in Thread] Current Thread [Next in Thread]