[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
- Re: *alloc: Take advantage of CHERI bounds-checking, (continued)