From 1be238a9721d172b611983b9638be475b8421b51 Mon Sep 17 00:00:00 2001 From: Eugene Syromiatnikov Date: Mon, 18 Aug 2025 13:38:56 +0200 Subject: [PATCH] Move OPENSSL_SMALL_FOOTPRINT-related logic from aligned_alloc to the only caller MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Originally, CRYPTO_aligned_alloc() returned NULL if OpenSSL was built with OPENSSL_SMALL_FOOTPRINT defined, which is a weird place for such a consideration; moreover it means that every caller requires to implement some form of a fallback (and manually over-allocate and then align the returned memory if the alignment is a requirement), which is counter-productive (and outright ridiculous in environments with posix_memalign() available). Move the OPENSSL_SMALL_FOOTPRINT consideration to the only current caller and update the documentation and tests accordingly. Signed-off-by: Eugene Syromiatnikov Reviewed-by: Neil Horman Reviewed-by: Saša Nedvědický (Merged from https://github.com/openssl/openssl/pull/28295) --- crypto/hashtable/hashtable.c | 5 ++++- crypto/mem.c | 4 ---- doc/man3/OPENSSL_malloc.pod | 28 +++++++++------------------- test/mem_alloc_test.c | 15 +++------------ 4 files changed, 16 insertions(+), 36 deletions(-) diff --git a/crypto/hashtable/hashtable.c b/crypto/hashtable/hashtable.c index 516ac7c822c..e09e9149e3d 100644 --- a/crypto/hashtable/hashtable.c +++ b/crypto/hashtable/hashtable.c @@ -154,11 +154,14 @@ static struct ht_neighborhood_st *alloc_new_neighborhood_list(size_t len, { struct ht_neighborhood_st *ret; +#if !defined(OPENSSL_SMALL_FOOTPRINT) ret = OPENSSL_aligned_alloc_array(len, sizeof(struct ht_neighborhood_st), CACHE_LINE_BYTES, freeptr); /* fall back to regular malloc */ - if (ret == NULL) { + if (ret == NULL) +#endif + { ret = *freeptr = OPENSSL_malloc_array(len, sizeof(struct ht_neighborhood_st)); if (ret == NULL) diff --git a/crypto/mem.c b/crypto/mem.c index 4a58b583cb9..f1448606a70 100644 --- a/crypto/mem.c +++ b/crypto/mem.c @@ -236,10 +236,6 @@ void *CRYPTO_aligned_alloc(size_t num, size_t alignment, void **freeptr, *freeptr = NULL; -#if defined(OPENSSL_SMALL_FOOTPRINT) - return NULL; -#endif - /* Ensure that alignment is a power of two */ if (alignment == 0 || (alignment & (alignment - 1)) != 0) { ossl_report_alloc_err_inv(file, line); diff --git a/doc/man3/OPENSSL_malloc.pod b/doc/man3/OPENSSL_malloc.pod index ffea63b1690..63b7cfd29c8 100644 --- a/doc/man3/OPENSSL_malloc.pod +++ b/doc/man3/OPENSSL_malloc.pod @@ -126,13 +126,7 @@ OPENSSL_aligned_alloc() operates just as OPENSSL_malloc() does, but it allows for the caller to specify an alignment value, for instances in which the default alignment of malloc is insufficient for the caller's needs. Note, the alignment value must be a power of 2. -NOTES: - -=over 4 - -=item * - -The call to OPENSSL_aligned_alloc() accepts a 3rd argument, I +NOTE: the call to OPENSSL_aligned_alloc() accepts a 3rd argument, I which must point to a void pointer. On some platforms, there is no available library call to obtain memory allocations with alignment greater than what malloc provides. In this case, OPENSSL_aligned_alloc() implements its own @@ -141,18 +135,6 @@ pointer to be on the requested alignment boundary. In order to safely free allocations made by this method, the caller must return the value in the I variable, rather than the returned pointer. -=item * - -The call to OPENSSL_aligned_alloc() may fail for reasons other than memory -exhaustion, depending on the underlying implementation, and, most notably, -OpenSSL library's build configuration: for example, it always returns C -without setting any error if OpenSSL is built with C -macro defined. Consequently, caller may need to fall back to a non-aligned -memory allocation (and open-code the alignment routine if the alignment -is a requirement). - -=back - OPENSSL_clear_realloc() and OPENSSL_clear_free() should be used when the buffer at B holds sensitive information. The old buffer is filled with zero's by calling OPENSSL_cleanse() @@ -321,6 +303,14 @@ that the size must be a multiple of the alignment, that was enforced only on platforms that do not provide posix_memalign(3), but do provide aligned_alloc(3). +Before OpenSSL 4.0, the call to OPENSSL_aligned_alloc() may fail for reasons +other than memory exhaustion or incorrect arguments, depending on the underlying +implementation, and, most notably, OpenSSL library's build configuration: +for example, it always returned C without setting any error if OpenSSL +was built with C macro defined. Consequently, +the caller may need to fall back to a non-aligned memory allocation +(and open-code the alignment routine if the alignment is a requirement). + =head1 COPYRIGHT Copyright 2016-2025 The OpenSSL Project Authors. All Rights Reserved. diff --git a/test/mem_alloc_test.c b/test/mem_alloc_test.c index 0f305d27440..2571c4eceb7 100644 --- a/test/mem_alloc_test.c +++ b/test/mem_alloc_test.c @@ -183,7 +183,7 @@ static const struct array_aligned_alloc_vector { { 1, SIZE_MAX / 2 + 2, SIZE_MAX / 2 + 1, #if (defined(_BSD_SOURCE) \ || (defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200112L)) \ - && !USE_CUSTOM_ALLOC_FNS || defined(OPENSSL_SMALL_FOOTPRINT) + && !USE_CUSTOM_ALLOC_FNS EXP_OOM, EXP_OOM #else EXP_INT_OF, EXP_INT_OF @@ -667,19 +667,15 @@ static int test_xaligned_alloc(const bool array, const bool macro, test_fn, test_line); } -#if !defined(OPENSSL_SMALL_FOOTPRINT) /* * aligned_alloc doesn't increment the call counts by itself, and * OPENSSL_malloc is only called when the open-coded implementation * is used. */ -# if USE_CUSTOM_ALLOC_FNS \ +#if USE_CUSTOM_ALLOC_FNS \ || !(defined(_BSD_SOURCE) || (defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200112L)) exp_cnt += !!(exp != EXP_INT_OF && exp != EXP_INVAL); -# endif -#else /* OPENSSL_SMALL_FOOTPRINT */ - exp = exp == EXP_INT_OF ? EXP_INT_OF : EXP_ZERO_SIZE; -#endif /* !OPENSSL_SMALL_FOOTPRINT */ +#endif /* * There is an OPENSSL_calloc in ERR_set_debug, triggered @@ -695,15 +691,10 @@ static int test_xaligned_alloc(const bool array, const bool macro, res = 0; } -#if !defined(OPENSSL_SMALL_FOOTPRINT) if (IS_FAIL(exp) && !TEST_ptr_null(freeptr)) res = 0; if ((exp == EXP_NONNULL) && !TEST_ptr(freeptr)) res = 0; -#else /* OPENSSL_SMALL_FOOTPRINT */ - if (!TEST_ptr_null(ret) || !TEST_ptr_null(freeptr)) - res = 0; -#endif /* !OPENSSL_SMALL_FOOTPRINT */ OPENSSL_free(freeptr); -- 2.47.3