commit:     13960a743787f9e8d400f35bc584346ea2aae357
Author:     Mike Gilbert <floppym <AT> gentoo <DOT> org>
AuthorDate: Fri Feb 14 16:58:37 2025 +0000
Commit:     Mike Gilbert <floppym <AT> gentoo <DOT> org>
CommitDate: Sat Feb 15 01:43:15 2025 +0000
URL:        https://gitweb.gentoo.org/proj/sandbox.git/commit/?id=13960a74

malloc: round size up to the nearest page

mmap can really only give us whole pages anyway.

Signed-off-by: Mike Gilbert <floppym <AT> gentoo.org>

 libsandbox/memory.c | 50 ++++++++++++++++++++++++++++++++------------------
 1 file changed, 32 insertions(+), 18 deletions(-)

diff --git a/libsandbox/memory.c b/libsandbox/memory.c
index 0d2c890..b6f7f80 100644
--- a/libsandbox/memory.c
+++ b/libsandbox/memory.c
@@ -15,9 +15,6 @@
 #include "libsandbox.h"
 #include "sbutil.h"
 
-/* Pick a value to guarantee alignment requirements. #565630 */
-#define MIN_ALIGN (2 * sizeof(void *))
-
 /* Well screw me sideways, someone decided to override mmap() #290249
  * We probably don't need to include the exact sym version ...
  */
@@ -52,29 +49,37 @@ static void *sb_mremap(void *old_address, size_t old_size, 
size_t new_size, int
 }
 #define mremap sb_mremap
 
-#define SB_MALLOC_TO_MMAP(ptr) ((void*)((uintptr_t)(ptr) - MIN_ALIGN))
-#define SB_MMAP_TO_MALLOC(ptr) ((void*)((uintptr_t)(ptr) + MIN_ALIGN))
-#define SB_MALLOC_TO_MMAP_SIZE(ptr) (*((size_t*)SB_MALLOC_TO_MMAP(ptr)))
-#define SB_MALLOC_TO_SIZE(ptr) (SB_MALLOC_TO_MMAP_SIZE(ptr) - MIN_ALIGN)
+/* Ensure malloc returns aligned memory #565630 */
+#define ALIGN_FACTOR 2
+#define ALIGN_SIZE (ALIGN_FACTOR * sizeof(size_t))
 
 void *malloc(size_t size)
 {
-       if (__builtin_add_overflow(size, MIN_ALIGN, &size)) {
+       long pagesize = sysconf(_SC_PAGESIZE);
+
+       if (__builtin_add_overflow(size, ALIGN_SIZE, &size) ||
+                       __builtin_add_overflow(size, pagesize - size % 
pagesize, &size)) {
                errno = ENOMEM;
                return NULL;
        }
-       size_t *ret = mmap(0, size, PROT_READ|PROT_WRITE, 
MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
-       if (ret == MAP_FAILED)
+
+       size_t *sp = mmap(0, size, PROT_READ|PROT_WRITE, 
MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
+       if (sp == MAP_FAILED)
                return NULL;
-       *ret = size;
-       return SB_MMAP_TO_MALLOC(ret);
+
+       *sp = size;
+       return sp + ALIGN_FACTOR;
 }
 
 void free(void *ptr)
 {
        if (ptr == NULL)
                return;
-       if (munmap(SB_MALLOC_TO_MMAP(ptr), SB_MALLOC_TO_MMAP_SIZE(ptr)))
+
+       size_t *sp = ptr;
+       sp -= ALIGN_FACTOR;
+
+       if (munmap(sp, *sp))
                sb_ebort("sandbox memory corruption with free(%p): %s\n",
                        ptr, strerror(errno));
 }
@@ -86,9 +91,11 @@ void *calloc(size_t nmemb, size_t size)
                errno = ENOMEM;
                return NULL;
        }
+
        void *ret = malloc(size);
        if (ret)
                memset(ret, 0, size);
+
        return ret;
 }
 
@@ -100,17 +107,24 @@ void *realloc(void *ptr, size_t size)
                free(ptr);
                return NULL;
        }
-       if (__builtin_add_overflow(size, MIN_ALIGN, &size)) {
+
+       long pagesize = sysconf(_SC_PAGESIZE);
+
+       if (__builtin_add_overflow(size, ALIGN_SIZE, &size) ||
+                       __builtin_add_overflow(size, pagesize - size % 
pagesize, &size)) {
                errno = ENOMEM;
                return NULL;
        }
-       size_t *sp = SB_MALLOC_TO_MMAP(ptr);
-       size_t old_size = *sp;
-       sp = mremap(sp, old_size, size, MREMAP_MAYMOVE);
+
+       size_t *sp = ptr;
+       sp -= 2;
+
+       sp = mremap(sp, *sp, size, MREMAP_MAYMOVE);
        if (sp == MAP_FAILED)
                return NULL;
+
        *sp = size;
-       return SB_MMAP_TO_MALLOC(sp);
+       return sp + ALIGN_FACTOR;
 }
 
 char *strdup(const char *s)

Reply via email to