From 35b5ffa05c6309c616fe607653041b3ea643dc65 Mon Sep 17 00:00:00 2001
From: Sebastian Andrzej Siewior <sebastian@breakpoint.cc>
Date: Sun, 13 Oct 2024 18:05:55 +0200
Subject: [PATCH] mem: Don't use posix_memalign() and friends with custom
 wrapper.

If the application provides custom memory allocations functions via
CRYPTO_set_mem_functions() then those should be used instead something
else like posix_memalign(). The applications might verify alloc and free
calls and pointers from posix_memalign() were never returned by the
implementations.

At least stunnel4 complains here.

Use posix_memalign() or if aligned_alloc() only if the application did
not provide a custom malloc() implementation. In case of a custom
implementation use CRYPTO_malloc() and align the memory accordingly.

Fixes: #25678

Signed-off-by: Sebastian Andrzej Siewior <sebastian@breakpoint.cc>
---
 crypto/mem.c | 27 ++++++++++++++++-----------
 1 file changed, 16 insertions(+), 11 deletions(-)

diff --git a/crypto/mem.c b/crypto/mem.c
index d788afaadbda40..218acd2c67a946 100644
--- a/crypto/mem.c
+++ b/crypto/mem.c
@@ -229,7 +229,7 @@ void *CRYPTO_zalloc(size_t num, const char *file, int line)
 void *CRYPTO_aligned_alloc(size_t num, size_t alignment, void **freeptr,
                            const char *file, int line)
 {
-    void *ret;
+    void *ret = NULL;
 
     *freeptr = NULL;
 
@@ -238,15 +238,21 @@ void *CRYPTO_aligned_alloc(size_t num, size_t alignment, void **freeptr,
     return ret;
 #endif
 
-#if defined (_BSD_SOURCE) || (defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200112L)
-    if (posix_memalign(&ret, alignment, num))
-        return NULL;
-    *freeptr = ret;
-    return ret;
+    /*
+     * Allow non-malloc() allocations as long as no malloc_impl is provided.
+     */
+    if (!malloc_impl) {
+#if defined(_BSD_SOURCE) || (defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200112L)
+        if (posix_memalign(&ret, alignment, num))
+            return NULL;
+        *freeptr = ret;
+        return ret;
 #elif defined(_ISOC11_SOURCE)
-    ret = *freeptr =  aligned_alloc(alignment, num);
-    return ret;
-#else
+        ret = *freeptr = aligned_alloc(alignment, num);
+        return ret;
+#endif
+    }
+
     /* we have to do this the hard way */
 
     /*
@@ -261,7 +267,7 @@ void *CRYPTO_aligned_alloc(size_t num, size_t alignment, void **freeptr,
      * Step 1: Allocate an amount of memory that is <alignment>
      * bytes bigger than requested
      */
-    *freeptr = malloc(num + alignment);
+    *freeptr = CRYPTO_malloc(num + alignment, file, line);
     if (*freeptr == NULL)
         return NULL;
 
@@ -282,7 +288,6 @@ void *CRYPTO_aligned_alloc(size_t num, size_t alignment, void **freeptr,
      */
     ret = (void *)((uintptr_t)ret & (uintptr_t)(~(alignment - 1)));
     return ret;
-#endif
 }
 
 void *CRYPTO_realloc(void *str, size_t num, const char *file, int line)