From 5c8fc31ab5db3372739a7ae9bf579cef946408ad Mon Sep 17 00:00:00 2001 From: Bruno Haible Date: Sat, 11 Nov 2023 20:04:02 +0100 Subject: [PATCH] malloca: Take advantage of CHERI bounds-checking. * lib/malloca.h: Include . (malloca) [CHERI]: In the stack-allocation case, return a pointer with a tight lower bound and a tight upper bound. * lib/malloca.c: Include . (small_t) [CHERI]: Define as uintptr_t. (mmalloca) [CHERI]: Return a pointer with a tight upper bound. (freea) [CHERI]: Update. --- ChangeLog | 11 +++++++++++ lib/malloca.c | 28 ++++++++++++++++++++++++---- lib/malloca.h | 27 +++++++++++++++++++++------ 3 files changed, 56 insertions(+), 10 deletions(-) diff --git a/ChangeLog b/ChangeLog index 1fd39a4a44..af8ead5fc2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2023-11-11 Bruno Haible + + malloca: Take advantage of CHERI bounds-checking. + * lib/malloca.h: Include . + (malloca) [CHERI]: In the stack-allocation case, return a pointer with + a tight lower bound and a tight upper bound. + * lib/malloca.c: Include . + (small_t) [CHERI]: Define as uintptr_t. + (mmalloca) [CHERI]: Return a pointer with a tight upper bound. + (freea) [CHERI]: Update. + 2023-11-11 Bruno Haible safe-alloc: Take advantage of CHERI bounds-checking. diff --git a/lib/malloca.c b/lib/malloca.c index 690ce2324b..f98fdf152d 100644 --- a/lib/malloca.c +++ b/lib/malloca.c @@ -22,6 +22,9 @@ #include "malloca.h" #include +#if defined __CHERI__ +# include +#endif #include "idx.h" @@ -36,10 +39,15 @@ allocation. - NULL comes from a failed heap allocation. */ +#if defined __CHERI__ +/* Type for holding the original malloc() result. */ +typedef uintptr_t small_t; +#else /* Type for holding very small pointer differences. */ typedef unsigned char small_t; /* Verify that it is wide enough. */ static_assert (2 * sa_alignment_max - 1 <= (small_t) -1); +#endif void * mmalloca (size_t n) @@ -56,20 +64,28 @@ mmalloca (size_t n) if (mem != NULL) { - uintptr_t umem = (uintptr_t)mem, umemplus; + uintptr_t umem = (uintptr_t) mem; /* The ckd_add avoids signed integer overflow on theoretical platforms where UINTPTR_MAX <= INT_MAX. */ + uintptr_t umemplus; ckd_add (&umemplus, umem, sizeof (small_t) + sa_alignment_max - 1); idx_t offset = (umemplus - umemplus % (2 * sa_alignment_max) + sa_alignment_max - umem); - void *vp = mem + offset; - small_t *p = vp; + void *p = mem + offset; /* Here p >= mem + sizeof (small_t), and p <= mem + sizeof (small_t) + 2 * sa_alignment_max - 1 hence p + n <= mem + nplus. So, the memory range [p, p+n) lies in the allocated memory range [mem, mem + nplus). */ - p[-1] = offset; + small_t *sp = p; +# if defined __CHERI__ + sp[-1] = umem; + p = (char *) cheri_bounds_set ((char *) p - sizeof (small_t), + sizeof (small_t) + n) + + sizeof (small_t); +# else + sp[-1] = offset; +# endif /* p ≡ sa_alignment_max mod 2*sa_alignment_max. */ return p; } @@ -101,7 +117,11 @@ freea (void *p) { char *cp = p; small_t *sp = p; +# if defined __CHERI__ + void *mem = sp[-1]; +# else void *mem = cp - sp[-1]; +# endif free (mem); } } diff --git a/lib/malloca.h b/lib/malloca.h index f68ddfe010..120f406880 100644 --- a/lib/malloca.h +++ b/lib/malloca.h @@ -28,6 +28,9 @@ #include #include #include +#if defined __CHERI__ +# include +#endif #include "xalloc-oversized.h" @@ -68,12 +71,24 @@ 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 -# define malloca(N) \ - ((N) < 4032 - (2 * sa_alignment_max - 1) \ - ? (void *) (((uintptr_t) (char *) alloca ((N) + 2 * sa_alignment_max - 1) \ - + (2 * sa_alignment_max - 1)) \ - & ~(uintptr_t)(2 * sa_alignment_max - 1)) \ - : mmalloca (N)) +# if defined __CHERI__ +# define malloca(N) \ + ((N) < 4032 - (2 * sa_alignment_max - 1) \ + ? cheri_bounds_set ((void *) (((uintptr_t) \ + (char *) \ + alloca ((N) + 2 * sa_alignment_max - 1) \ + + (2 * sa_alignment_max - 1)) \ + & ~(uintptr_t)(2 * sa_alignment_max - 1)), \ + (N)) \ + : mmalloca (N)) +# else +# define malloca(N) \ + ((N) < 4032 - (2 * sa_alignment_max - 1) \ + ? (void *) (((uintptr_t) (char *) alloca ((N) + 2 * sa_alignment_max - 1) \ + + (2 * sa_alignment_max - 1)) \ + & ~(uintptr_t)(2 * sa_alignment_max - 1)) \ + : mmalloca (N)) +# endif #else # define malloca(N) \ mmalloca (N) -- 2.39.5