diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-15 19:38:57 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-15 19:38:57 +0000 |
commit | f5b6b735a731901f09d7f3cc153c1d869269ee83 (patch) | |
tree | 565a1b0f3c6a4094a5f2198879fb239053549f1e /gl/lib/malloca.c | |
parent | Adding upstream version 2.12.0. (diff) | |
download | man-db-upstream.tar.xz man-db-upstream.zip |
Adding upstream version 2.12.1.upstream/2.12.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'gl/lib/malloca.c')
-rw-r--r-- | gl/lib/malloca.c | 41 |
1 files changed, 32 insertions, 9 deletions
diff --git a/gl/lib/malloca.c b/gl/lib/malloca.c index f055b1e..e75c72d 100644 --- a/gl/lib/malloca.c +++ b/gl/lib/malloca.c @@ -1,5 +1,5 @@ /* Safe automatic memory allocation. - Copyright (C) 2003, 2006-2007, 2009-2023 Free Software Foundation, Inc. + Copyright (C) 2003, 2006-2007, 2009-2024 Free Software Foundation, Inc. Written by Bruno Haible <bruno@clisp.org>, 2003, 2018. This file is free software: you can redistribute it and/or modify @@ -22,6 +22,9 @@ #include "malloca.h" #include <stdckdint.h> +#if defined __CHERI_PURE_CAPABILITY__ +# include <cheri.h> +#endif #include "idx.h" @@ -36,10 +39,15 @@ allocation. - NULL comes from a failed heap allocation. */ +#if defined __CHERI_PURE_CAPABILITY__ +/* 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 & ~alignment2_mask) + 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_PURE_CAPABILITY__ + 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; } @@ -90,15 +106,22 @@ void freea (void *p) { /* Check argument. */ - if ((uintptr_t) p & (sa_alignment_max - 1)) + uintptr_t u = (uintptr_t) p; + if (u & (sa_alignment_max - 1)) { /* p was not the result of a malloca() call. Invalid argument. */ abort (); } /* Determine whether p was a non-NULL pointer returned by mmalloca(). */ - if ((uintptr_t) p & sa_alignment_max) + if (u & sa_alignment_max) { - void *mem = (char *) p - ((small_t *) p)[-1]; + char *cp = p; + small_t *sp = p; +# if defined __CHERI_PURE_CAPABILITY__ + void *mem = sp[-1]; +# else + void *mem = cp - sp[-1]; +# endif free (mem); } } |