From 59c6afcd46d87e5bd10dc7dec32ef86b248866fa Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Mon, 23 Feb 2026 13:56:41 +0100 Subject: [PATCH 01/17] Update framework with TEST_ASSERT_ERRNO Signed-off-by: Gilles Peskine --- framework | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/framework b/framework index 8ed11c99fe..bd6dfd6d8a 160000 --- a/framework +++ b/framework @@ -1 +1 @@ -Subproject commit 8ed11c99fe9e6d4d96289ebc1e134949421be917 +Subproject commit bd6dfd6d8af59ccd6ea24fcc37565809bd2c8cc7 From a7de32a7194bc141a46b1c3a39945164e11380f9 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Sat, 21 Feb 2026 21:19:42 +0100 Subject: [PATCH 02/17] Disable Unix-like integration code in baremetal builds in all.sh Signed-off-by: Gilles Peskine --- tests/scripts/components-configuration-crypto.sh | 2 +- tests/scripts/components-configuration.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/scripts/components-configuration-crypto.sh b/tests/scripts/components-configuration-crypto.sh index bb4608acca..47dd20450e 100644 --- a/tests/scripts/components-configuration-crypto.sh +++ b/tests/scripts/components-configuration-crypto.sh @@ -882,7 +882,7 @@ component_test_crypto_for_psa_service () { component_build_crypto_baremetal () { msg "build: make, crypto only, baremetal config" scripts/config.py crypto_baremetal - make CFLAGS="-O1 -Werror -I$PWD/framework/tests/include/baremetal-override/" + make CFLAGS="-O1 -Werror -I$PWD/framework/tests/include/baremetal-override/ -DMBEDTLS_TEST_PLATFORM_IS_NOT_UNIXLIKE" are_empty_libraries library/libmbedx509.* library/libmbedtls.* } diff --git a/tests/scripts/components-configuration.sh b/tests/scripts/components-configuration.sh index 72e7a86e3d..db9b5740e4 100644 --- a/tests/scripts/components-configuration.sh +++ b/tests/scripts/components-configuration.sh @@ -222,7 +222,7 @@ component_test_full_deprecated_warning () { component_build_baremetal () { msg "build: make, baremetal config" scripts/config.py baremetal - make CFLAGS="-O1 -Werror -I$PWD/framework/tests/include/baremetal-override/" + make CFLAGS="-O1 -Werror -I$PWD/framework/tests/include/baremetal-override/ -DMBEDTLS_TEST_PLATFORM_IS_NOT_UNIXLIKE" } support_build_baremetal () { From f2c25e01335ef564265672793cd3c3a7c88446f5 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Tue, 17 Feb 2026 17:08:12 +0100 Subject: [PATCH 03/17] test_suite_debug: test the printf used by debug.c In `test_suite_debug`, test `mbedtls_debug_snprintf()`, which uses `mbedtls_vsnprintf()` like `mbedtls_debug_print_msg()`. Do this instead of testing `mbedtls_snprintf()`, which might be subtly different (older Windows runtimes had slightly different behavior for vsnprintf() vs snprintf(); TF-PSA-Crypto might pick up a different function if the platform configuration is different in TF-PSA-Crypto and Mbed TLS). Signed-off-by: Gilles Peskine --- library/debug.c | 10 ++++++++++ library/debug_internal.h | 13 +++++++++++++ tests/suites/test_suite_debug.function | 6 +++--- 3 files changed, 26 insertions(+), 3 deletions(-) diff --git a/library/debug.c b/library/debug.c index c36ed3c5c2..24c6253c40 100644 --- a/library/debug.c +++ b/library/debug.c @@ -21,6 +21,16 @@ /* DEBUG_BUF_SIZE must be at least 2 */ #define DEBUG_BUF_SIZE 512 +int mbedtls_debug_snprintf(char *dest, size_t maxlen, + const char *format, ...) +{ + va_list argp; + va_start(argp, format); + int ret = mbedtls_vsnprintf(dest, maxlen, format, argp); + va_end(argp); + return ret; +} + static int debug_threshold = 0; void mbedtls_debug_set_threshold(int threshold) diff --git a/library/debug_internal.h b/library/debug_internal.h index 4523b4633a..2dd2599c1c 100644 --- a/library/debug_internal.h +++ b/library/debug_internal.h @@ -12,6 +12,19 @@ #include "mbedtls/debug.h" +/* This should be equivalent to mbedtls_snprintf(). But it might not be due + * to platform shenanigans. For example, Mbed TLS and TF-PSA-Crypto could + * have inconsistent platform definitions. On Mingw, some code might + * be built with a different setting of __USE_MINGW_ANSI_STDIO, resulting + * in an old non-C99 printf being used somewhere. + * + * Our library assumes that mbedtls_snprintf() and other printf functions + * are consistent throughout. This function is not an official API and + * is not meant to be used inside the library. It is provided to help + * debugging printf inconsistencies issues. If you need it, good luck! + */ +int mbedtls_debug_snprintf(char *dest, size_t maxlen, + const char *format, ...) MBEDTLS_PRINTF_ATTRIBUTE(3, 4); /** * \brief Print a message to the debug output. This function is always used * through the MBEDTLS_SSL_DEBUG_MSG() macro, which supplies the ssl diff --git a/tests/suites/test_suite_debug.function b/tests/suites/test_suite_debug.function index 9e53107626..df0ce4c987 100644 --- a/tests/suites/test_suite_debug.function +++ b/tests/suites/test_suite_debug.function @@ -113,11 +113,11 @@ void printf_int_expr(int format_indicator, intmax_t sizeof_x, intmax_t x, char * /* Nominal case: buffer just large enough */ TEST_CALLOC(output, n + 1); if ((size_t) sizeof_x <= sizeof(int)) { // Any smaller integers would be promoted to an int due to calling a vararg function - TEST_EQUAL(n, mbedtls_snprintf(output, n + 1, format, (int) x)); + TEST_EQUAL(n, mbedtls_debug_snprintf(output, n + 1, format, (int) x)); } else if (sizeof_x == sizeof(long)) { - TEST_EQUAL(n, mbedtls_snprintf(output, n + 1, format, (long) x)); + TEST_EQUAL(n, mbedtls_debug_snprintf(output, n + 1, format, (long) x)); } else if (sizeof_x == sizeof(long long)) { - TEST_EQUAL(n, mbedtls_snprintf(output, n + 1, format, (long long) x)); + TEST_EQUAL(n, mbedtls_debug_snprintf(output, n + 1, format, (long long) x)); } else { TEST_FAIL( "sizeof_x <= sizeof(int) || sizeof_x == sizeof(long) || sizeof_x == sizeof(long long)"); From 15c041c46575478e3c77b47864640467c95b4081 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Wed, 18 Feb 2026 19:11:57 +0100 Subject: [PATCH 04/17] Fix wrong pointer type passed to printf It works in practice, but clang on FreeBSD rightfully complains about it. Signed-off-by: Gilles Peskine --- tests/suites/test_suite_platform.function | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/suites/test_suite_platform.function b/tests/suites/test_suite_platform.function index 5d49e52e45..6c967fa8dc 100644 --- a/tests/suites/test_suite_platform.function +++ b/tests/suites/test_suite_platform.function @@ -127,7 +127,7 @@ void check_mbedtls_calloc_overallocation(intmax_t num, intmax_t size) unsigned char *buf; buf = mbedtls_calloc((size_t) num, (size_t) size); /* Dummy usage of the pointer to prevent optimizing it */ - mbedtls_printf("calloc pointer : %p\n", buf); + mbedtls_printf("calloc pointer : %p\n", (void *) buf); TEST_ASSERT(buf == NULL); exit: From 168461a3a907941ab73bcd54652516299b32a6e8 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Fri, 16 Jan 2026 18:55:24 +0100 Subject: [PATCH 05/17] Unify the detection of Unix-like platforms We were using slightly different guards to decide whether to include `` in different places. Unify those. Signed-off-by: Gilles Peskine --- ChangeLog.d/unistd.txt | 3 +++ library/common.h | 15 +++++++++++++++ library/net_sockets.c | 4 +--- library/platform_util.c | 15 +++++---------- library/threading.c | 4 +--- library/timing.c | 4 +--- 6 files changed, 26 insertions(+), 19 deletions(-) create mode 100644 ChangeLog.d/unistd.txt diff --git a/ChangeLog.d/unistd.txt b/ChangeLog.d/unistd.txt new file mode 100644 index 0000000000..d2e4d4301a --- /dev/null +++ b/ChangeLog.d/unistd.txt @@ -0,0 +1,3 @@ +Changes + * Tweak the detection of Unix-like platforms, which makes more system + interfaces (timing, threading) available on Haiku, QNX and Midipix. diff --git a/library/common.h b/library/common.h index c5cd241e7a..4aab94ba21 100644 --- a/library/common.h +++ b/library/common.h @@ -27,6 +27,21 @@ #define MBEDTLS_HAVE_NEON_INTRINSICS #endif +/* Decide whether we're built for a Unix-like platform. + */ +#if defined(_WIN32) +/* If Windows platform interfaces are available, we use them, even if + * a Unix-like might also to be available. */ +/* defined(_WIN32) ==> we can include */ +#elif defined(unix) || defined(__unix) || defined(__unix__) || \ + (defined(__APPLE__) && defined(__MACH__)) || \ + defined(__HAIKU__) || \ + defined(__midipix__) || \ + /* Add other Unix-like platform indicators here ^^^^ */ 0 +/* defined(MBEDTLS_PLATFORM_IS_UNIXLIKE) ==> we can include */ +#define MBEDTLS_PLATFORM_IS_UNIXLIKE +#endif + /** Helper to define a function as static except when building invasive tests. * * If a function is only used inside its own source file and should be diff --git a/library/net_sockets.c b/library/net_sockets.c index 1419c787b9..c919f6f574 100644 --- a/library/net_sockets.c +++ b/library/net_sockets.c @@ -19,9 +19,7 @@ #if defined(MBEDTLS_NET_C) -#if !defined(unix) && !defined(__unix__) && !defined(__unix) && \ - !defined(__APPLE__) && !defined(_WIN32) && !defined(__QNXNTO__) && \ - !defined(__HAIKU__) && !defined(__midipix__) +#if !defined(MBEDTLS_PLATFORM_IS_UNIXLIKE) && !defined(_WIN32) #error "This module only works on Unix and Windows, see MBEDTLS_NET_C in mbedtls_config.h" #endif diff --git a/library/platform_util.c b/library/platform_util.c index 19ef07aead..1cab42ffc0 100644 --- a/library/platform_util.c +++ b/library/platform_util.c @@ -147,12 +147,9 @@ void mbedtls_zeroize_and_free(void *buf, size_t len) #if defined(MBEDTLS_HAVE_TIME_DATE) && !defined(MBEDTLS_PLATFORM_GMTIME_R_ALT) #include -#if !defined(_WIN32) && (defined(unix) || \ - defined(__unix) || defined(__unix__) || (defined(__APPLE__) && \ - defined(__MACH__)) || defined(__midipix__)) +#if defined(MBEDTLS_PLATFORM_IS_UNIXLIKE) #include -#endif /* !_WIN32 && (unix || __unix || __unix__ || - * (__APPLE__ && __MACH__) || __midipix__) */ +#endif #if !((defined(_POSIX_VERSION) && _POSIX_VERSION >= 200809L) || \ (defined(_POSIX_THREAD_SAFE_FUNCTIONS) && \ @@ -218,12 +215,10 @@ void (*mbedtls_test_hook_test_fail)(const char *, int, const char *); #if defined(MBEDTLS_HAVE_TIME) && !defined(MBEDTLS_PLATFORM_MS_TIME_ALT) #include -#if !defined(_WIN32) && \ - (defined(unix) || defined(__unix) || defined(__unix__) || \ - (defined(__APPLE__) && defined(__MACH__)) || defined(__HAIKU__) || defined(__midipix__)) +#if defined(MBEDTLS_PLATFORM_IS_UNIXLIKE) #include -#endif \ - /* !_WIN32 && (unix || __unix || __unix__ || (__APPLE__ && __MACH__) || __HAIKU__ || __midipix__) */ +#endif + #if (defined(_POSIX_VERSION) && _POSIX_VERSION >= 199309L) || defined(__HAIKU__) mbedtls_ms_time_t mbedtls_ms_time(void) { diff --git a/library/threading.c b/library/threading.c index ff8183ed15..8764b3edce 100644 --- a/library/threading.c +++ b/library/threading.c @@ -21,9 +21,7 @@ #if defined(MBEDTLS_HAVE_TIME_DATE) && !defined(MBEDTLS_PLATFORM_GMTIME_R_ALT) -#if !defined(_WIN32) && (defined(unix) || \ - defined(__unix) || defined(__unix__) || (defined(__APPLE__) && \ - defined(__MACH__))) +#if defined(MBEDTLS_PLATFORM_IS_UNIXLIKE) #include #endif /* !_WIN32 && (unix || __unix || __unix__ || * (__APPLE__ && __MACH__)) */ diff --git a/library/timing.c b/library/timing.c index 58f1c1ec2e..e3e9da52ef 100644 --- a/library/timing.c +++ b/library/timing.c @@ -13,9 +13,7 @@ #if !defined(MBEDTLS_TIMING_ALT) -#if !defined(unix) && !defined(__unix__) && !defined(__unix) && \ - !defined(__APPLE__) && !defined(_WIN32) && !defined(__QNXNTO__) && \ - !defined(__HAIKU__) && !defined(__midipix__) +#if !defined(_WIN32) && !defined(MBEDTLS_PLATFORM_IS_UNIXLIKE) #error "This module only works on Unix and Windows, see MBEDTLS_TIMING_C in mbedtls_config.h" #endif From df9fdae4c4f29a3cd94a3a10ab405c575b21199b Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Tue, 17 Feb 2026 17:55:30 +0100 Subject: [PATCH 06/17] Add smoke test for availability of some Unix functions The goal isn't to do any functional testing, but to have a simple diagnostic if some Unix platform function isn't available, and to have a record of success in the outcome file. Signed-off-by: Gilles Peskine --- tests/suites/test_suite_platform_unix.data | 12 +++++ .../suites/test_suite_platform_unix.function | 45 +++++++++++++++++++ 2 files changed, 57 insertions(+) create mode 100644 tests/suites/test_suite_platform_unix.data create mode 100644 tests/suites/test_suite_platform_unix.function diff --git a/tests/suites/test_suite_platform_unix.data b/tests/suites/test_suite_platform_unix.data new file mode 100644 index 0000000000..7135bf77b3 --- /dev/null +++ b/tests/suites/test_suite_platform_unix.data @@ -0,0 +1,12 @@ + smoke test +unistd_available: + +# At the time of writing, we don't actually use CLOCK_REALTIME. +# But it's the only clock that's guaranteed by POSIX. +clock_gettime(CLOCK_REALTIME) smoke test +clock_gettime_available:CLOCK_REALTIME + +# Used for mbedtls_ms_time() on platforms where we don't think +# CLOCK_BOOTTIME is available. +clock_gettime(CLOCK_MONOTONIC) smoke test +clock_gettime_available:CLOCK_MONOTONIC diff --git a/tests/suites/test_suite_platform_unix.function b/tests/suites/test_suite_platform_unix.function new file mode 100644 index 0000000000..14f3099a4e --- /dev/null +++ b/tests/suites/test_suite_platform_unix.function @@ -0,0 +1,45 @@ +/* BEGIN_HEADER */ +/* Test access to the Unix primitives used in platform_util.c and elsewhere. + * We aren't testing that they work, just getting an easy-to-understand + * diagnostic if they aren't available. + * (There is a separate test suite for the platform_util.h interfacces.) + */ + +#include +#include +#include "common.h" + +#if defined(MBEDTLS_PLATFORM_IS_UNIXLIKE) + +#include +#include + +#endif /* defined(MBEDTLS_PLATFORM_IS_UNIXLIKE) */ + +/* END_HEADER */ + +/* Note: we can't make the whole test suite depend on + * MBEDTLS_PLATFORM_IS_UNIXLIKE, because file-level dependencies can only + * come from build_info.h, platform.h or some test helper headers, not + * from internal macros. */ +/* BEGIN_DEPENDENCIES + * END_DEPENDENCIES */ + +/* BEGIN_CASE depends_on:MBEDTLS_PLATFORM_IS_UNIXLIKE */ +void unistd_available() +{ + pid_t pid = getpid(); + TEST_LE_S(1, pid); +} +/* END_CASE */ + +/* BEGIN_CASE depends_on:MBEDTLS_PLATFORM_IS_UNIXLIKE */ +void clock_gettime_available(int clockid) +{ + struct timespec ts = { 0, 0 }; + memset(&ts, 0, sizeof(ts)); + int ret = clock_gettime(clockid, &ts); + TEST_ASSERT_ERRNO(ret == 0); + TEST_LE_S(1, ts.tv_sec); +} +/* END_CASE */ From 5ca8894b596fc37e6961ef7683a3a82018cfb690 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Thu, 19 Feb 2026 00:43:59 +0100 Subject: [PATCH 07/17] Fix the build with dietlibc Signed-off-by: Gilles Peskine --- tests/suites/host_test.function | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/suites/host_test.function b/tests/suites/host_test.function index d28a75e077..90b050e129 100644 --- a/tests/suites/host_test.function +++ b/tests/suites/host_test.function @@ -275,7 +275,12 @@ static int convert_params(size_t cnt, char **params, * \return 0 for success else 1 */ #if defined(__GNUC__) +# if defined(__dietlibc__) +/* __noinline__ is a macro in dietlibc... */ +__attribute__((noinline)) +# else __attribute__((__noinline__)) +# endif #endif static int test_snprintf(size_t n, const char *ref_buf, int ref_ret) { From f994fe05cd539c4ae570a1d0d71c52b5e7ad283f Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Sat, 21 Feb 2026 21:17:47 +0100 Subject: [PATCH 08/17] Fix the build on non-UNIXLIKE platforms Signed-off-by: Gilles Peskine --- tests/suites/test_suite_platform_unix.function | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tests/suites/test_suite_platform_unix.function b/tests/suites/test_suite_platform_unix.function index 14f3099a4e..d731e07ed5 100644 --- a/tests/suites/test_suite_platform_unix.function +++ b/tests/suites/test_suite_platform_unix.function @@ -14,6 +14,13 @@ #include #include +#else /* defined(MBEDTLS_PLATFORM_IS_UNIXLIKE) */ + +/* Constants used in the test data need to be defined even if no test + * functions that use them are enabled. */ +#define CLOCK_REALTIME 0 +#define CLOCK_MONOTONIC 0 + #endif /* defined(MBEDTLS_PLATFORM_IS_UNIXLIKE) */ /* END_HEADER */ From dec0d500a810c2396284f3a19817254bd0acbaa3 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Fri, 30 Jan 2026 20:35:54 +0100 Subject: [PATCH 09/17] Test printf integer format modifiers more In particular, test `"%zu"` for `size_t` and `"%lld"` for `long long`, which older Windows runtimes do not support, but which Mbed TLS uses. Signed-off-by: Gilles Peskine --- tests/suites/test_suite_platform_printf.data | 61 +++++++++++++------ .../test_suite_platform_printf.function | 43 ++++++++++++- 2 files changed, 83 insertions(+), 21 deletions(-) diff --git a/tests/suites/test_suite_platform_printf.data b/tests/suites/test_suite_platform_printf.data index 891771b919..25c1ed33a8 100644 --- a/tests/suites/test_suite_platform_printf.data +++ b/tests/suites/test_suite_platform_printf.data @@ -3,58 +3,83 @@ # and strings through the test framework. printf "%d", 0 -printf_int:"%d":0:"0" +printf_integer:"%d":PRINTF_CAST_INT:0:"0" printf "%d", -0 -printf_int:"%d":-0:"0" +printf_integer:"%d":PRINTF_CAST_INT:-0:"0" printf "%d", 0x0 -printf_int:"%d":0x0:"0" +printf_integer:"%d":PRINTF_CAST_INT:0x0:"0" printf "%d", 0x00 -printf_int:"%d":0x00:"0" +printf_integer:"%d":PRINTF_CAST_INT:0x00:"0" printf "%d", 0x000000000000000000000000000000000000000000 -printf_int:"%d":0x000000000000000000000000000000000000000000:"0" +printf_integer:"%d":PRINTF_CAST_INT:0x000000000000000000000000000000000000000000:"0" printf "%d", -0x0 -printf_int:"%d":-0x0:"0" +printf_integer:"%d":PRINTF_CAST_INT:-0x0:"0" printf "%d", 1 -printf_int:"%d":1:"1" +printf_integer:"%d":PRINTF_CAST_INT:1:"1" printf "%d", 0x1 -printf_int:"%d":0x1:"1" +printf_integer:"%d":PRINTF_CAST_INT:0x1:"1" printf "%d", 0x0000000000000000000000000000000000000000001 -printf_int:"%d":0x0000000000000000000000000000000000000000001:"1" +printf_integer:"%d":PRINTF_CAST_INT:0x0000000000000000000000000000000000000000001:"1" printf "%d", -1 -printf_int:"%d":-1:"-1" +printf_integer:"%d":PRINTF_CAST_INT:-1:"-1" printf "%d", -0x1 -printf_int:"%d":-0x1:"-1" +printf_integer:"%d":PRINTF_CAST_INT:-0x1:"-1" printf "%d", -0x0000000000000000000000000000000000000000001 -printf_int:"%d":-0x0000000000000000000000000000000000000000001:"-1" +printf_integer:"%d":PRINTF_CAST_INT:-0x0000000000000000000000000000000000000000001:"-1" printf "%d", 2147483647 -printf_int:"%d":2147483647:"2147483647" +printf_integer:"%d":PRINTF_CAST_INT:2147483647:"2147483647" printf "%d", 0x7fffffff -printf_int:"%d":0x7fffffff:"2147483647" +printf_integer:"%d":PRINTF_CAST_INT:0x7fffffff:"2147483647" printf "%d", -2147483647 -printf_int:"%d":-2147483647:"-2147483647" +printf_integer:"%d":PRINTF_CAST_INT:-2147483647:"-2147483647" printf "%d", -0x7fffffff -printf_int:"%d":-0x7fffffff:"-2147483647" +printf_integer:"%d":PRINTF_CAST_INT:-0x7fffffff:"-2147483647" printf "%d", -2147483648 -printf_int:"%d":-2147483648:"-2147483648" +printf_integer:"%d":PRINTF_CAST_INT:-2147483648:"-2147483648" printf "%d", -0x80000000 -printf_int:"%d":-0x80000000:"-2147483648" +printf_integer:"%d":PRINTF_CAST_INT:-0x80000000:"-2147483648" + +printf "%u", 0x80000000 +printf_integer:"%u":PRINTF_CAST_INT:-0x80000000:"2147483648" + +printf "%zx", 0x12345678 +printf_integer:"%zx":PRINTF_CAST_SIZE_T:0x12345678:"12345678" + +printf "%zu", 0x80000000 +printf_integer:"%zu":PRINTF_CAST_SIZE_T:0x80000000:"2147483648" + +printf "%zx", 0xffffffff +printf_integer:"%zx":PRINTF_CAST_SIZE_T:0xffffffff:"ffffffff" + +printf "%zx", 0xffffffffffffffff +depends_on:SIZE_T_AT_LEAST_64_BIT +printf_integer:"%zx":PRINTF_CAST_SIZE_T:0xffffffffffffffff:"ffffffffffffffff" + +printf "%lld", 0x7fffffffffffffff +printf_integer:"%lld":PRINTF_CAST_LONG_LONG:0x7fffffffffffffff:"9223372036854775807" + +printf "%lld", -0x8000000000000000 +printf_integer:"%lld":PRINTF_CAST_LONG_LONG:-0x8000000000000000:"-9223372036854775808" + +printf "%llx", 0x102030405060708 +printf_integer:"%llx":PRINTF_CAST_UNSIGNED_LONG_LONG:0x0102030405060708:"102030405060708" # Test that LONG_MAX is coming out untruncated through the test framework. printf "%lx", LONG_MAX diff --git a/tests/suites/test_suite_platform_printf.function b/tests/suites/test_suite_platform_printf.function index 643accf1f7..000d265a53 100644 --- a/tests/suites/test_suite_platform_printf.function +++ b/tests/suites/test_suite_platform_printf.function @@ -15,6 +15,20 @@ #include #include +#if SIZE_MAX >= 0xffffffffffffffff +#define SIZE_T_AT_LEAST_64_BIT +#endif + +typedef enum { + PRINTF_CAST_INT, + PRINTF_CAST_UNSIGNED, + PRINTF_CAST_SIZE_T, + PRINTF_CAST_LONG, + PRINTF_CAST_UNSIGNED_LONG, + PRINTF_CAST_LONG_LONG, + PRINTF_CAST_UNSIGNED_LONG_LONG, +} printf_cast_type_t; + #define NEWLINE_CHAR '\n' #define SPACE_CHAR ' ' #define DOUBLE_QUOTE_CHAR '"' @@ -22,18 +36,41 @@ #define QUESTION_CHAR '?' #define BACKSLASH_CHAR '\\' #define LOWERCASE_N_CHAR 'n' + /* END_HEADER */ /* BEGIN_CASE */ -void printf_int(char *format, /* any format expecting one int argument, e.g. "%d" */ - int x, char *result) +void printf_integer(char *format, /* format expecting one foo_t argument */ + int type, /* enum value from printf_cast_type_t */ + intmax_t value, + char *result) { char *output = NULL; const size_t n = strlen(result); + int ret = 0; /* Nominal case: buffer just large enough */ TEST_CALLOC(output, n + 1); - TEST_EQUAL(n, mbedtls_snprintf(output, n + 1, format, x)); + switch (type) { + case PRINTF_CAST_INT: + ret = mbedtls_snprintf(output, n + 1, format, (int) value); + break; + case PRINTF_CAST_UNSIGNED: + ret = mbedtls_snprintf(output, n + 1, format, (unsigned) value); + break; + case PRINTF_CAST_SIZE_T: + ret = mbedtls_snprintf(output, n + 1, format, (size_t) value); + break; + case PRINTF_CAST_LONG_LONG: + ret = mbedtls_snprintf(output, n + 1, format, (long long) value); + break; + case PRINTF_CAST_UNSIGNED_LONG_LONG: + ret = mbedtls_snprintf(output, n + 1, format, (unsigned long long) value); + break; + default: + TEST_FAIL("Unsupported type"); + } + TEST_EQUAL(n, ret); TEST_MEMORY_COMPARE(result, n + 1, output, n + 1); mbedtls_free(output); output = NULL; From 9cd92b207fe9bdfead66d96cb020946a0849e9db Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Sat, 21 Feb 2026 21:18:03 +0100 Subject: [PATCH 10/17] Support testing baremetal builds without the UNIXLIKE code When `MBEDTLS_TEST_PLATFORM_IS_NOT_UNIXLIKE` is defined, do not enable `MBEDTLS_PLATFORM_IS_UNIXLIKE`. This lets us test baremetal builds as such even if we happen to be building for Linux or other Unix-like platform. Signed-off-by: Gilles Peskine --- library/common.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/library/common.h b/library/common.h index 4aab94ba21..1f59b32426 100644 --- a/library/common.h +++ b/library/common.h @@ -29,7 +29,10 @@ /* Decide whether we're built for a Unix-like platform. */ -#if defined(_WIN32) +#if defined(MBEDTLS_TEST_PLATFORM_IS_NOT_UNIXLIKE) //no-check-names +/* We may be building on a Unix-like platform, but for test purposes, + * do not try to use Unix features. */ +#elif defined(_WIN32) /* If Windows platform interfaces are available, we use them, even if * a Unix-like might also to be available. */ /* defined(_WIN32) ==> we can include */ From 60cfb78882a0adfcc025af2805c2d81e91be87d9 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Sun, 22 Feb 2026 20:40:10 +0100 Subject: [PATCH 11/17] Fix the build on non-Unix-like platforms that define CLOCK_REALTIME as a macro Needed for MinGW builds in our CI. Signed-off-by: Gilles Peskine --- tests/suites/test_suite_platform_unix.function | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tests/suites/test_suite_platform_unix.function b/tests/suites/test_suite_platform_unix.function index d731e07ed5..d9182bce74 100644 --- a/tests/suites/test_suite_platform_unix.function +++ b/tests/suites/test_suite_platform_unix.function @@ -17,8 +17,12 @@ #else /* defined(MBEDTLS_PLATFORM_IS_UNIXLIKE) */ /* Constants used in the test data need to be defined even if no test - * functions that use them are enabled. */ + * functions that use them are enabled. + * Undefine the macros first in case a system header does define them + * even though we haven't recognized the platform as Unix-like. */ +#undef CLOCK_REALTIME #define CLOCK_REALTIME 0 +#undef CLOCK_MONOTONIC #define CLOCK_MONOTONIC 0 #endif /* defined(MBEDTLS_PLATFORM_IS_UNIXLIKE) */ From 5c6ec6bcc0e47eae1a2fd312eaa8a903c17af5f6 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Mon, 23 Feb 2026 14:00:23 +0100 Subject: [PATCH 12/17] Add smoke test for gettimeofday() Signed-off-by: Gilles Peskine --- tests/suites/test_suite_platform_unix.data | 4 ++++ tests/suites/test_suite_platform_unix.function | 12 ++++++++++++ 2 files changed, 16 insertions(+) diff --git a/tests/suites/test_suite_platform_unix.data b/tests/suites/test_suite_platform_unix.data index 7135bf77b3..adb90fe80c 100644 --- a/tests/suites/test_suite_platform_unix.data +++ b/tests/suites/test_suite_platform_unix.data @@ -10,3 +10,7 @@ clock_gettime_available:CLOCK_REALTIME # CLOCK_BOOTTIME is available. clock_gettime(CLOCK_MONOTONIC) smoke test clock_gettime_available:CLOCK_MONOTONIC + +# Used in library/timing.c and programs/test/benchmark.c +gettimeofday() smoke test +gettimeofday_available: diff --git a/tests/suites/test_suite_platform_unix.function b/tests/suites/test_suite_platform_unix.function index d9182bce74..d419390bf4 100644 --- a/tests/suites/test_suite_platform_unix.function +++ b/tests/suites/test_suite_platform_unix.function @@ -13,6 +13,7 @@ #include #include +#include #else /* defined(MBEDTLS_PLATFORM_IS_UNIXLIKE) */ @@ -54,3 +55,14 @@ void clock_gettime_available(int clockid) TEST_LE_S(1, ts.tv_sec); } /* END_CASE */ + +/* BEGIN_CASE depends_on:MBEDTLS_PLATFORM_IS_UNIXLIKE */ +void gettimeofday_available() +{ + struct timeval tv = { 0, 0 }; + memset(&tv, 0, sizeof(tv)); + int ret = gettimeofday(&tv, NULL); + TEST_ASSERT_ERRNO(ret == 0); + TEST_LE_S(1, tv.tv_sec); +} +/* END_CASE */ From 08614e1e96e096feee3328b40d8cd82a4d3c500c Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Mon, 23 Feb 2026 20:30:33 +0100 Subject: [PATCH 13/17] Skip printf("%zu") tests with MinGW MinGW uses a legacy printf by default which doesn't support the `z` modifier for `size_t`. Skip these test cases on MinGW. Signed-off-by: Gilles Peskine --- tests/suites/test_suite_platform_printf.data | 5 ++++- tests/suites/test_suite_platform_printf.function | 14 ++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/tests/suites/test_suite_platform_printf.data b/tests/suites/test_suite_platform_printf.data index 25c1ed33a8..a359e8c581 100644 --- a/tests/suites/test_suite_platform_printf.data +++ b/tests/suites/test_suite_platform_printf.data @@ -60,16 +60,19 @@ printf "%u", 0x80000000 printf_integer:"%u":PRINTF_CAST_INT:-0x80000000:"2147483648" printf "%zx", 0x12345678 +depends_on:HAVE_C99_PRINTF printf_integer:"%zx":PRINTF_CAST_SIZE_T:0x12345678:"12345678" printf "%zu", 0x80000000 +depends_on:HAVE_C99_PRINTF printf_integer:"%zu":PRINTF_CAST_SIZE_T:0x80000000:"2147483648" printf "%zx", 0xffffffff +depends_on:HAVE_C99_PRINTF printf_integer:"%zx":PRINTF_CAST_SIZE_T:0xffffffff:"ffffffff" printf "%zx", 0xffffffffffffffff -depends_on:SIZE_T_AT_LEAST_64_BIT +depends_on:HAVE_C99_PRINTF:SIZE_T_AT_LEAST_64_BIT printf_integer:"%zx":PRINTF_CAST_SIZE_T:0xffffffffffffffff:"ffffffffffffffff" printf "%lld", 0x7fffffffffffffff diff --git a/tests/suites/test_suite_platform_printf.function b/tests/suites/test_suite_platform_printf.function index 000d265a53..5a132b7954 100644 --- a/tests/suites/test_suite_platform_printf.function +++ b/tests/suites/test_suite_platform_printf.function @@ -19,6 +19,20 @@ #define SIZE_T_AT_LEAST_64_BIT #endif +/* Older Windows runtimes have a non-compliant printf family, e.g. + * it doesn't understand `%zu` to print a `size_t`. MSVC provides a + * C99-compliant printf family (at least enough for our purposes), + * since Visual Studio 2015. With MinGW, you get the non-compliant legacy + * printf by default, but can select the standard-compliant version + * at compile time. In the Mbed TLS 3.6 LTS, we use the default, so + * we can't rely on %z being understood. The debug module defines + * `MBEDTLS_PRINTF_SIZET` for that, and this is tested in test_suite_debug. + * Here we just skip the test cases that break the legacy Windows printf. + */ +#if !(defined(__MINGW32__)) +#define HAVE_C99_PRINTF +#endif + typedef enum { PRINTF_CAST_INT, PRINTF_CAST_UNSIGNED, From fa62af0a47cd09f7f9539c6de79ab80bb886400b Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Wed, 18 Feb 2026 22:03:20 +0100 Subject: [PATCH 14/17] Let test suites see gettimeofday() on FreeBSD Signed-off-by: Gilles Peskine --- tests/suites/main_test.function | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tests/suites/main_test.function b/tests/suites/main_test.function index c0cc2ac50b..ba9b021b59 100644 --- a/tests/suites/main_test.function +++ b/tests/suites/main_test.function @@ -23,6 +23,13 @@ #endif #endif +#if defined(__FreeBSD__) +// for gettimeofday() (On FreeBSD, _POSIX_C_SOURCE isn't enough) +#if !defined(_XOPEN_SOURCE) +#define _XOPEN_SOURCE 500 +#endif +#endif + #include "mbedtls/build_info.h" /* Test code may use deprecated identifiers only if the preprocessor symbol From b17d0f3028d35a23ad674e58df9fbbe20d9109f9 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Thu, 19 Feb 2026 01:23:56 +0100 Subject: [PATCH 15/17] Let test suites see strtoull() on FreeBSD if building with -std=c99 Signed-off-by: Gilles Peskine --- tests/suites/main_test.function | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/tests/suites/main_test.function b/tests/suites/main_test.function index ba9b021b59..0121f826c7 100644 --- a/tests/suites/main_test.function +++ b/tests/suites/main_test.function @@ -24,9 +24,13 @@ #endif #if defined(__FreeBSD__) -// for gettimeofday() (On FreeBSD, _POSIX_C_SOURCE isn't enough) +/* On FreeBSD as of 14.3, no value of _POSIX_C_SOURCE is enough for + * gettimeofday(), you need _XOPEN_SOURCE (any value). + * Furthermore, setting _XOPEN_SOURCE to 500 removes support for long long + * in libc, so you need at least 600 for e.g. strtoull(). + */ #if !defined(_XOPEN_SOURCE) -#define _XOPEN_SOURCE 500 +#define _XOPEN_SOURCE 600 #endif #endif From 2393fddd60af7d5853c48745ae989f75f5ca3bee Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Mon, 2 Mar 2026 19:22:24 +0100 Subject: [PATCH 16/17] clock_gettime: don't assume more than 1 second since the origin of time With e.g. `CLOCK_BOOTTIME`, it's plausible that less than 1 second has passed since the boot reference time. Only assert that the returned time is nonzero (because all-bits-zero is highly implausible as an actual clock value, but likely indicates that the intended value was not copied out correctly). Signed-off-by: Gilles Peskine --- tests/suites/test_suite_platform_unix.function | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/suites/test_suite_platform_unix.function b/tests/suites/test_suite_platform_unix.function index d419390bf4..6646815962 100644 --- a/tests/suites/test_suite_platform_unix.function +++ b/tests/suites/test_suite_platform_unix.function @@ -52,7 +52,7 @@ void clock_gettime_available(int clockid) memset(&ts, 0, sizeof(ts)); int ret = clock_gettime(clockid, &ts); TEST_ASSERT_ERRNO(ret == 0); - TEST_LE_S(1, ts.tv_sec); + TEST_ASSERT(ts.tv_sec != 0 || ts.tv_nsec != 0); } /* END_CASE */ From 31934f47c5cd0566a8a63b9f0d9a3d006ea818c5 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Mon, 2 Mar 2026 19:26:04 +0100 Subject: [PATCH 17/17] Note platforms with known improvements Signed-off-by: Gilles Peskine --- ChangeLog.d/unistd.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ChangeLog.d/unistd.txt b/ChangeLog.d/unistd.txt index d2e4d4301a..84afdc315f 100644 --- a/ChangeLog.d/unistd.txt +++ b/ChangeLog.d/unistd.txt @@ -1,3 +1,6 @@ Changes * Tweak the detection of Unix-like platforms, which makes more system interfaces (timing, threading) available on Haiku, QNX and Midipix. + +Bugfix + * Fix a build failure with dietlibc.